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 );
}
相关文章推荐
- mysql高可用方案MHA介绍
- Linux安装多个Python版本
- 分享一个学习php的网站
- Linux的架构(硬件与应用的曲折...)
- ssh登录docker容器
- Linux 内核的文件 Cache 管理机制介绍-ibm
- tomcat修改默认主页
- Dropwizard测试
- Apache服务器常规操作
- iText操作错误:PdfReader not opened with owner password
- [Hadoop]SSH免密码登录以及失败解决方案
- linux下python开发环境——安装Eclipse+PyDev
- 从读取图像程序比较opencv1.0与opencv2.0以上版本
- Linux下XAMPP的部署
- Goodle Clean设计架构
- Linux下软件安装之Mysql安装
- 文件的基本管理和XFS文件系统备份恢复
- OpenWrt - rpcd
- LeetCode 354. Russian Doll Envelopes(信封包装)
- VS2010 调试基于ARM的linux程序方法