用OpenCV与MFC写一个图像格式转换及简单处理程序

2023-12-06 16:30

本文主要是介绍用OpenCV与MFC写一个图像格式转换及简单处理程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

          打开不同格式的图形文件,彩色装灰度图像、锐化、高斯滤波、边界检测及将其存储为需求格式是图像处理的最基本的操作。如果单纯用MFC编程,是一个令人头痛的事情,有不少的代码量。可用OpenCV与MFC编程就变得相对简单。下面来详细演示这一编程操作。

一  在VS2022中创建一个MFC对话框Project

      在V2022中用MFC向导创建一个对话框Project,在对话框中添加如下按钮控件:

修改控件ID

“打开图像文件”的ID修改如下:

“彩色图像转换为灰度图像”的ID修改如下:

“图像锐化“的ID修改如下: 

“图像高斯滤波“的ID修改如下:

“图像边缘检测“的ID修改如下:

 

“图像文件另存为“的ID修改如下:

”退出“的ID修改如下:

二   设置Project属性

          设置使用字符集   使用“Unicode字符集”,如下:

    设置Debug|X64附加依赖库

设置Release|X64 附加依赖库

三 包含OpenCV 相关头文件,并定义变量

   在对话框头文件中包含OpenCV相关头文件如下:

// MFCDiaologOpenCVDlg.h: 头文件
//#pragma once
#include <opencv2/opencv.hpp>using namespace cv;

在头文件中定义以下私有变量:

class CMFCDiaologOpenCVDlg : public CDialogEx
{
// 构造
public:CMFCDiaologOpenCVDlg(CWnd* pParent = nullptr);	// 标准构造函数
private:Mat src;CWnd* pWnd;CRect mRec;CPoint mPoint;CString m_Path;CString m_strEx;CString m_strName;String m_str;// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_MFCDIAOLOGOPENCV_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:afx_msg void OnBnClickedOpen();afx_msg void OnBnClickedCvt();afx_msg void OnBnClickedSaveas();afx_msg void OnBnClickedOk();
};
四 编写程序代码

     为”打开图像文件”控件添加如下响应代码:

void CMFCDiaologOpenCVDlg::OnBnClickedOpen()
{// TODO: 在此添加控件通知处理程序代码CFileDialog fdlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("All files(*.*)|*.*||"));if (fdlg.DoModal() == IDOK){m_Path = fdlg.GetPathName();m_strEx = fdlg.GetFileExt();m_strName = fdlg.GetFileName();m_Path.ReleaseBuffer();m_strEx.ReleaseBuffer();m_strName.ReleaseBuffer();}if (m_strEx == "BMP" || m_strEx == "bmp" || m_strEx == "TIF" || m_strEx == "tif" || m_strEx == "PNG" || m_strEx == "png" || m_strEx == "jpg" || m_strEx == "JPG"){pWnd = GetDlgItem(IDC_PICSHOW);pWnd->GetClientRect(&mRec);mPoint = mRec.TopLeft();pWnd->ClientToScreen(&mPoint);m_str = CT2A(m_Path);src = imread(m_str);if(src.empty())MessageBox(_T("打开图像文件失败!"));else{m_str = CT2A(m_strName);namedWindow(m_str, WINDOW_AUTOSIZE);moveWindow(m_str, mPoint.x, mPoint.y);imshow(m_str, src);}}else{MessageBox(_T("你打开的文件不是本程序支持的图像文件!"));}
}

    为”彩色图像转换为灰度图像”控件添加如下响应代码:

void CMFCDiaologOpenCVDlg::OnBnClickedCvt()
{// TODO: 在此添加控件通知处理程序代码Mat des;cvtColor(src, des, COLOR_BGR2GRAY, 0);destroyAllWindows();m_str = CT2A(m_strName);namedWindow(m_str, WINDOW_AUTOSIZE);moveWindow(m_str, mPoint.x, mPoint.y);imshow(m_str, des);src.release();des.copyTo(src);
}

为”图像锐化”控件添加如下响应代码:

void CMFCDiaologOpenCVDlg::OnBnClickedSharp()
{// TODO: 在此添加控件通知处理程序代码Mat sharpenKernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);filter2D(src, src, -1, sharpenKernel);destroyAllWindows();namedWindow(m_str, WINDOW_AUTOSIZE);moveWindow(m_str, mPoint.x, mPoint.y);imshow(m_str, src);
}

 为”图像高斯滤波”控件添加如下响应代码:

void CMFCDiaologOpenCVDlg::OnBnClickedGausFilter()
{// TODO: 在此添加控件通知处理程序代码Mat gaussianKernel = getGaussianKernel(5, 2);filter2D(src, src, -1, gaussianKernel);destroyAllWindows();namedWindow(m_str, WINDOW_AUTOSIZE);moveWindow(m_str, mPoint.x, mPoint.y);imshow(m_str, src);
}

为”图像边缘检测”控件添加如下响应代码: 

void CMFCDiaologOpenCVDlg::OnBnClickedEdgeDetect()
{
    // TODO: 在此添加控件通知处理程序代码
    Mat kernel1 = (Mat_<char>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);
    Mat kernel2 = (Mat_<char>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);
    Mat dst1, dst2;
    filter2D(src, dst1, -1, kernel1);
    filter2D(src, dst2, -1, kernel2);
    dst1 = abs(dst1);
    dst2 = abs(dst2);
    src.release();
    add(dst1, dst2, src);
    destroyAllWindows();
    namedWindow(m_str, WINDOW_AUTOSIZE);
    moveWindow(m_str, mPoint.x, mPoint.y);
    imshow(m_str, src);
}

为”图像另存为”控件添加如下响应代码:

void CMFCDiaologOpenCVDlg::OnBnClickedSaveas()
{// TODO: 在此添加控件通知处理程序代码CFileDialog fdlg(FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("All files(*.*)|*.*||"));if (fdlg.DoModal() == IDOK){m_Path = fdlg.GetPathName();m_strEx = fdlg.GetFileExt();m_strName = fdlg.GetFileName();m_Path.ReleaseBuffer();m_strEx.ReleaseBuffer();m_strName.ReleaseBuffer();}if (m_strEx == "BMP" || m_strEx == "bmp" || m_strEx == "TIF" || m_strEx == "tif" || m_strEx == "PNG" || m_strEx == "png" || m_strEx == "jpg" || m_strEx == "JPG"){m_str = CT2A(m_Path);imwrite(m_str, src);src = imread(m_str);destroyAllWindows();m_str = CT2A(m_strName);namedWindow(m_str, WINDOW_AUTOSIZE);moveWindow(m_str, mPoint.x, mPoint.y);imshow(m_str, src);}else{MessageBox(_T("你输入的文件格式不是不是本程序支持的图像文件格式,不能保存!"));}}

为”退出”控件添加如下响应代码:

void CMFCDiaologOpenCVDlg::OnBnClickedOk()
{// TODO: 在此添加控件通知处理程序代码//destroyAllWindows();CDialogEx::OnOK();
}
五   程序试运行

      按“Ctrl+F5”试运行,程序跑起来了,如下:

 

点击“打开图像文件按钮”,进入到打开图像界面,如下:

  选中1.bmp后点击打开,结果如下:

点击“图像另存为” 按钮,进入图像存储界面,如下:

点击“保存”,弹出确认对话框,如下:

点击是,回到原界面后,如下:

显示的图像变成了2.png,在打开图像时看到的2.png是灰度图像,现在变成了彩色图像。

点击“彩色图像转换为灰度图像”,结果如下:

点击图像另存为,进入图像存储界面

在文件名对话框中输入3.tif,点击保存,结果如下:

显示的图像变成了3.tif,再点击“打开图像文件”按钮,去看一下存储的文件是否存在,进入到打开文件界面,如下:

可以看到前面存储的3.tif文件确实存在。

关闭对话框,点“退出”,退出程序。

重新按“Ctrl+F5”运行程序,再试下打开3.tif这个存储文件,看能否正常打开,打开结果,如下:

        确实能打开。说明控件响应程序没有问题。

       点击“打开图想文件” ,然后打开如下图像。

点击“图像锐化”,结果如下:

点击“图像边缘检测”,结果如下:

虽然效果不是让人满意,但确实检测到了边界。

再打开一张图像,如下:

点击“图像锐化”后的效果如下:

再点击“图像高斯滤波”,结果如下:

      几行代码就完成了图像转换及图像的简单处理,可以看出OpenCV确实强悍。值得我们去深入学习与研究。

       这个程序还存在些问题,当激活别的运行程序后,再回到这个对话框程序,可能回发现打开的图片不见了,或者跑到别的地方去了,这是MFC界面编程问题,如何处理,这里这里暂不做讨论。留到后面的机器视觉编程实战部分再做介绍。

       此程序的编程环境:Win10+VS2022+OpenCV4.8,示例程序的源代码已上传到CSDN,链接为:https://download.csdn.net/download/billliu66/88593238

这篇关于用OpenCV与MFC写一个图像格式转换及简单处理程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/462492

相关文章

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

四种简单方法 轻松进入电脑主板 BIOS 或 UEFI 固件设置

《四种简单方法轻松进入电脑主板BIOS或UEFI固件设置》设置BIOS/UEFI是计算机维护和管理中的一项重要任务,它允许用户配置计算机的启动选项、硬件设置和其他关键参数,该怎么进入呢?下面... 随着计算机技术的发展,大多数主流 PC 和笔记本已经从传统 BIOS 转向了 UEFI 固件。很多时候,我们也

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

opencv实现像素统计的示例代码

《opencv实现像素统计的示例代码》本文介绍了OpenCV中统计图像像素信息的常用方法和函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 统计像素值的基本信息2. 统计像素值的直方图3. 统计像素值的总和4. 统计非零像素的数量