1. 程式人生 > >MFC/C# 中顯示 OpenCV 的 Mat

MFC/C# 中顯示 OpenCV 的 Mat

在 OpenCV 2.2 版本之前有個類叫做 Cvvimage 可以在 MFC 中顯示 IplImage ,但是自從 2.2 版本之後這個類就消失了,有人把之前版本的程式碼摳出來繼續用,但是這樣也不是很方便,比如在 C++ 中還得把 Mat 轉換為 IplImage。為此找了一些資料,總算是把 cv::Mat 在各種 Windows 窗體裡面的顯示問題解決了,這樣用起來就方便多了。在此分享出來,有需要的朋友直接拿去用吧,此文為原創,轉載請註明地址,謝謝~

下面這個函式就是實現在 MFC 或者 C# 的窗體中顯示 Mat 的功能,之所以這麼說是因為不管程式語言是什麼, Windows 的窗體都有一個叫做控制代碼(在 C# 中對應 handle)的東西,把這個作為函式的第二個引數傳進來就行了。

這個函式要用到 ATL 中的 CImage 類,需要引用標頭檔案 atlimage.h,注意這個要放在 cv.h 神馬的前面,最好就放在 windows.h 後面,否則編譯會出現 ‘min’ 和 ‘max’ 未定義的錯誤。

另外這個函式只實現了 3 通道影象的顯示功能, 1 通道的影象請參考本文最後的連結。

int ShowMat( cv::Mat img, HWND hWndDisplay )
{
	if (img.channels()<3 )
	{
		return -1;
	}

	RECT rect;
	GetClientRect(hWndDisplay, &rect);
	cv::Mat imgShow( abs(rect.top - rect.bottom), abs(rect.right - rect.left), CV_8UC3 );
	resize( img, imgShow, imgShow.size() );

	ATL::CImage CI;
	int w=imgShow.cols;//寬
	int h=imgShow.rows;//高
	int channels=imgShow.channels();//通道數

	CI.Create( w, h, 8*channels);
	uchar *pS;
	uchar *pImg=(uchar *)CI.GetBits();//得到CImage資料區地址
	int step=CI.GetPitch();
	for(int i=0;i<h;i++)
	{
		pS=imgShow.ptr<uchar>(i);
		for(int j=0;j<w;j++)
		{
			for(int k=0;k<3;k++)
				*(pImg+i*step+j*3+k)=pS[j*3+k];
			//注意到這裡的step不用乘以3
		}
	}

	HDC dc ;
	dc = GetDC( hWndDisplay );
	CI.Draw( dc, 0, 0 );
	ReleaseDC( hWndDisplay, dc);
	CI.Destroy();

	return 0;
}
參考連結:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=15224