OpenCV Mat of cropped images do not correctly display on MFC View(裁剪图像的 OpenCV Mat 无法在 MFC 视图上正确显示)
问题描述
我正在使用以下例程在 MFC 视图上显示 OpenCV Mat.它适用于未裁剪的图像.但是对于预先裁剪的图像,它会显示如下所示的空白或奇怪的图像:
I am using following routines to display OpenCV Mat on MFC View. And it's working well for uncropped images. But for pre-cropped images, it shows blank or weird images like the ones below:
第一个显示在 MS Paint 等常用图像软件上,第二个显示在我的 MFC 视图上.困难在于未裁剪的图像文件显示得很好.我不确定这是 SetDIBitsToDevice 或 OpenCV 的错.但显然 SetDIBitsToDevice 在每行中丢失了恒定数量的字节.有人有解决这个问题的想法吗?
First one is displayed on usual image software such as MS Paint and the second is on my MFC view. Difficult is that uncropped image files are displaying just fine. I am not sure this is fault of SetDIBitsToDevice or OpenCV. But clearly SetDIBitsToDevice loses constant number of bytes in each row. Anybody has any idea to fix this problem?
cv::Mat m_cvImage;
static int Bpp(cv::Mat img) { return 8 * img.channels(); }
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;
}
}
}
推荐答案
正如 Roel 所说,位图数据需要双字对齐.然而,这是对问题的不完整描述;每一行数据都需要从一个 DWORD 边界开始.通常,您会在每行的末尾插入 0 到 3 个字节的填充以确保这一点.
As Roel says, the bitmap data needs to be DWORD aligned. This is an incomplete description of the problem however; each row of the data needs to start on a DWORD boundary. Typically you insert 0 to 3 bytes of padding at the end of each row to ensure this.
如果不方便或无法填充行,只需确保图像的宽度可以被 4 整除.
If it is inconvenient or impossible to pad the rows, simply make sure the width of the image is evenly divisible by 4.
这篇关于裁剪图像的 OpenCV Mat 无法在 MFC 视图上正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:裁剪图像的 OpenCV Mat 无法在 MFC 视图上正确显示
基础教程推荐
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 初始化列表*参数*评估顺序 2021-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- CString 到 char* 2021-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
