OpenCV学习笔记(8)VS2008 MFC下使用OpenCV2.0进行简单图像处理
来源:互联网 发布:富士康网络重复报名 编辑:程序博客网 时间:2024/06/01 08:47
源自:http://blog.csdn.net/chenyusiyuan/article/details/4733691
在OpenCV中文论坛看到有不少帖子讲到如何在MFC下应用OpenCV进行图像和视频处理的方法,受益颇丰,主要有下面这些帖子:
1、opencv 数据读写操作+图像噪声+ MFC下OpenCV源代码
2、MFC中快速应用OpenCV & 相应论坛帖子
3、MFC+openCV对话框中显示视频
4、如何把视频显示到MFC的picture控件上
5、一个人脸-人眼检测例程,大家可以参考参考
6、A step-by-step guide to the use of Microsoft Visual C++ and the Intel OpenCV library
另外还参考了于仕琪老师的《OpenCV教程-基础篇》,不过上面这些资料主要是 VC6 和 OpenCV1.0/1.1 的版本,而我使用的是 VS2008 和 OpenCV2.0,两者与之前版本相比都有很大的不同,按照论坛教程资料来做MFC下的OpenCV应用常会遇到各种各样的编程和调试问题。接下来的学习笔记将以上面的《A step-by-step guide …》为基础,总结一下VS2008 MFC下使用OpenCV2.0进行图像和视频处理的各种问题。
一、《OpenCV教程-基础篇》2.8节中的问题
1、P27初始化代码ROI值不为0的bug
IplImage* Temp = cvCreateImage(ImgSize, IPL_DEPTH_8U, 1); // 创建8U单通道图像来缓存RGB图的各通道子图; int h,w; float dx = (Temp->width / 256.0f); // 将图像按宽度作256等分 // 复制数据到IPL的蓝色通道 for(w = 0; w < Temp->width; w++) for(h = 0;h < Temp->height; h++) { // 复制数据到IPL Temp->imageData[Temp->height * w + h] = (char)(w/dx); // 单通道图像每一列像素的像素值等于(所在列/总列数)*256.0f // 其效果是使单通道图像显示为从上到下由黑到白的灰度渐变效果 } /* 函数 cvSetImageCOI 基于给定的值设置感兴趣的通道。 值 0 意味着所有的通道都被选定, 1 意味着第一个通道被选定等等。 如果 ROI 是 NULL 并且COI!= 0, ROI 被分配. 然而大多数的 OpenCV 函数不支持 COI, 对于这种状况当处理分离图像/矩阵通道时,可以拷贝(通过 cvCopy 或cvSplit) 通道来分离图像/矩阵, 处理后如果需要可再拷贝(通过cvCopy 或 cvCvtPlaneToPix)回来. */ cvSetImageCOI(TheImage,1); // 选择TheImage的蓝色通道 cvCopy(Temp,TheImage); // 复制数据到TheImage的蓝色通道 // 复制数据到IPL的绿色通道 for(w = 0; w < Temp->width; w++) for(h = 0;h < Temp->height; h++) { // 复制数据到IPL Temp->imageData[Temp->height * w + h] = (char)(255-w/dx); // 用255去减w/dx,则三个通道子图合在一起会呈现出从上到下由绿变紫的彩色渐变效果 // 如果也同红绿通道一样只用 w/dx,则最终是呈现由黑到白的灰度渐变 } cvSetImageCOI(TheImage,2); // 选择TheImage的绿色通道 cvCopy(Temp,TheImage); // 复制数据到TheImage的绿色通道 // 复制数据到IPL的红色通道 for(w = 0; w < Temp->width; w++) for(h = 0;h < Temp->height; h++) { // 复制数据到IPL Temp->imageData[Temp->height * w + h] = (char)(w/dx);//?? } cvSetImageCOI(TheImage,3); //选择TheImage的红色通道 cvCopy(Temp,TheImage); //复制数据到TheImage的红色通道 cvReleaseImage(&Temp); //释放Temp占用的内存空间
不过上述代码在运行之后,ROI的值不为0,这应该是一个bug,如何处理?
2、P34 cvCopy 使得运行出错的问题
P34执行Canny边缘检测的代码:
void MyIplClass::ProcessIpl(IplImage* ipl){ IplImage *gray = 0, *edge = 0; gray = cvCreateImage( cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 1 ); edge = cvCreateImage( cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 1 ); cvCvtColor( ipl, gray, CV_BGR2GRAY ); cvCanny( gray, edge, 30, 100, 3 ); cvCvtColor( edge, ipl, CV_GRAY2BGR ); // save result cvCopyImage( ipl, m_Ipl ); cvReleaseImage( &gray ); cvReleaseImage( &edge );}
其中的 cvCopyImage( ipl, m_Ipl ) 是无法执行的,因为经过前3行的颜色转换处理后, ipl 和 m_ipl 的ROI的区域已经不一样。这需要重设 ipl 的ROI,即在 cvCopyImage 前加一行代码:
cvResetImageROI( ipl ); cvCopyImage( ipl, m_Ipl );
3、P31增加的成员函数LoadBMP其输入参数类型应为 const char*
在书中,LoadBMP的输入参数类型是 CString,不过我在VS2008下编译时会报错,不能由 CString 类型转换到 const char* 类型。另外OpenCV函数 cvLoadImage 定义为:IplImage* cvLoadImage( const char* filename, int flags ) ,所以在 VS2008 下LoadBMP其输入参数类型应为 const char*。
void MyIplClass::GetIplData( IplImage* ipl ){ memcpy( ipl->imageData, m_Ipl->imageData, m_Ipl->imageSize );}void MyIplClass::LoadBMP( const char* FileName ){ m_Ipl = cvLoadImage( FileName, 1 );}
上面的 GetIplData 其实是把 m_Ipl->imageData 的内容,复制到了 ipl->imageData里面,注意,这个 ipl 就是传入参数,也就是
TheImage, 因此,实际上的图片,被保存在了 TheImage 里面(注意,TheImage是一个在程序里面早就初始化好了的图片)。那么,在下面的程序中:
void Cmfc_imgDlg::OnBnClickedReadimg(){ // TODO: Add your control notification handler code here MyIplClass* img = new MyIplClass; //实例化MyIplClass类 const char* filename; filename = "C://OpenCV2.0//projects//mfc_img//lena.bmp"; img->LoadBMP( filename ); img->GetIplData( TheImage ); delete img; RedrawWindow( NULL, NULL, RDW_INVALIDATE );}
其中的 delete img 只是删除了实例 img,但读入的图像已经保存在 TheImage 中,不影响后续的处理,这样,我们就可以新建一个按钮来执行读入图像后的处理工作,例如:
void Cmfc_imgDlg::OnBnClickedEdgedetect(){ // TODO: Add your control notification handler code here MyIplClass* img = new MyIplClass; img->ProcessIpl( TheImage ); delete img; RedrawWindow( NULL, NULL, RDW_INVALIDATE );}
最终就得到一个简单的MFC程序如下:
- OpenCV学习笔记(8)VS2008 MFC下使用OpenCV2.0进行简单图像处理
- OpenCV学习笔记(8)VS2008 MFC下使用OpenCV2.0进行简单图像处理
- OpenCV学习笔记(8)VS2008 MFC下使用OpenCV2.0进行简单图像处理
- OpenCV學習筆記(8)VS2008 MFC下使用OpenCV2.0進行簡單圖像處理
- 学习opencv(1)--VS2008下安装opencv2.4 配置 显示图像
- ROS学习笔记(2):在ROS中使用OpenCV进行简单的图像处理---代码实现篇
- 【opencv学习笔记一】opencv2.4.3在vs2008下的配置(包括测试程序)
- OpenCV学习笔记(3)用VS2008编译OpenCV2.0源代码(编译错误已解决)
- OpenCV笔记(3)图像简单处理
- OpenCV学习笔记2:使用opencv进行图像比较
- VC6使用GDI+进行图像的特效处理和MFC学习笔记-1
- 二 图像处理opencv mfc学习
- Opencv (Opencv2)结合MFC学习数字图像处理---显示图片
- MFC中使用openCV显示、处理图像
- MFC中使用openCV显示、处理图像
- 计算机视觉与图像处理学习笔记(三)opencv的基本数据类型与简单图像处理函数
- Opencv (Opencv2)结合MFC学习数字图像处理---图片解码(3)
- Opencv (Opencv2)结合MFC学习数字图像处理---图片解码(1)
- 【Java网络编程】UDP协议实例——简单的在线聊天程序
- hanganalyz 性能诊断工具
- epoll简介
- erlang mnesia 数据库备份与还原
- Android 判断Intent是否存在
- OpenCV学习笔记(8)VS2008 MFC下使用OpenCV2.0进行简单图像处理
- Ubuntu下SVN的配制
- 中英不同字体的设置
- sql中批量插入数据、char与int拼接实例
- objective-C 中两种实现动画的方法(转)
- 详解WINCE的控制面板
- 实战CentOS 6.0+Nagios中文版+PNP+Nagios Web管理工具nagiosQL中文版
- Hbase学习笔记
- 解决 chrome 浏览器对 div 的 display : none 不支持