裁剪图像的 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.
相关文章