MFC中OpenCV的使用

来源:互联网 发布:数据分析作图软件 编辑:程序博客网 时间:2024/05/29 16:56


本文特别感谢 CVMFC(许红梅),在此基础上进行更新修正、扩展得到的。


    得到的程序如上图所示。本文的意图在于简单的介绍一下程序开发中的有价值的方法,以便后来者能快速入手。程序源码请自行到PUND上下载。


首先,进行项目的配置。具体参考下面的几步说明

1.VC++目录--包含目录D:\Program Files\opencv\vc10x86\include;D:\Program Files\opencv\vc10x86\include\opencv;D:\Program Files\opencv\vc10x86\include\opencv2;$(IncludePath)2.VC++目录--库目录D:\Program Files\opencv\vc10x86\lib;$(LibraryPath)3.链接器--输入opencv_calib3d245d.lib;opencv_contrib245d.lib;opencv_core245d.lib;opencv_features2d245d.lib;opencv_flann245d.lib;opencv_gpu245d.lib;opencv_highgui245d.lib;opencv_imgproc245d.lib;opencv_legacy245d.lib;opencv_ml245d.lib;opencv_objdetect245d.lib;opencv_ts245d.lib;opencv_video245d.lib;%(AdditionalDependencies)也即:opencv_calib3d2410d.lib;opencv_contrib2410d.lib;opencv_core2410d.lib;opencv_features2d2410d.lib;opencv_flann2410d.lib;opencv_gpu2410d.lib;opencv_highgui2410d.lib;opencv_imgproc2410d.lib;opencv_legacy2410d.lib;opencv_ml2410d.lib;opencv_objdetect2410d.lib;opencv_ts2410d.lib;opencv_video2410d.lib;

然后,进行程序的编写,具体的分为以下三个步奏

(1)文件的读取

重载在项目CCVPPDoc类的OnFileOpen函数

<span style="font-size:18px;">BOOL CCVPPDoc::OnOpenDocument(LPCTSTR lpszPathName){if (!CDocument::OnOpenDocument(lpszPathName))return FALSE;// TODO:  在此添加您专用的创建代码// Doc的打开文档的虚函数//-------------------------------------------------BOOL bools;Load(&m_pImg,lpszPathName);if (m_pImg!=NULL) bools=true;else bools=false;return(bools);}</span>

然后,在CCVPPDoc类中自定义两个变量和文件读取、保存文件的函数

// 特性public:IplImage* m_pImg;int m_display;//是否已经显示标记


// 读入图片BOOL CCVPPDoc::Load(IplImage** pImg,LPCTSTR pszFileName){IplImage* pImgLoad=NULL;pImgLoad = cvLoadImage(pszFileName,-1);      //  读图像文件(DSCV)if (!pImgLoad) return false;// 将图像采集卡采集的图像cvShowImage出来的是反着的图像,也就是图像采集卡采集的图像// 是以左下角为原点的,而窗口显示的图像原点是左上角,相当于是关于X轴翻转了。在显示// 图像之前使用cvFlip()函数将图像翻转一下就可cvFlip(pImgLoad);                            //  与 DIB 像素结构一致if (*pImg) {cvReleaseImage(pImg);}(*pImg)=pImgLoad;m_display=0;return true;}//保存图片BOOL CCVPPDoc::Save(LPCTSTR pszFileName,IplImage* pImg){int status;cvFlip(pImg); //  恢复原 OpenCV 位图结构status=cvSaveImage(pszFileName,pImg); //  图像保存入硬盘return(status);}

(2)在CCVPPView类的OnDraw中绘图

void CCVPPView::OnDraw(CDC* pDC){CCVPPDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: 在此处为本机数据添加绘制代码// 图像的输出//--------------------------------------------------------------------------------//  有磁盘输入图像if (pDoc->m_pImg!=NULL){                       if (pDoc->m_display==0) {                      //  尚未显示imageClone(pDoc->m_pImg,&m_SaveImg);         //  复制到备份位图m_dibFlag=imageClone(m_SaveImg,&m_WorkImg);    //  复制到工作位图m_ImageType=imageType(m_WorkImg);m_SaveFlag=m_ImageType;pDoc->m_display=1;}}//  DIB 结构改变if (m_dibFlag) {if (m_lpBmi)free(m_lpBmi);m_lpBmi=CtreateMapInfo(m_WorkImg,m_dibFlag);m_dibFlag=0;CSize  sizeTotal = CSize(m_WorkImg->width,m_WorkImg->height);SetScrollSizes(MM_TEXT,sizeTotal);  //  设置滚动条}char *pBits=NULL;if (m_CaptFlag==1) pBits=m_Frame->imageData;else if (m_WorkImg)  pBits=m_WorkImg->imageData;//  刷新窗口画面if (m_WorkImg) {                          StretchDIBits(pDC->m_hDC,0,0,m_WorkImg->width,m_WorkImg->height,0,0,m_WorkImg->width,m_WorkImg->height,pBits,m_lpBmi,DIB_RGB_COLORS,SRCCOPY);}//--------------------------------------------------------------------------------}

(3)典型处理事件的消息响应函数(以亮度变换为例)

/*src and dst are grayscale, 8-bit images;Default input value: [low, high] = [0,1];  X-Direction[bottom, top] = [0,1]; Y-Directiongamma ;if adjust successfully, return 0, otherwise, return non-zero.*/int ImageAdjust(IplImage* src, IplImage* dst, double low, double high,   // X方向:low and high are the intensities of srcdouble bottom, double top, // Y方向:mapped to bottom and top of dstdouble gamma ){if( low<0 && low>1 && high <0 && high>1&&bottom<0 && bottom>1 && top<0 && top>1 && low>high)return -1;double low2 = low*255;double high2 = high*255;double bottom2 = bottom*255;double top2 = top*255;double err_in = high2 - low2;double err_out = top2 - bottom2;int x,y,k;double val;// intensity transformfor( y = 0; y < src->height; y++){for (x = 0; x < src->width; x++){for ( k = 0; k < src->nChannels; k++){//-------------------------------------------------------------------------------------------// 图像点处理的源泉。2015-5-6 22~48//-------------------------------------------------------------------------------------------val = ((uchar*)(src->imageData + src->widthStep*y + x*(src->nChannels)))[k]; //提取IplImage*类型的图像的数据的方法//-------------------------------------------------------------------------------------------val = pow((val - low2)/err_in, gamma) * err_out + bottom2;// Make sure src is in the range [low,high]if(val>255) val=255; if(val<0) val=0; ((uchar*)(dst->imageData + dst->widthStep*y + x*(dst->nChannels)))[k] = (uchar) val;}}}return 0;}void CCVPPView::OnPointprocImageAdjust(){// 亮度变换IplImage *src = 0, *dst = 0;//    if( argc != 2 || (src=cvLoadImage(argv[1], 0)) == NULL)  // force to gray image//        return -1;src = m_WorkImg;//cvNamedWindow( "src", 1 );cvNamedWindow( "result", 1 );// Image adjustdst = cvCloneImage(src);// 输入参数 [0,0.5] 和 [0.5,1], gamma=1if( ImageAdjust( src, dst, 0, 0.5, 0.5, 1, 1)!=0) return;// cvShowImage( "src", src );cvFlip(dst);cvShowImage( "result", dst );cvWaitKey(0);//    cvDestroyWindow("src");cvDestroyWindow("result");//    cvReleaseImage( &src );//    cvReleaseImage( &dst );cvFlip(dst);m_dibFlag=imageReplace(dst,&m_WorkImg);Invalidate();}


以上就是OpenCV与MFC结合的一个具体的例子,希望大家以此类推,能够将两者很好的结合起来。写博客很费时间,多的就不写了。




0 0