Display image in MFC / C ++ application using OpenCV

I would like to display frames in an MFC application that I capture from an AVI file using the OpenCV ( cvCaptureFromAVI) function .

I am new to MFC, but I feel that I'm close to getting it to work. But instead of the frames displayed in the image window, they are displayed in a new window.

cvGetWindowName always returns a null value.

There is my code:

CWnd* hPic = 0;
hPic = GetDlgItem(IDC_STATICPIC1);  
const char* szWindName = cvGetWindowName(hPic->GetSafeHwnd());
cvShowImage(szWindName, frame_copy);
+3
source share
4 answers

So, I found something to make it work after much research.

The solution is to create a window and then paste it into the image field. I'm not sure this is a good practice, but so far I have not found anything better.

cvNamedWindow("IDC_STATIC_OUTPUT", 0); 
cvResizeWindow("IDC_STATIC_OUTPUT", 420, 240);

HWND hWnd = (HWND) cvGetWindowHandle("IDC_STATIC_OUTPUT"); 
HWND hParent = ::GetParent(hWnd); 
     ::SetParent(hWnd, GetDlgItem(IDC_PIC1)->m_hWnd); 
     ::ShowWindow(hParent, SW_HIDE); 

cvShowImage("IDC_STATIC_OUTPUT", frame_copy);

IDC_PIC1, frame_copy - IplImage OpenCV.

, -.

+7

, Mat CImage, CImage , :

int Mat2CImage(Mat *mat, CImage &img){
  if(!mat || mat->empty())
    return -1;
  int nBPP = mat->channels()*8;
  img.Create(mat->cols, mat->rows, nBPP);
  if(nBPP == 8)
  {
    static RGBQUAD pRGB[256];
    for (int i = 0; i < 256; i++)
        pRGB[i].rgbBlue = pRGB[i].rgbGreen = pRGB[i].rgbRed = i;
    img.SetColorTable(0, 256, pRGB);
  }
  uchar* psrc = mat->data;
  uchar* pdst = (uchar*) img.GetBits();
  int imgPitch = img.GetPitch();
  for(int y = 0; y < mat->rows; y++)
  {
    memcpy(pdst, psrc, mat->cols*mat->channels());//mat->step is incorrect for those images created by roi (sub-images!)
    psrc += mat->step;
    pdst += imgPitch;
  }

  return 0;
}
+6

. StretchDIBits() BITMAPINFO, , StretchDIBits() , raw OpenCV Mat:: data 4 ! , , DC StretchDIBits(), , .

, . , , :

void AdjustAspectImageSize( const Size& imageSize,
                            const Size& destSize, 
                                  Size& newSize )
{
   double destAspectRatio   =  float( destSize.width  )  /  float( destSize.height  );
   double imageAspectRatio  =  float( imageSize.width )  /  float( imageSize.height );

   if ( imageAspectRatio > destAspectRatio )
   {
      // Margins on top/bottom
      newSize.width    =   destSize.width;
      newSize.height   =   int( imageSize.height  *  
                                    ( double( destSize.width )  /  double( imageSize.width ) ) );
   }
   else
   {
      // Margins on left/right
      newSize.height   =   destSize.height;
      newSize.width    =   int( imageSize.width  *
                                    ( double( destSize.height )  /  double( imageSize.height ) ) );
   }
}


void DrawPicToHDC( Mat  cvImg, 
                   UINT nDlgID, 
                   bool bMaintainAspectRatio /* =true*/  )
{
   // Get the HDC handle information from the ID passed
   CDC* pDC  =  GetDlgItem(nDlgID)->GetDC();
   HDC  hDC  =  pDC->GetSafeHdc();

   CRect rect;
   GetDlgItem(nDlgID)->GetClientRect(rect);

   Size winSize( rect.right, rect.bottom );

   // Calculate the size of the image that
   // will fit in the control rectangle.
   Size origImageSize( cvImg.cols, cvImg.rows );
   Size imageSize;
   int  offsetX;
   int  offsetY;

   if ( ! bMaintainAspectRatio )
   {
      // Image should be the same size as the control rectangle
      imageSize = winSize;
   }
   else
   {
      Size newSize;

      _AdjustAspectImageSize( origImageSize,
                              winSize,
                              imageSize );
   }

   offsetX   =   ( winSize.width  - imageSize.width  )  /  2;
   offsetY   =   ( winSize.height - imageSize.height )  /  2;

   // Resize the source to the size of the destination image if necessary
   Mat cvImgTmp;

   resize( cvImg, 
           cvImgTmp, 
           imageSize,
           0,
           0,
           INTER_AREA );

   // To handle our Mat object of this width, the source rows must
   // be even multiples of a DWORD in length to be compatible with 
   // SetDIBits().  Calculate what the correct byte width of the 
   // row should be to be compatible with SetDIBits() below.
   int stride  =  ( ( ( ( imageSize.width * 24 )  +  31 )  &  ~31 )  >>  3 );

   // Allocate a buffer for our DIB bits
   uchar* pcDibBits  =  (uchar*) malloc( imageSize.height * stride );

   if ( pcDibBits != NULL )
   {
      // Copy the raw pixel data over to our dibBits buffer.
      // NOTE: Can setup cvImgTmp to add the padding to skip this.
      for ( int row = 0;  row < cvImgTmp.rows;  ++row )
      {
         // Get pointers to the beginning of the row on both buffers
         uchar* pcSrcPixel  =  cvImgTmp.ptr<uchar>(row);
         uchar* pcDstPixel  =  pcDibBits  +  ( row * stride );

         // We can just use memcpy
         memcpy( pcDstPixel,
                 pcSrcPixel,
                 stride );
      }

      // Initialize the BITMAPINFO structure
      BITMAPINFO bitInfo;

      bitInfo.bmiHeader.biBitCount       =  24;
      bitInfo.bmiHeader.biWidth          =   cvImgTmp.cols;
      bitInfo.bmiHeader.biHeight         =  -cvImgTmp.rows;
      bitInfo.bmiHeader.biPlanes         =  1;
      bitInfo.bmiHeader.biSize           =  sizeof(BITMAPINFOHEADER);
      bitInfo.bmiHeader.biCompression    =  BI_RGB;
      bitInfo.bmiHeader.biClrImportant   =  0;
      bitInfo.bmiHeader.biClrUsed        =  0;
      bitInfo.bmiHeader.biSizeImage      =  0;      //winSize.height * winSize.width * * 3;
      bitInfo.bmiHeader.biXPelsPerMeter  =  0;
      bitInfo.bmiHeader.biYPelsPerMeter  =  0;

      // Add header and OPENCV image data to the HDC
      StretchDIBits( hDC, 
                     offsetX, 
                     offsetY,
                     cvImgTmp.cols,
                     cvImgTmp.rows,
                     0, 
                     0,
                     cvImgTmp.cols,
                     cvImgTmp.rows,
                     pcDibBits,
                     & bitInfo, 
                     DIB_RGB_COLORS, 
                     SRCCOPY );

      free(pcDibBits);
   }

   ReleaseDC(pDC);
}
0

int DrawImageToHDC (IplImage * img, HDC hdc, int xDest, int yDest, UINT iUsage, DWORD rop)

{

char m_chBmpBuf[2048];
BITMAPINFO *m_pBmpInfo = 0;
m_pBmpInfo = (BITMAPINFO*)m_chBmpBuf;
m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_pBmpInfo->bmiHeader.biWidth = img->width;
m_pBmpInfo->bmiHeader.biHeight = -img->height;
m_pBmpInfo->bmiHeader.biBitCount = 24;

m_pBmpInfo->bmiHeader.biPlanes = 1;
m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
m_pBmpInfo->bmiHeader.biSizeImage = 0;
m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biClrUsed = 0;
m_pBmpInfo->bmiHeader.biClrImportant = 0;

return StretchDIBits(hdc, xDest, yDest, img->width, img->height, 0, 0,

img-> width, img-> height, img-> imageData, m_pBmpInfo, DIB_RGB_COLORS, SRCCOPY);

}

Usage: DrawImageToHDC (img, pDC-> m_hDC, Area.left, Area.top, DIB_RGB_COLORS, SRCCOPY);

-2
source

All Articles