Draw image incorrectly

asked 2018-04-18 04:35:13 -0500

flaviu2 gravatar image

updated 2018-04-18 06:22:54 -0500

I intent to use OpenCV into MFC app, when to render images and videos ... I have used cv::Mat to load images into app, but when I draw image into CView, here is the result:

image description

opened with any viewer, the image are look like this: image description

I have used this code:

void CTestOpenView::OnDraw(CDC* pDC)
{
CTestOpenDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(NULL == pDoc || NULL == pDoc->m_pMat)
    return;

// TODO: add draw code for native data here

// Create BitmapInfo
BITMAPINFO bmi;
BITMAPINFOHEADER* pHeader= &bmi.bmiHeader;
pHeader->biSize         = sizeof(BITMAPINFOHEADER);
pHeader->biPlanes       = 1;
pHeader->biCompression   = BI_RGB;
pHeader->biXPelsPerMeter = 100;
pHeader->biYPelsPerMeter = 100;
pHeader->biClrUsed      = 0;
pHeader->biClrImportant  = 0;
pHeader->biWidth    = pDoc->m_pMat->cols;
pHeader->biHeight   = -pDoc->m_pMat->rows;
pHeader->biBitCount = 24;
bmi.bmiHeader.biSizeImage = 0;

CRect rect;
GetClientRect(&rect);

StretchDIBits(pDC->m_hDC, 0, 0, rect.Width(), rect.Height(), 
    0, 0, rect.Width(), rect.Height(), pDoc->m_pMat->data, &bmi, DIB_RGB_COLORS, SRCCOPY);
}

and in CTestOpenDoc I have

    cv::Mat* m_pMat;

nothing special ... why this image are not show correctly as color and size, and other show correctly ?

Update: I had take it from here some code: link text

and the code is:

BOOL CTestOpenDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
if (! CDocument::OnOpenDocument(lpszPathName))
    return FALSE;

// TODO: Add your specialized creation code here

m_Mat = cv::imread(lpszPathName);

int nPadding = 0;
if (CV_8UC4 != m_Mat.type()) // padding is not needed for 32bit images
{
    nPadding = 4 - (m_Mat.cols % 4);
    if(4 == nPadding)
        nPadding = 0;
}

cv::Mat matTemp;
if(nPadding > 0 || ! m_Mat.isContinuous())
{
    // Adding needed columns on the right (max 3 px)
    cv::copyMakeBorder(m_Mat, matTemp, 0, 0, 0, nPadding, cv::BORDER_CONSTANT, 0);
    m_Mat = matTemp;
}

return TRUE;
}

but the result is almost good, except there has a little black border in the right side of the image:

image description

Now, the cv::Mat object are declared as:

// Attributes
public:
cv::Mat m_Mat;

How can I get rid of this black border ? And the quality of the image are not so good ... I have done something wrong ?

Update2: I have solved using cv::BORDER_REPLICATE in cv::copyMakeBorder method.

edit retag flag offensive close merge delete

Comments

cv::Mat* m_pMat; -- please do NOT use pointers to cv::Mat, you're defeating the internal refcounting this way (not responsible for your problem, though)

berak gravatar imageberak ( 2018-04-18 04:40:21 -0500 )edit

StretchDIBits expects DWORD aligned images (width must be a multiple of 4)

berak gravatar imageberak ( 2018-04-18 04:42:34 -0500 )edit

Kindly thank you for your response. Can you detail a little bit how to re-compute the image alignment ? Or, should I not use SRCCOPY ?

flaviu2 gravatar imageflaviu2 ( 2018-04-18 05:17:21 -0500 )edit

Then, how to compute the image width ?

flaviu2 gravatar imageflaviu2 ( 2018-04-18 05:23:13 -0500 )edit

SRCCOPY only handles the composition (like: how alpha is treated)

imho, you need to either resize or pad your image, so the width requirement fits.

berak gravatar imageberak ( 2018-04-18 05:35:20 -0500 )edit

I have updated my answer. Thank you !

flaviu2 gravatar imageflaviu2 ( 2018-04-18 06:05:21 -0500 )edit

Berak, your comments mean a lot for me, I am a newbie in OpenCV ! Thank you !

flaviu2 gravatar imageflaviu2 ( 2018-04-19 03:21:22 -0500 )edit