opencv的Mat图像显示在MFC控件中

opencv的Mat图像显示在MFC控件中

方法:

  只需要给Mat图像建立一个位图信息头即可;
例:
头文件中(.h)成员:

cv::Mat m_image
BITMAPINFO *m_imgInfo;

源文件中(.cpp):

BOOL CPointMatchDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	// TODO:  在此添加额外的初始化代码
	
	m_image = cv::imread("E:\dog.jpeg", cv::IMREAD_UNCHANGED);                 //(1)

    //根据图像通道数建立图像信息(这里假定图像像素为24与32位或者8位(有颜色表的类似))
    if(m_image.channels() == 3 || m_image.channels() == 4)
    {
        m_imgInfo = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER)];
    }
    else    //8位,有颜色表
    {
        m_imgInfo = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)];
        //颜色表赋值
        for (int i(0); i < 256; ++i)
        {
	        m_imgInfo ->bmiColors[i].rgbBlue = i;
	        m_imgInfo ->bmiColors[i].rgbGreen = i;
	        m_imgInfo ->bmiColors[i].rgbRed = i;
	        m_imgInfo ->bmiColors[i].rgbReserved = 0;
        }
    }

    //头文件信息(注意由实际显示情况可得出图像原点显示在空间左下角)
    m_imgInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    m_imgInfo->bmiHeader.biBitCount = 8 * m_image .channels();
    m_imgInfo->bmiHeader.biHeight = -m_image .rows;
    m_imgInfo->bmiHeader.biWidth = m_image .cols;
    m_imgInfo->bmiHeader.biPlanes = 1;
    m_imgInfo->bmiHeader.biCompression = BI_RGB;
    m_imgInfo->bmiHeader.biSizeImage = m_image .channels() * m_image .cols * m_image .rows;
    m_imgInfo->bmiHeader.biXPelsPerMeter = 0;
    m_imgInfo->bmiHeader.biYPelsPerMeter = 0;
    m_imgInfo->bmiHeader.biClrUsed = 0;
    m_imgInfo->bmiHeader.biClrImportant = 0;
	
	return TRUE;
}

void CPointMatchDlg::OnPaint()
{
	CDC *pDC;
	pDC = GetDlgItem(IDC_MATCH_PICTURE_CONTROL)->GetDC();
	CRecr imgCtrlRect;
	GetDlgItem(IDC_MATCH_PICTURE_CONTROL)->GetClientRect(&imgCtrlRect);
	
	pDC->SetStretchBltMode(COLORONCOLOR);
	::StretchDIBits(pDC->GetSafeHdc(), 
				0, 0, 
				imgCtrlRect.Width(), m_imgCtrlRect.Height(), 
				0, 0, 
				m_image.cols, m_image.rows, 
				m_image.data, 
				m_imgInfo, 
				DIB_RGB_COLORS, 
				SRCCOPY);

	ReleaseDC(pDC);
}

注:onPaint中的绘图程序一定不要放到OnInitDialog中,否则会发现StretchDIBits返回值不为零(说明函数执行正常),但是图像无法显示——OnInitDialog中是对话框初始化程序,对话框还没有初始化完成。OnInitDialog(初始化完成)后系统会自动调用onPaint绘制窗口(则OnInitDialog中显示图片没有意义,会被擦除)。

注意:
  这里绘制图片时,一定要保证Mat图片符合window图片要求(即每行字节数为4的倍数),如果不满足则要进行适当的转化,否则画出的图像会出现问题(图像不是标准图像,反而是斜的)。
  如果图片行字节数不是4的倍数,可在语句(1)修改为如下语句:

cv::Mat tempImg =  cv::imread("E:\dog.jpeg", cv::IMREAD_UNCHANGED); 
m_image = cv::Mat::zeros(tempImg.rows, (tempImg.cols + 3) / 4 * 4, m_image.type());   //转化行字节数为4的倍数(这里直接转化行像素为4的倍数)
tempImage.copyTo(m_image(cv::Rect(0, 0, tempImg.cols, tempImg.rows)));
原文地址:https://www.cnblogs.com/silentteen/p/7732487.html