在 OpenCV 2.2 版本之前有个类叫做 Cvvimage 可以在 MFC 中显示 IplImage ,但是自从 2.2 版本之后这个类就消失了,有人把之前版本的代码抠出来继续用,但是这样也不是很方便,比如在 C++ 中还得把 Mat 转换为 IplImage。为此找了一些资料,总算是把 cv::Mat 在各种 Windows 窗体里面的显示问题解决了,这样用起来就方便多了。在此分享出来,有需要的朋友直接拿去用吧,此文为原创,转载请注明地址,谢谢~
本文地址:http://blog.csdn.net/houston11235/article/details/7678088
下面这个函数就是实现在 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;
}