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)));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM