1

I cannot properly convert and/or display an ROI using a QRect in a QImage and create a cv::Mat image out of the QImage. The problem is symmetric, i.e, I cannot properly get the ROI by using a cv::Rect in a cv::Mat and creating a QImage out of the Mat. Surprisingly, everything work fine whenever the width and the height of the cv::Rect or the QRect are equal.

In what follows, my full-size image is the cv::Mat matImage. It is of type CV_8U and has a square size of 2048x2048

int x = 614;
int y = 1156;

// buggy
int width = 234;
int height = 278;

//working
//    int width = 400;
//    int height = 400;
QRect ROI(x, y, width, height);

QImage imageInit(matImage.data, matImage.cols, matImage.rows,   QImage::Format_Grayscale8);
QImage imageROI = imageInit.copy(ROI);
createNewImage(imageROI);

unsigned char* dataBuffer = imageROI.bits();
cv::Mat tempImage(cv::Size(imageROI.width(), imageROI.height()), CV_8UC1, dataBuffer, cv::Mat::AUTO_STEP);

cv::namedWindow( "openCV imshow() from a cv::Mat image", cv::WINDOW_AUTOSIZE );
cv::imshow( "openCV imshow() from a cv::Mat image", tempImage);  

The screenshot below illustrates the issue.

full size and ROI (Left) The full-size cv::Mat matImage. (Middle) the expected result from the QImage and the QRect (which roughly corresponds to the green rectangle drawn by hand). (Right) the messed-up result from the cv::Mat matImageROI

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Wall-E
  • 623
  • 5
  • 17

1 Answers1

0

By exploring other issues regarding conversion between cv::Mat and QImage, it seems the stride becomes "non-standard" in some particular ROI sizes. For example, from this post, I found out one just needs to change cv::Mat::AUTO_STEP to imageROI.bytesPerLine() in cv::Mat tempImage(cv::Size(imageROI.width(), imageROI.height()), CV_8UC1, dataBuffer, cv::Mat::AUTO_STEP);

so I end up instead with: cv::Mat matImageROI(cv::Size(imageROI.width(), imageROI.height()), CV_8UC1, dataBuffer, imageROI.bytesPerLine());

For the other way round, i.e, creating the QImage from a ROI of a cv::Mat, one would use the property cv::Mat::step.

For example:

QImage imageROI(matImageROI.data, matImageROI.cols, matImageROI.rows, matImageROI.step, QImage::Format_Grayscale8);

instead of:

QImage imageROI(matImageROI.data, matImageROI.cols, matImageROI.rows, QImage::Format_Grayscale8);

Update

For the case of odd ROI sizes, although it is not a problem when using either imshow() with cv::Mat or QImage in QGraphicsScene, it becomes an issue when using openGL (with QOpenGLWidget). I guess the simplest workaround is just to constrain ROIs to have even sizes.

Community
  • 1
  • 1
Wall-E
  • 623
  • 5
  • 17