用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/202147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

敏捷:应对软件定义汽车时代的开发模式变革

随着软件定义汽车典型应用场景的落地&#xff0c;汽车从交通工具转向智能移动终端的趋势愈发明显。几十年前&#xff0c;一台好车的定义主要取决于高性能的底盘操稳与动力系统&#xff1b;几年前&#xff0c;一台好车的定义主要取决于智能化系统与智能交互能否满足终端用户的用…

五肽-13|提亮肤色,美白肌肤

五肽-13 INCI名称&#xff1a;五肽-13 说明&#xff1a; 五肽-13是一种合成肽&#xff0c;由丙氨酸、精氨酸、赖氨酸、脯氨酸和缬氨酸组成 功能&#xff1a; 五肽-13起到增白剂的作用 应用程序&#xff1a; 提亮和美白

Unity渲染Stats分析

文章目录 前言一、Stats二、我们主要看渲染状态分析1、FPS2、其他状态信息3、DrawCall4、Batch5、Setpass Call6、在Unity中弱化了DrawCall的概念&#xff0c;我们主要看 Batch 和 Setpass Call 三、使用 Batching&#xff08;合批&#xff09; 降低 Batch &#xff08;渲染批次…

【c】杨辉三角

下面介绍两种方法 1.利用上面性质的第五条&#xff0c;我们可以求各行各列的组合数 2.利用上面性质的第7条&#xff0c;我们可以用数组完成 下面附上代码 1. #include<stdio.h> void fact(int n ,int m )//求组合数 {long long int sum11;long long int sum21;int a…

LTD254次升级 | 订单批打印 • 官网搭“抖音“ • 合伙人添权益

1、 商城订单支持打印功能&#xff1b; 2、 H5/小程序商城新增一款首页样式&#xff1b; 3、 社区中视频支持抖音方式浏览&#xff1b; 4、 极速官微优化管理页面布局、优化海报分享样式&#xff1b; 5、 新增一款轮播模块&#xff1b; 6、 已知问题修复与优化&#xff1b; 01 …

<sa8650>Safety Monitor 之 API介绍 (第二部分)

&#xff1c;sa8650&#xff1e;Safety Monitor 之 API介绍 4.由APSS安全监视器支持的接口4.1数据结构文件4.1.1 struct sm_handle4.1.2 struct safety_msg_initial_fault4.1.3 struct safety_msg_notify_fault 4.2 Enumeration documentation4.2.1 safety_fault_subsystem4.2…

前端:让一个div悬浮在另一个div之上

使用 CSS 的 position 属性和 z-index 属性 首先&#xff0c;将第二个 div 元素的 position 属性设为 relative 或 absolute。这样可以让该元素成为一个定位元素&#xff0c;使得后代元素可以相对于它进行定位。 然后&#xff0c;将要悬浮的 div 元素的 position 属性设为 ab…

分布式锁常见实现方案

分布式锁常见实现方案 基于 Redis 实现分布式锁 如何基于 Redis 实现一个最简易的分布式锁&#xff1f; 不论是本地锁还是分布式锁&#xff0c;核心都在于“互斥”。 在 Redis 中&#xff0c; SETNX 命令是可以帮助我们实现互斥。SETNX 即 SET if Not eXists (对应 Java 中…

Redis7--基础篇7(哨兵sentinel)

1. 关于哨兵的介绍 1、监控redis运行状态&#xff0c;包括master和slave&#xff08;主从监控&#xff09; 2、哨兵可以将故障转移的结果发送给客户端&#xff08;消息通知&#xff09; 3、当master down机&#xff0c;能自动将slave切换成新master&#xff08;故障转移&#…

软件测试理论

含义&#xff1a;使用技术手段来验证软件是否满足使用需求 目的&#xff1a;减少软件缺陷&#xff0c;保障软件质量 单元测试&#xff1a;对模块/函数进行的测试 集成测试&#xff1a;把多个模块/函数组装到一起进行的测试 系统测试&#xff1a;计算机程序结合外设网络等其…

springboot077基于SpringBoot的汽车票网上预订系统

springboot077基于SpringBoot的汽车票网上预订系统 成品项目已经更新&#xff01;同学们可以打开链接查看&#xff01;需要定做的及时联系我&#xff01;专业团队定做&#xff01;全程包售后&#xff01; 2000套项目视频链接&#xff1a;https://pan.baidu.com/s/1N4L3zMQ9n…

流量异常-挂马造成百度收录异常关键词之解决方案(虚拟主机)

一.异常现象&#xff1a;流量突然暴涨&#xff0c;达到平时流量几倍乃至几十倍&#xff0c;大多数情况下因流量超标网站被停止。 二.排查原因&#xff1a; 1.首先分析web日志&#xff1a;访问量明显的成倍、几十倍的增加&#xff1b;访问页面不同&#xff1b;访问IP分散并不固…

err_connect_length_mismatch错误

原因: 官网解释为&#xff1a;err_content_length_mismatch:错误的内容长度不匹配&#xff08;请求的Heather 里content-length长度与返回的content-length不一致&#xff09; 问题截图: 分析: 由截图可见,静态资源加载错误,提示err_content_length_mismatch,经排查,网络页签…

“新KG”视点 | 知识与大模型融合技术在电信领域应用探索

OpenKG 大模型专辑 导读 知识图谱和大型语言模型都是用来表示和处理知识的手段。大模型补足了理解语言的能力&#xff0c;知识图谱则丰富了表示知识的方式&#xff0c;两者的深度结合必将为人工智能提供更为全面、可靠、可控的知识处理方法。在这一背景下&#xff0c;OpenKG组织…

M2芯片回顾

M芯片&#xff0c; 一竟到底&#xff1a; M1芯片的体积&#xff1a; M2 代表 M 系列芯片的第二代&#xff1a; 其进一步提升了芯片的性能和功率 &#xff0c;这也是 M 芯片目前的追求&#xff1a;最大化性能的同时&#xff0c;最大限度降低功耗。 UMA 统一内存架构被再一次提到…

什么是 shell 脚本?

一、什么是 shell&#xff1f; Shell 是一个应用程序&#xff0c;它负责接收用户输入的命令&#xff0c;然后根据命令做出相应的动作&#xff0c; Shell 负责将应用层或者用户输入的命令传递给系统内核&#xff0c;由操作系统内核来完成相应的工作&#xff0c;然后将结果反馈给…

西门子 ULTRAMAT 23多组分气体分析仪 端子接线说明

后面板端子分布图 RS485接口 模拟量&#xff08;开关量&#xff09;接口 特此记录 anlog 2023年12月6日

天眼销为电销行业降低获客成本

当下&#xff0c;做电销的老板都有一个深刻体会&#xff1a;市场竞争越来越激烈&#xff0c;获客成本不断攀升&#xff0c;但效率不升返降&#xff0c;企业经营困难。特别是在这一两年&#xff0c;市场环境紧张&#xff0c;业务不好开展&#xff0c;更是雪上加霜。 销售也感觉…

1.3角色设计精要

一、角色设计流程 二、确定角色关键词 OW角色小美 关键词&#xff1a; 中国防守英雄冰与雪聪明的邻家大姐姐探索与冒险南极科考航天科技 OW角色猎空 关键词&#xff1a; 英国敏捷飞行员进攻英雄年轻动感活泼 三、收集素材和灵感 概念设计 由分析用户需求到生成概念产品一系…