您的位置:首页 > 运维架构

MFC中使用openCV显示、处理图像

2014-11-26 21:14 751 查看

http://blog.sina.com.cn/s/blog_8e6bfecf0100xn14.html

openCV读取、显示、处理图像比较方便,但是整体界面设计以及鼠标、键盘事件响应比较弱。将MFC这方面的功能和openCV结合起来。

    在openCV的C++接口中(2.2及以后),图像都用cv::Mat存储,但是可以使用openCV已经做好的重载运算符直接转为C版本openCV的图像类型 IplImage:

    cv::Mat mat;

    IplImage img = mat;

    而且在上述过程中没有数据拷贝,只是新建了一个IplImage文件头。

    创建一个Dialog-Based的MFC窗口作为例子,添加一个Picture Control空间,将其ID修改为 IDC_RENDER。

在MFC界面中添加一个按钮用来打开文件窗口选择载入的图片(这比较简单,就不细说了);读取图片当然用的是opencv的接口了。

    使用openCV的 cv::Mat 读取图片之后,需要在picture control控件中将图片显示出来。

    其过程是这样的:将 cv::Mat 转换格式为 IplImage,然后将 IplImage 转换格式为 CvvImage,因为 CvvImage 类中有函数 DrawToHDC(),可以直接完成MFC空间中的绘图。

    问题是:在openCV2.2以后,这个类 CvvImage 被删掉了。。。

    解决办法,参考一些遇到相同问题的人在论坛里的讨论(网址),将 CvvImage 的定义单独抠出来组成.cpp和.h。问题解决。

    最后读取并显示图片的MFC 按钮空间的反馈函数为:

// load image

void CpicUIDlg::OnBnClickedLoadimage() {

string tstring;

CString tFileName;

CFileDialog tDlg(TRUE);

if(tDlg.DoModal() == IDOK) {

tFileName = tDlg.GetPathName();

tstring = tFileName.GetBuffer(0);

}

mat = cv::imread(tstring, 1);

if(! mat.data) {

MessageBox("error", "no image loaded!", MB_OK);

return;

}

CDC* pDC = GetDlgItem(IDC_RENDER)->GetDC();

HDC hDC = pDC->GetSafeHdc();

IplImage img = mat;

CvvImage cimg;

cimg.CopyOf( &img );

CRect rect;

GetDlgItem(IDC_RENDER)->GetClientRect(&rect);

cimg.DrawToHDC(hDC, &rect);

ReleaseDC( pDC );

}

    CvvImage.cpp和CvvImage.h,参见上面链接的openCV论坛帖子。

    然后是这样一个问题:载入的图片和MFC中显示图片的窗口的大小、比例是不一样的,需要进行调整;进行调整的载入图片的反馈函数如下:

// load image

void CpicUIDlg::OnBnClickedLoadimage() {

string tstring;

CString tFileName;

CFileDialog tDlg(TRUE);

if(tDlg.DoModal() == IDOK) {

tFileName = tDlg.GetPathName();

tstring = tFileName.GetBuffer(0);

}

mat = cv::imread(tstring, 1);

if(! mat.data) {

MessageBox("error", "no image loaded!", MB_OK);

return;

}

CRect rect;

GetDlgItem(IDC_RENDER)->GetClientRect(&rect);

float widRat = (float)rect.Width() / mat.cols;

float heiRat = (float)rect.Height() / mat.rows;

float resRat = widRat < heiRat ? widRat : heiRat;

int resWid = mat.cols * resRat;

int resHei = mat.rows * resRat;

cv::resize(mat, mat2, cv::Size(resWid, resHei)); // 调整

renderScene();

}

    之后只需要在显示的时候只按原比例在picture control控件中显示调整过的图像即可,例子为:

void CpicUIDlg::renderScene() {

CDC* pDC = GetDlgItem(IDC_RENDER)->GetDC();

HDC hDC = pDC->GetSafeHdc();

IplImage img = mat2;

CvvImage cimg;

cimg.CopyOf( &img );

CRect rect;

GetDlgItem(IDC_RENDER)->GetClientRect(&rect);

int tlx = rect.TopLeft().x;

int tly = rect.TopLeft().y;

int brx = tlx + mat2.cols - 1;

int bry = tly + mat2.rows - 1;

CRect drawRect;

drawRect.SetRect(tlx, tly, brx, bry);

cimg.DrawToHDC(hDC, &drawRect);

ReleaseDC( pDC );

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv vc