1

我无法在 QImage 中使用 QRect 正确转换和/或显示 ROI,并从 QImage 中创建 cv::Mat 图像。问题是对称的,即我无法通过在 cv::Mat 中使用 cv::Rect 并从 Mat 中创建 QImage 来正确获得 ROI。令人惊讶的是,只要 cv::Rect 或 QRect 的宽度和高度相等,一切都会正常工作。

接下来,我的全尺寸图像是 cv::Mat matImage。它是类型CV_8U,正方形大小为 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);  

下面的屏幕截图说明了这个问题。

全尺寸和投资回报率 (左)全尺寸cv::Mat matImageQImage(中)和的预期结果QRect(大致对应于手工绘制的绿色矩形)。(右)混乱的结果cv::Mat matImageROI

4

1 回答 1

0

cv::Mat通过探索有关和之间转换的其他问题QImage,似乎步幅在某些特定的 ROI 大小中变得“非标准”。例如,从这篇文章中,我发现一个只需要更改cv::Mat::AUTO_STEPimageROI.bytesPerLine()in cv::Mat tempImage(cv::Size(imageROI.width(), imageROI.height()), CV_8UC1, dataBuffer, cv::Mat::AUTO_STEP);

所以我最终改为: cv::Mat matImageROI(cv::Size(imageROI.width(), imageROI.height()), CV_8UC1, dataBuffer, imageROI.bytesPerLine());

对于另一种方式,即从 cv::Mat 的 ROI 创建 QImage,将使用属性cv::Mat::step

例如:

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

代替:

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

更新

对于奇数 ROI 大小的情况,虽然使用imshow()withcv::MatQImagein都不是问题,但使用 openGL(with )QGraphicsScene时就会出现问题。QOpenGLWidget我想最简单的解决方法就是将 ROI 限制为均匀大小。

于 2016-04-09T09:27:26.637 回答