本文主要是介绍OpenCV4.1 显示图像到MFC Pictrue控件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
新版本的opencv取消了CvvImage,然而就不支持在MFC中显示了。这里介绍一种新的显示图像的方法。
环境:OpenCV4.1 +MCF 对话框 +Picture控件
方法一:直接将Mat显示在Picture窗体上
显示函数定义如下,
// MFC上Picture Control控件显示图像// src 待显示的图像 (OpenCV库Mat对象结构)// hwnd MFC显示图像的窗口句柄void CXXXDlg::ShowImage(Mat& imgSrc, HWND hwnd) {HDC hdc = ::GetDC(hwnd);CRect rect;//获取图片控件矩形框GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetClientRect(&rect);//缩放Mat,以适应图片控件大小cv::resize(imgSrc, imgSrc, cv::Size(rect.Width(), rect.Height()));//cv::resize(imgSrc, imgSrc, cv::Size(300, 300));// 转换格式 ,便于获取BITMAPINFOswitch (imgSrc.channels()){case 1:cv::cvtColor(imgSrc, imgSrc, COLOR_GRAY2BGRA); // GRAY单通道break;case 3:cv::cvtColor(imgSrc, imgSrc, COLOR_BGR2BGRA); // BGR三通道break;default:break;}// 计算一个像素多少个字节int pixelBytes = imgSrc.channels()*(imgSrc.depth() + 1);// 制作bitmapinfo(数据头)BITMAPINFO bitInfo;bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;bitInfo.bmiHeader.biWidth = imgSrc.cols;bitInfo.bmiHeader.biHeight = -imgSrc.rows; //注意"-"号(正数时倒着绘制)bitInfo.bmiHeader.biPlanes = 1;bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bitInfo.bmiHeader.biCompression = BI_RGB;bitInfo.bmiHeader.biClrImportant = 0;bitInfo.bmiHeader.biClrUsed = 0;bitInfo.bmiHeader.biSizeImage = 0;bitInfo.bmiHeader.biXPelsPerMeter = 0;bitInfo.bmiHeader.biYPelsPerMeter = 0;CDC *pDC = GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetDC(); //获取图片控件DC//绘图::StretchDIBits(pDC->GetSafeHdc(),0, 0, rect.Width(), rect.Height(),0, 0, imgSrc.cols, imgSrc.rows,imgSrc.data,&bitInfo,DIB_RGB_COLORS,SRCCOPY);ReleaseDC(pDC); //释放DC}
函数调用方法:
HWND hwnd = GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetSafeHwnd();
// 获取显示的图像
Mat img = imread("D:/images/11111.jpg");
// 调用显示函数
ShowImage(img, hwnd);
方法二:用Mat转CImage的方式,然后在Pictrue控件上绘制CImage
Mat转CImage
void CXXXDlg::MatToCImage(Mat &mat, CImage &cImage){//create new CImage int width = mat.cols;int height = mat.rows;int channels = mat.channels();cImage.Destroy(); //clear cImage.Create(width, height, 8 * channels); //默认图像像素单通道占用1个字节 //copy values uchar* ps;uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer int step = cImage.GetPitch();for (int i = 0; i < height; ++i){ps = (mat.ptr<uchar>(i));for (int j = 0; j < width; ++j){if (channels == 1) //gray {*(pimg + i * step + j) = ps[j];}else if (channels == 3) //color {for (int k = 0; k < 3; ++k){*(pimg + i * step + j * 3 + k) = ps[j * 3 + k];}}}}
}
函数调用示例:
void CXXXDlg::ShowMethord4(){int cxl, cyl;Mat rgbImageL1 = imread("D:/images/11111.jpg");//opencv图片CImage rgbImageL2;CRect rectl, pic_rectl;int widthl, heightl;//改变图片大小适应picture控件GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetClientRect(&pic_rectl);widthl = pic_rectl.right;heightl = pic_rectl.bottom;resize(rgbImageL1, rgbImageL1, Size(widthl, heightl));MatToCImage(rgbImageL1, rgbImageL2);//OpenCV中Mat对象转MFC的CImage类的函数//获取图片的宽 高度 cxl = rgbImageL2.GetWidth();cyl = rgbImageL2.GetHeight();//获取Picture Control控件的大小 GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetWindowRect(&rectl);//将客户区选中到控件表示的矩形区域内 ScreenToClient(&rectl);//窗口移动到控件表示的区域 GetDlgItem(IDC_STATIC_SHOWIMAGE)->MoveWindow(rectl.left, rectl.top, cxl, cyl, TRUE);CWnd *pWnd = NULL;pWnd = GetDlgItem(IDC_STATIC_SHOWIMAGE);//获取控件句柄 pWnd->GetClientRect(&rectl);//获取句柄指向控件区域的大小 CDC *pDc = NULL;pDc = pWnd->GetDC();//获取picture的DC rgbImageL2.Draw(pDc->m_hDC, rectl);//将图片绘制到picture表示的区域内 ReleaseDC(pDc);}
这篇关于OpenCV4.1 显示图像到MFC Pictrue控件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!