OpenCV裁剪图像的垫子无法在MFC视图上正确显示

时间:2011-12-17 18:08:22

标签: c++ mfc opencv

我正在使用以下例程在MFC View上显示OpenCV Mat。并且它适用于未剪切的图像。但对于预裁剪的图像,它会显示空白或奇怪的图像,如下图所示:

第一个显示在常用图像软件(如MS Paint)上,第二个显示在我的MFC视图上。很难的是,未剪切的图像文件显示得很好。我不确定这是SetDIBitsToDevice或OpenCV的错误。但显然SetDIBitsToDevice在每一行中丢失了恒定的字节数。有人有任何想法解决这个问题吗?

Correct Displayed

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; 
    } 
} 
}

2 个答案:

答案 0 :(得分:3)

我没有详细调查您的示例,但请注意,传递给SetDIBitsToDevice的数据需要在DWORD边界(IIRC)上对齐。也许你工作的90%的情况都是相同的尺寸,而且事情是偶然的,当你旋转对齐开关时。

我希望在这种情况下你不会看到没有输出,但是GDI驱动程序可能检测到错误的对齐并且根本不做任何blitting。听起来很合理。

我想我发布了一个函数示例,该函数在DWORD边界上正确对齐,以便与之前的SetDIBitsToDevice一起使用,搜索我的帖子以获取代码示例。

答案 1 :(得分:3)

作为Roel says,位图数据需要与DWORD对齐。然而,这是对问题的不完整描述; 数据的每一行需要在DWORD边界上启动。通常,在每行的末尾插入0到3个字节的填充以确保这一点。

如果不方便或无法填充行,只需确保图像的宽度可被4整除。