裁剪图像的OpenCV Mat无法在MFC视图上正确显示 [英] OpenCV Mat of cropped images do not correctly display on MFC View

查看:147
本文介绍了裁剪图像的OpenCV Mat无法在MFC视图上正确显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



第一个图像显示在常见的图像软件,如MS油漆,第二个是我的MFC视图。困难的是,未裁剪的图像文件正在显示很好。我不知道这是SetDIBitsToDevice或OpenCV的错误。但是明确地SetDIBitsToDevice在每行中丢失恒定的字节数。任何人都有想法解决这个问题?



  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:为本地数据添加绘制代码
int height = pDoc-> m_cvImage.rows;
int width = pDoc-> m_cvImage.cols;
uchar buffer [sizeof(BITMAPINFOHEADER)+ 1024];
BITMAPINFO * bmi =(BITMAPINFO *)缓冲区;
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&&&&> = 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对齐。这是对问题的一个不完整的描述; 每行需要在DWORD边界上启动。通常,在每行末尾插入0到3个字节的填充字符,以确保这一点。



如果填充行不方便或不可能,的图像可以被4整除。


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:

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

解决方案

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.

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视图上正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆