Advertisement
alfps

Display OpenCV RGB image in a Windows window

Apr 25th, 2020
594
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. #pragma once
  2. #include <header-wrappers/winapi/windows-h.hpp>
  3. #include <opencv2/opencv.hpp>
  4.  
  5. #include <assert.h>
  6.  
  7. namespace win_cv
  8. {
  9.     inline void display_aligned_bgr( const HDC dc, const cv::Mat& image )
  10.     {
  11.         constexpr int pixels_per_meter = 2835;  // 72 DPI × 39.3701 inch/meter. Is ignored.
  12.  
  13.         assert( image.channels() == 3 );                    // BGR format.
  14.         assert( CV_MAT_DEPTH( image.type() ) == CV_8U );    // Of bytes.
  15.         assert( image.step % 4 == 0 );                      // With 4 byte row alignment.
  16.  
  17.         const int logical_width     = image.cols;
  18.         const int physical_width    = int( image.step / 3 );   assert( image.step % 3 == 0 );
  19.         const int height            = image.rows;
  20.  
  21.         BITMAPINFO bmpinfo = {};
  22.         bmpinfo.bmiHeader.biSize            = sizeof (BITMAPINFOHEADER );
  23.         bmpinfo.bmiHeader.biBitCount        = 24;
  24.         bmpinfo.bmiHeader.biClrImportant    = 0;
  25.         bmpinfo.bmiHeader.biClrUsed         = 0;
  26.         bmpinfo.bmiHeader.biCompression     = BI_RGB;
  27.         bmpinfo.bmiHeader.biWidth           = physical_width;
  28.         bmpinfo.bmiHeader.biHeight          = -height;
  29.         bmpinfo.bmiHeader.biPlanes          = 1;
  30.         bmpinfo.bmiHeader.biSizeImage       = 0;
  31.         bmpinfo.bmiHeader.biXPelsPerMeter   = pixels_per_meter;
  32.         bmpinfo.bmiHeader.biYPelsPerMeter   = pixels_per_meter;
  33.  
  34.         //const auto& h = bmpinfo.bmiHeader;
  35.         //const int stride = ((((h.biWidth * h.biBitCount) + 31) & ~31) >> 3);
  36.         //const int cvstep = image.step;
  37.         //assert( stride == cvstep );
  38.  
  39.         const int n_scan_lines_set = SetDIBitsToDevice(
  40.             dc,                 // hdc
  41.             0,                  // xDest
  42.             0,                  // yDest
  43.             logical_width,      // w
  44.             height,             // h
  45.             0,                  // xSrc
  46.             0,                  // ySrc
  47.             0,                  // StartScan
  48.             height,             // cLines
  49.             image.data,         // lpvBits
  50.             &bmpinfo,           // lpbmi
  51.             DIB_RGB_COLORS      // ColorUse
  52.         );
  53.         (void) n_scan_lines_set;
  54.     }
  55.  
  56.     inline auto compatible_image( const cv::Mat image )
  57.         -> cv::Mat
  58.     {
  59.         const int stepmod = image.step % 4;
  60.         if( stepmod == 0 ) {
  61.             return image;
  62.         } else {
  63.             const int colsmod = image.cols % 4;
  64.             cv::Mat aligned_image_data( image.rows, image.cols + (4 - colsmod), image.type() );
  65.             cv::Mat aligned_image = aligned_image_data( cv::Rect( 0, 0, image.cols, image.rows ) );
  66.             image.copyTo( aligned_image );
  67.             return aligned_image;
  68.         }
  69.     }
  70.  
  71.     inline void display_bgr( const HDC dc, const cv::Mat& image )
  72.     {
  73.         const int stepmod = image.step % 4;
  74.         if( stepmod == 0 ) {
  75.             display_aligned_bgr( dc, image );
  76.         } else {
  77.             display_aligned_bgr( dc, compatible_image( image ) );
  78.         }
  79.     }
  80. }  // namespace win_cv
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement