OpenCV中Mat、IplImage格式的图片,显示到MFC中的picture控件上

2019-04-15 16:29发布

OpenCV中Mat、IplImage格式的图片,显示到MFC中的picture控件上

问题1.位图显示在picture控件上

如果你会把位图显示到picture在控件上,那么要将opencv中的Mat、IplImage格式的图片矩阵数据显示在MFC中的picture控件上就很容易了。 如下代码: CDC* pDC = m_ColorArea.GetDC(); // 颜 {MOD}面板的CDC CDC memDC; // 内存CDC CBitmap bitmap; // 内存位图 BITMAP infoBitmap; // 位图信息结构体 // 创建内存CDC memDC.CreateCompatibleDC(pDC); // 创建设备相关位图 bitmap.CreateCompatibleBitmap(pDC, width, height); // 获得位图信息 bitmap.GetBitmap(&infoBitmap); // 是否支持32位颜 {MOD} if (infoBitmap.bmBitsPixel != 32) { MessageBox(L"当前显示设备不支持32位颜 {MOD},程序自动退出!"); PostMessage(WM_QUIT); } BYTE* pixels = new BYTE[width*height * 4]; // 32位颜 {MOD}点阵数组 ..................... // 设置位图的点阵信息 bitmap.SetBitmapBits(width*height * 4, pixels); memDC.SelectObject(bitmap); // 拷贝内存CDC中的内容 pDC->BitBlt(0, 0,width, height, &memDC, 0, 0, SRCCOPY); //pDC->StretchBlt(0,0,ctrl.Width(),ctrl.Height,&memDC,0,0,width,height,SRCCOPY);//以压缩和拉伸的方式显示位图 ReleaseDC(pDC); SAFE_DELETE_ARRAY (pixels);要显示一张位图,首先要创建兼容DC,调用CreateCompatibleDC函数后就会在内存中开辟空间,设置与设备相关的属性值,当然这些值的设置,你也可以自己进行。然后通过 函数CreateCompatibleBitmap来创建设备相关的位图,通过CBitmap中的GetBitmap函数得知设备中位图的显示格式。然后是得到像素值,就是uchar类型的堆。再通过CBitmap 中的SetBitmapBits函数将像素值保存到CBitmap的实例中。接着选择到设备上下文中。最后将设备上下文中的位图数据拷贝到屏幕上。

问题2.像素值的排列

将Mat、IlpImage格式的矩阵数据显示到MFC的picture控件上,唯一的问题就是其中的像素数据的排列的方式的问题。32位 {MOD}的显示器,每一个像素的值都是R位、G位、B位、 保留位,这样的顺序排列的,对于黑白图像RGB三个分量的值是相同的。而对于Mat和IlpImage的图像格式3通道的彩 {MOD}图像是按R、G、B的顺序排列每一位的彩 {MOD}像素值,而 没有保留位,所以显示位图的时候要把保留位加上。对于灰度图像来说,Mat和IlpImage直接按灰度值排列。他们都是按先行后列的方式排列的。 如下代码: std::string strName = (LPCTSTR)dlg.GetPathName(); cv::Mat test = cv::imread(strName); //把Mat格式的图像数据显示到控件上 CPicture *pPicture = this; CDC* pDC = pPicture->GetDC(); CDC memCDC; CBitmap bitmap; BITMAP infoBitmap; memCDC.CreateCompatibleDC(pDC); bitmap.CreateCompatibleBitmap(pDC,test.cols,test.rows); bitmap.GetBitmap(&infoBitmap); uchar *p = test.ptr(0); Vec3b *pVec3b = test.ptr(0); int row = test.rows, col = test.cols; uchar *pixel = new uchar[row*col*4]; if(test.channels() > 1 && infoBitmap.bmBitsPixel == 32) { int j=0; for(int i=0;iGetClientRect(&rect); //pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memCDC,0,0,SRCCOPY); pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&memCDC,0,0,test.cols,test.rows,SRCCOPY); memCDC.DeleteDC(); bitmap.DeleteObject(); delete[] pixel;