您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 在MFC中使用OpenCV的方法
在MFC中使用OpenCV1在MFC中使用OpenCV演示程序CVMFC本程序是在MFC中使用OpenCV的演示程序,由3部分组成。一、Windows下用MFC编制的程序框架采用设备无关位图DIB实现Windows多文档模式下图像的显示,实现显示的关键函数StretchDIBits的原型如下:intStretchDIBits(HDChdc,//显示设备句柄intXDest,//目标矩形区域左上角X坐标intYDest,//目标矩形区域左上角Y坐标intnDestWidth,//目标矩形区域宽度intnDestHeight,//目标矩形区域高度intXSrc,//源矩形区域左上角X坐标intYSrc,//源矩形区域左上角Y坐标intnSrcWidth,//源矩形区域宽度intnSrcHeight,//源矩形区域高度CONSTVOID*lpBits,//位图的像素存放首地址CONSTBITMAPINFO*lpBitsInfo,//位图信息存放地址UINTiUsage,//位图中的颜色类型,RGB模式用DIB_RGB_COLORSDWORDdwRop//像素操作码,简单复制用SRCCOPY);由于OpenCV中的位图结构中的像素数据与DIB中的像素具有相同的存储结构,见表1中的像素部分。所以,只要为它构造一个DIB的位图信息就可以调用API函数StretchDIBits实现它的显示了。表1DIB位图参数与IplImage结构参数参数DIB(MFC)IplImage(OpenCV)宽度biWidthwidth高度biHeightheight像素位数biBitCount(1,4,8,16,24,32)=depth*nChannelsdepth(8,16,32,64)通道数---nChannels(1,2,3,4)(单通道位图)调色板单元数2biBitCount(2,16,256)二值图像显示为灰阶图像256色彩色图像显示为真彩色图像位图坐标原点底-左origin(0顶-左,1底-左)像素分量存放方式交叉存取(按像素为单位存放)0交叉存取,1位平面方式对齐方式(行像素数据凑整)4字节对齐4字节对齐或8字节对齐每行字节数(biWidth*biBitCount+31)/32*4widthStep像素字节数((biWidth*biBitCount+31)/32*4)*biHeightimageSize像素存放地址BYTE*pBitschar*imageData感兴趣区域---roi在MFC中使用OpenCV2表中正体字母部分表示相同的参数,粗体字母表示参数部分相同时的交集,斜体加下划线表示结构特有的参数。位图的宽度、高度、像素存放首地址、每行字节数、像素总字节数等5个参数在两种结构中相同。像素位数、通道数、坐标原点位置、像素分量存放方式、对齐方式等5个参数在两种结构中部分相同,使用时可以取其交集,表中用粗体字表示。有2个参数是两种位图各自独有的,感兴趣区域为IplImage结构所独有,调色板单元为DIB所独有。从表1中可以看出,除了高精度图像(位深度16,32,64)外,这两种位图结构在图像处理的绝大部分应用中可以通用。从以上比较中也可看出,IplImage结构适用于高精度处理,并且可以限制处理的区域;而DIB适用于Windows图形操作,并且可以存储低位数图像文件,如每像素一位的二值图像与像素8位的索引图像等。另一种实现MFC的方法是采用CvvImage类,它有一个特点,就是其成员函数DrawToHDC可将位图全部经缩放后显示到窗口中。这样,虽然能够察看全图,但当位图与窗口的长宽比不一致时会造成图像失真。而采用DIB实现的显示比例可选择为1:1,图像显示没有经过缩放,显示画面按窗口大小进行裁剪,并可使用滑动条选择显示部位,这比较符合图像采集与处理的使用习惯。二、调用OpenCV函数实现处理使用OpenCV函数处理图像在MFC环境下显示,实现功能为图像平滑、图像缩小与Canny边缘检测。根据《学习OpenCV》一书第2章的3个例子(例2-4,2-5,2-6)改编而成。例2-4与2-5使用例图fruits.jpg,例2-6使用例图lena.jpg。还增加了若干图像处理常用功能,详见下面表2菜单结构列表。视频播放也用OpenCV函数实现,根据《OpenCV教程(基础篇)》中第3章的例3-5改编而成,用的是highgui函数,测试视频文件为globe.avi。例图文件都在image\目录下。三、用DirectShow编制的视频采集程序采用DirectShow实现视频采集,其优点是支持高分辨率图像采集,最高分辨率由所用的摄像头决定,如罗技130万像素USB摄像头C300最高分辨率可达1280*1024,在MPEG模式下采集速度为每秒15帧。使用时CPU的时间占用率在15~30%之间。通过多图像平均可以采集得到质量不错的图像,经过4幅图像平均采集所得图像的信噪比可提高一倍。由于需要连续采集多帧图像,约需0.25秒,故适宜采集静态或缓慢移动对象的图像。视频采集功能调用OpenCVChina网站下载的软件camerads中的函数实现。主要内容下面列出stdafx.h尾部集中的几个头文件,程序结构由此可见一斑。#includeCVMFC.h//窗口管理#includecv.h//OpenCV头文件#includehighgui.h#includeCameraDS.h//DirectShow(基于OpenCV)#includeCVDSCap.h//视频采集接口在MFC中使用OpenCV3CVMFC的菜单结构程序分为文件、点处理、邻域处理、二值图像处理、形态学处理、综合处理例与视频采集播放等七、八个菜单条共70个功能,近半数功能由参考文献上的程序修改而成,为了便于找到相应参考材料进行对照,在程序中附上了它们的出处。程序的菜单结构见表2,其中列出了演示程序的大多数功能。表2CVMFC菜单结构文件点处理邻域处理二值图像处理形态学处理综合处理例视频采集播放打开图像彩色变灰阶邻域平均选择阈值腐蚀图像缩小启动摄像头恢复图像图像反相Gauss滤波自适应阈值法膨胀径向梯度打开AVI文件关闭当前窗口垂直镜像中值滤波全局阈值法开运算Canny算法视频解冻保存当前位图水平镜像Sobel算法外接矩形闭运算种子填充视频冻结最近文件180度旋转Laplace算法最小面积矩形形态学梯度金字塔图像分割多图像平均恢复原始图像30度旋转点集凸包顶帽变换椭圆曲线拟合关闭视频当前画面存盘亮度变换区域凸包波谷检测Snake原理选择分辨率退出图像直方图轮廓跟踪分水岭原理动态边缘检测直方图均衡化距离变换角点检测L_K光流跟踪典型例图各类功能都有一定的特异性,为了突出各功能的实效,建议初次使用时先用表3中列出的例图进行处理。这些例图在程序包的Image\目录下,表中也对一些功能作了简要的说明。表3功能的典型例图功能名称典型例图简要说明外接矩形(BoundingRect)ExampleL.bmp、ExampleQ.bmp仅适用于单连通区域,不能处理多连通区域与孔边界最小面积矩形(MinAreaRect2)区域凸包(ConvexHull2)轮廓跟踪(FindContours)ExampleC.bmp、SteelBar.bmp、pic3.png适用各类二值图像,使用范围较宽图像反相后也可进行处理,得到不同结果距离变换(DistTransform)顶帽变换ExampleD.bmp为灰值形态学运算,波谷检测又称黑顶帽变换图像反相后处理与另一方法直接处理等价波谷检测图像缩小lena.jpg、fruits.jpg径向梯度lena.jpg、fruits.jpgCanny算法lena.jpgHough变换(直线)(HoughLines2)pic1.pngHough变换(圆)(HoughCircles)stuff.jpg平行四边形检测pic1.png、pic2.png种子填充(FloodFill)fruits.jpg鼠标选种子,命令键C、M、R、S、F、G、8、4,ESC金字塔图像分割(PyrSegmentation)fruits.jpg滑动条调节参数,任意键退出椭圆曲线拟合(FitEllipse)stuff.jpg、rice.tif滑动条调节参数,任意键退出Snake原理(SnakeImage)ring.bmp、square.bmp滑动条调节参数,ESC退出分水岭原理(Watershed)fruits.jpg鼠标绘制区域标记,R清除,W或Enter分割,ESC退出角点检测(GoodFeaturesToTrack)chessboard.jpg滑动条调节参数,鼠标确定检测范围,任意键退出人脸检测(HaarDetectObjects)lena.jpg打开AVI文件globe.avi不能播放用Mpeg压缩的视频文件L_K算法光流跟踪鼠标选择跟踪点,命令键R、C、N,ESC退出在MFC中使用OpenCV4程序结构程序采用VC++多文档结构,图像的存放与处理则采用OpenCV的结构与函数,图像的显示采用位图信息m_lpBmi实现,为了便于管理对m_lpBmi的操作集中在OnDraw程序中。待显示位图结构发生改变时用m_dibFlag标志激发m_lpBmi的刷新。除了文件结构与图像显示外,其余部分基本上是OpenCV程序。位图数据:CVMFCDoc中pImg(读入图像文件所得原始位图)CVMFCView中workImg(工作位图)、saveImg(备份位图)m_lpBmi(工作位图的位图信息)CVDSCap中m_Frame(视频采集所得位图)视图的显示:voidCCVMFC0View::OnDraw(CDC*pDC){CCVMFCDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);//TODO:adddrawcodefornativedatahereif(pDoc-pImg!=NULL){//有磁盘输入图像CSizesizeTotal;sizeTotal=CSize(pDoc-pImg-width,pDoc-pImg-height);SetScrollSizes(MM_TEXT,sizeTotal);if(pDoc-m_Display==0){//输入图像尚未显示newCloneImage(pDoc-pImg,&saveImg);//复制到备份位图m_dibFlag=newCloneImage(saveImg,&workImg);//复制到工作位图m_ImageType=pDoc-pImg-nChannels;//设置标志m_SaveFlag=m_ImageType;pDoc-m_Display=1;}}if(m_dibFlag){//刷新DIB位图信息if(m_lpBmi)free(m_lpBmi);m_lpBmi=CtreateMapInfo(workImg,m_dibFlag);m_dibFlag=0;}if(workImg){//刷新窗口画面StretchDIBits(pDC-m_hDC,0,0,workImg-width,workImg-height,0,0,workImg-width,workImg-height,workImg-imageData,m_lpBmi,DIB_RGB_COLORS,SRCCOPY);}}CCVMFC模块中增加了4个函数,即CtreateMapInfo、imageType、imageClone与imageReplace。CtreateMapInfo函数用于建立工作位图workImg的位图信息m_lpBmi,其特点是可以为单通道位图设置两在MFC中使用OpenCV5种调色板,即黑白灰阶调色板与VGA默认调色板。因为在OpenCV中二值图像显示为灰阶图像,imageType函数可从单通道位图中识别出二值位图。ImageClone与imageReplace函数使用OpenCV函数实现位图的复制,自动释放老的指针所指向的存储单元
本文标题:在MFC中使用OpenCV的方法
链接地址:https://www.777doc.com/doc-2600829 .html