用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_TIME
	enum { IDD = IDD_MFCDIAOLOGOPENCV_DIALOG };
#endif

	protected:
	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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Altair推出 Altair RapidMiner 2023 平台,提供生成式 AI 功能

Altair推出 Altair RapidMiner 2023 平台&#xff0c;提供生成式 AI 功能 更新包括自动聚类、扩展 SAS、Python 和 R 编程功能等 近日&#xff0c;Altair&#xff08;纳斯达克股票代码&#xff1a;ALTR&#xff09;近日宣布其数据分析和 AI 平台 Altair RapidMiner 取得了一系…

Python文件打包成exe可执行文件

我们平常用python写些脚本可以方便我们的学习办公&#xff0c;但限制就是需要有python环境才能运行。 那能不能直接在没有python环境的电脑上运行我们的脚本呢&#xff1f; 当然可以&#xff0c;那就是直接把python脚本打包成exe可执行程序&#xff08;注针对win系统&#xf…

Linux之进程(一)

目录 一、概念 1、基本概念 2、描述进程的PCB 3、task_struct 二、查看进程 三、获取进程的PID和PPID 通过系统调用获取进程的PID和PPID 四、通过系统调用创建进程 1、fork函数创建子进程 2、用if进行分流 五、进程状态 1、操作系统进程状态 1、新建 2、运行 3、…

windows磁盘扩容

在我们为电脑加装一个新的硬盘之后&#xff0c;需要相应的操作才能将硬盘空间加到磁盘空间中。 1.打开磁盘管理器 windows系统可以选择在搜索中直接搜索计算机管理并将其打开 windows server的打开方式为服务器管理器→工具→计算机管理 打开计算机管理后就可以看到磁盘管理&…

【链表Linked List】力扣-234回文链表

目录 问题描述 解题过程 labuladong题解 问题描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff…

20、pytest中的参数化

官方实例 # content of test_expectation.pyimport pytestpytest.mark.parametrize("test_input, expected",[("35",8),("24",6),("6*9",42)]) def test_eval(test_input, expected):assert eval(test_input) expected# content of …

unsafe类和varhandle类讲解

Java的Unsafe类是一个非常特殊的类&#xff0c;它提供了一组原始、底层的操作&#xff0c;可以跳过Java的限制&#xff0c;直接操作内存和对象。这些操作可能会破坏Java的安全机制&#xff0c;所以Unsafe类被标记为不安全的。 Unsafe类提供了下列方法&#xff1a; allocateIns…

漏洞复现--云时空商业ERP文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

几个查找开源组件CVE的网站和工具

有时在使用一个开源组件之前&#xff0c;需要先调查一下这个组件是否有一些比较验证的CVE。同时&#xff0c;对于一些重要的正在使用的组件&#xff0c;例如&#xff1a;Spring Framework&#xff0c;也希望查询一下是否有严重的CVE。 本文就介绍几个曾经用过的查找开源组件还不…

抖店怎么对接达人带货?达人渠道整理,实操详解!

我是电商珠珠 很多人在抖店开通后&#xff0c;按照流程去正常的跑自然流量&#xff0c;再去找达人带货让自己店铺的流量增多&#xff0c;得到相应的曝光。 但是一些新手小白并不知道从哪去找达人&#xff0c;或者说不知道怎么去筛选达人。 一开始所有人都想着去找头部主播&a…

MySQL_1. mysql数据库介绍

shell脚本差不多快完结了接下来会为大家更新MySQL系列的相关的基础知识笔记&#xff0c;希望对大家有所帮助&#xff0c;好废话不多说&#xff0c;接下来开始正题&#xff01; 1.mysql数据库介绍 mysql 是一款安全、跨平台、高效的&#xff0c;并与 PHP、Java 等主流编程语言…

docker安装及使用(Linux版本)

文章目录 前言一、docker安装二、docker命令pull&#xff08;安装镜像&#xff09;images&#xff08;安装镜像&#xff09;run&#xff08;创建容器&#xff09;exec&#xff08;进入运行中的容器&#xff09;常用命令 总结如有启发&#xff0c;可点赞收藏哟~ 前言 https://do…

Jmeter测试移动接口性能 —— 压测

一般的公司都想知道自己产品的性能瓶颈和以及提升性能&#xff0c;以期大流量来了还撑得住。其实性能测试很难&#xff0c;难点在你不知道性能要达到怎样的需求。难点在于你没有实际的环境场景给你测试&#xff0c;总不能给线上环境你测试吧&#xff1f; 难点在于找性能瓶颈&a…

吐血整理,Web自动化测试-项目阶段性总结,一篇策底打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、什么是web自动…

25道Python练手题(附详细答案),赶紧收藏!Python入门|Python学习

题目 1&#xff1a;水仙花数 水仙花数&#xff08;Narcissistic number&#xff09;也被称为超完全数字不变数&#xff08;pluperfect digital invariant, PPDI&#xff09;、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数&#xff08;Armstrong number&#xff09; 水仙花数是指…

身为 Go 程序员,我为啥更喜欢用 Zig?

Zig 是一种比较新的编程语言&#xff0c;于 2016 年首次推出。Zig 社区将其描述为“一种用于维护稳固的、可优化和可重用软件的通用编程语言”。 看似一句简单的描述&#xff0c;却隐藏着远大的抱负。Zig被看作是可与C语言一较高下的编程语言。此外&#xff0c;Zig 也是一个编…

04 硬件知识入门(二极管)

1 二极管的定义 导电性能介于导体与绝缘体之间的材料称为半导体&#xff0c;常见的半导体材料有硅、锗和硒等。利用半导体材料可以制作各种各样的半导体元器件&#xff0c;如二极管、三极管、场效应管和晶闸管等都是由半导体材料制作而成的。 2 二极管的简介 1&#xff0e;半…

报表生成器FastReport .Net用户指南:带图表的报告(图表要素)

FastReport .Net是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案&#xff0c;使用FastReport .NET可以创建独立于应用程序的.NET报表&#xff0c;同时FastReport .Net支持中文、英语等14种语言&#xff0c;可以让你的产品保证真正的国际性。 FastReport.NET官方版…

InnoDB存储引擎体系结构中的各个组件是如何协同工作的?

InnoDB存储引擎体系结构如下图&#xff08;图片来源&#xff1a;XtraDB / InnoDB internals in drawing&#xff09;&#xff1a; 列举一个UPDATE场景加以说明。 假设有一个UPDATE语句正在执行&#xff1a;UPDATE test SET idx 2 WHERE id10&#xff0c;执行流程如下&#xf…

老师可以做副业吗

当老师&#xff0c;除了教学工作之外&#xff0c;还可以怎样来丰富自己的职业体验和增加收入呢&#xff1f; 自媒体作者 许多教师选择成为自媒体作者&#xff0c;分享自己的教育心得、教学经验以及与学生相处的生活状态等。通过撰写文章、发布在社交媒体上&#xff0c;不仅可以…