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 视图上正确显示


基础教程推荐
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 常量变量在标题中不起作用 2021-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01