如何在MFC视图上显示OpenCV Mat
How to display OpenCV Mat on MFC View
我认为在MFC视图上显示OpenCV2 Mat很简单,但事实并非如此。这只是我在谷歌上找到的相关资料。请原谅我的无知,但我找不到任何其他材料显示如何使用一维数组"数据"成员返回SetDIBitsToDevice。更具体地说,我需要知道如何为函数指定BITMAPINFO。我回到旧的c风格的OpenCV与MFC工作吗?
更新:
我发现了一个SetDIBitsToDevice的例子,它实际上是旧的c风格的OpenCV。但是将它转换为OpenCV2是很简单的。为了使它起作用,我需要提到一些事情:
-
Bpp方法不工作,因为Mat的深度返回0。我只是像这样修改:
static int Bpp(cv::Mat img) { return 8 * img.channels(); }
-
Mat没有origin成员。但是对于FillBitmapInfo方法的origin参数,只要输入0就可以了
除此之外,下面的代码工作得很好。希望这对其他开发者也有帮助。
void COpenCVTestView::OnDraw(CDC* pDC)
{
COpenCVTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
if(pDoc->m_cvImage.empty()) return;
// TODO: add draw code for native data here
int height=pDoc->m_cvImage.rows;
int width=pDoc->m_cvImage.cols;
uchar buffer[sizeof( BITMAPINFOHEADER ) + 1024];
BITMAPINFO* bmi = (BITMAPINFO* )buffer;
FillBitmapInfo(bmi,width,height,Bpp(pDoc->m_cvImage),0);
SetDIBitsToDevice(pDC->GetSafeHdc(), 0, 0, width,
height, 0, 0, 0, height, pDoc->m_cvImage.data, bmi,
DIB_RGB_COLORS);
}
void COpenCVTestView::FillBitmapInfo(BITMAPINFO* bmi, int width, int height, int bpp, int origin)
{
assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset(bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = origin ? abs(height) : -abs(height);
bmih->biPlanes = 1;
bmih->biBitCount = (unsigned short)bpp;
bmih->biCompression = BI_RGB;
if (bpp == 8)
{
RGBQUAD* palette = bmi->bmiColors;
for (int i = 0; i < 256; i++)
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
}
这是在MFC中显示OpenCV数据的另一种可能的方法,我使用并且效果很好:
IplImage* image// <-- this contains the image you want to display
CvvImage tempdefault;
RECT myrect; // <-- specifiy where on the screen you want it to be displayed
myrect.top = 0;
myrect.bottom = _pictureh;
myrect.left = _picturex;
myrect.right = _picturew+_picturex;
tempdefault.Create(_pictureh,_picturew,32);
tempdefault.CopyOf(image);
tempdefault.DrawToHDC(pDC->GetSafeHdc(),&myrect);
From MSDN:
lpvBits[在]指向以字节数组形式存储的颜色数据的指针。有关更多信息,请参阅以下"备注"部分。
这个指针必须用Mat::data返回的数据初始化。
CvvImage在新版本的OpenCV中不可用。使用以下代码,您可以将Mat转换为CImage,然后在您想要的任何地方显示CImage:
int Mat2CImage(Mat *mat, CImage &img){
if(!mat || mat->empty())
return -1;
int nBPP = mat->channels()*8;
img.Create(mat->cols, mat->rows, nBPP);
if(nBPP == 8)
{
static RGBQUAD pRGB[256];
for (int i = 0; i < 256; i++)
pRGB[i].rgbBlue = pRGB[i].rgbGreen = pRGB[i].rgbRed = i;
img.SetColorTable(0, 256, pRGB);
}
uchar* psrc = mat->data;
uchar* pdst = (uchar*) img.GetBits();
int imgPitch = img.GetPitch();
for(int y = 0; y < mat->rows; y++)
{
memcpy(pdst, psrc, mat->cols*mat->channels());//mat->step is incorrect for those images created by roi (sub-images!)
psrc += mat->step;
pdst += imgPitch;
}
return 0;
}
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如果不在窗口 10 中声明名为 openCV 的 openCV namedWindow,QT 图像显示将无法正常工作
- OpenCV QT,显示视频的帧(不使用while循环)
- 如何使用OpenCV同时显示"深度"和"颜色"视频图像
- 无法在 Opencv 中显示图像导致内存位置
- 有没有办法拿一个opencv显示窗口并将其保存到GUI窗口?
- openCV中的Absdiff可以编译,但显示黑色图像
- OpenCV版本显示错误
- C++/openCV - 为什么显示图像会产生 Linux 分割错误?(打开CV错误?
- OpenCV没有显示来自Macbook网络摄像头的视频
- 如何使用OpenCV在不同的显示器中显示不同的窗口
- 如何在任何使用 Opencv 的计算机上显示图像
- OpenCV Webcam 源未显示在 PictureBox visual studio 2015 中
- 如何将OpenCV的输出显示或流式传输到HTML页面或其他一些客户端应用程序
- 使用 opencv 同时显示多个摄像机馈送
- 如何在QT中有效显示OpenCV视频
- 未显示 OpenCV 运行时"Errors"
- 显示OpenCV在Android上创建的图像
- 如何在MFC视图上显示OpenCV Mat
- 读取和显示opencv视频的程序工作不正常