我们知道,OpenCV可以通过imread()和imshow()函数将读取到的图片显示到windows创建的窗口中,但如果我们要将其显示在MFC应用界面内,还需要做一些别的转换。网上的许多资料都是基于OpenCV的CvvImage类,但新版本的OpenCV中已经取消了该类,虽然我们也可以添加旧版本中该类对应.h和.cpp文件中到自己的工程中,但过程较为繁琐。这里我介绍的是另外一种更为直接的方法:通过OpenCV的Mat类读取图片,并基于Mat类及OpenCV的函数完成图像处理环节的大部分内容,显示时只需将Mat类转化成MFC中的CImage类,在视图中OnDraw即可完成显示。
参考博客:
Opencv (Opencv2)结合MFC学习数字图像处理【3】—显示图片
一、图像的显示
在文档类Doc.h头文件中,引入OpenCV相关的头文件,并使用命名空间cv
#include <opencv2/opencv.hpp>
using namespace cv;
在文档类Doc.cpp源文件中添加成员变量:Mat rawImage;
(属性为public
),表示读取到的原始图像。
同样,要记得在.cpp文件中,引入相关头文件,并使用相应的命名空间
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
在文档类的.cpp文件中定义全局变量Mat myImage
,该全局变量通过extern
的方法即可在所有项目文件中使用,今后我们所有的的图像处理与显示都是基于myImage进行操作。
点击“项目”,选择“类向导”(快捷键为Ctrl + Shift + X),进入类向导界面,点击“类名”,注意这里要切换成“Doc类”,再点击虚函数,找到OnOpenDocument
,双击该函数或者点击右侧“添加函数”即可完成添加。
点击“编辑代码”,即可进入该函数的重写,在return True
前添加这样一段代码:
//下面几句话为宽字符字符串到ansi字符串的一个转化,因cv::imread函数的第一个参数为String型
CT2A str1(lpszPathName);
string str = str1.m_psz;
TRACE("%s\n", str.c_str());
rawImage = imread(str, -1); //rawImage读取到图像数据,-1表示按按解码方式读,可保留图像源格式
myImage = rawImage.clone(); //今后基于myImage进行图像操作和显示
//图像的显示需要还需将Mat转化为CImage类,具体可见工程View类的OnDraw函数
这段代码实现的功能是,将我们打开的原图像保存在rawImage中,并将图像原始数据复制给myImage,今后我们只基于myImage进行图像的处理和显示,而不改变rawImage,这样的好处是我们可以随时恢复原图像。
重写视图类view.cpp的OnDraw
函数,即可实现图像的绘制,同样地,我们别忘了在.cpp文件中添加相关的头文件。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
// COpenCVMFCView 绘图
extern Mat myImage;
void MatToCImage(Mat& mat, CImage& cImage);
void COpenCVMFCView::OnDraw(CDC* pDC)
{
COpenCVMFCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if