演示程序
演示程序CVMFC采用VC++多文档带滚动条结构,图像的存放与处理则采用OpenCV的位图结构与函数,图像的显示通过建立相应的位图信息m_lpBmi来实现,为了便于管理对m_lpBmi的操作集中在OnDraw程序中。待显示位图结构发生改变时用m_dibFlag标志激发m_lpBmi的刷新。除了文件结构与图像显示外,其馀部分基本上都是OpenCV程序。
位图数据:
CVMFCDoc中, pImg (读入图像文件所得原始位图)
CVMFCView中, workImg (工作位图)、saveImg (备份位图)、m_lpBmi (工作位图的位图信息)
CVDSCap中, m_Frame (视频采集所得位图)

视图的显示管理集中在OnDraw函数中:
void CCVMFC0View::OnDraw(CDC* pDC) { …… // 其馀部分内容 if (m_dibFlag) { // 刷新 DIB位图信息 if (m_lpBmi) free(m_lpBmi); m_lpBmi = CtreateMapInfo(workImg); 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); } }
像素数据类型
图像处理主要是对像素数据的处理。需要注意的是,在OpenCV中像素存放地址imageData为char* 类型。因此,在图像处理时必须转换成BYTE* 类型才可以使用。下面以识别图像类型函数imageType为例来作说明。
int imageType(IplImage* p) // 识别图像类型 { int i,j,k,bpl,n,pg[256]; BYTE *buf; k=p->nChannels; // 1 与 3 分别表示灰阶图像与彩像 if ( k==1 ) { // 检查二值图像 for ( i = 0; i < 256; i++ ) pg[i] = 0; buf = (BYTE*) p->imageData; // 修改像素数据类型 bpl = p->widthStep; for ( i = 0; i < p->height; i++ ) { for ( j = 0; j < p->width; j++) pg[buf[j]]++; // 直方图统计 buf += bpl; } for ( i = 0, n = 0; i < 256; i++ ) if (pg[i]) n++; // 统计使用色阶数 if (n == 2) k = -1; // -1 表示二值图像 } return(k); }
图像镜像
在位图的像素方面,除了imageData的类型问题外,DIB位图与IplImage结构间还有一个显着的不同,那就是坐标原点位置的不同。前者的坐标原点在位图底部左侧,而后者在顶部左侧。因此,当在OpenCV中需要使用MFC的函数显示时位图应作垂直镜像,反之亦然。典型的例子是在OpenCV中调用DirectShow视频采集程序CameraDS中的获取当前帧函数QueryFrame,其程序如下:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-30453-3.html
记忆深刻
美舰根本进不了12海里
快回归