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

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

2016-06-16 09:07 761 查看


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

2012-10-23 09:17:08|  分类: 默认分类|举报|字号 订阅

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 );
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: