如何将ROI从/到QImage转换为cv :: Mat?

时间:2016-04-08 17:56:24

标签: opencv3.0 qimage roi opencv-mat

我无法使用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);  

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

full size and ROI (左)全尺寸cv::Mat matImage。 (中)来自QImageQRect的预期结果(大致对应于手工绘制的绿色矩形)。 (右)来自cv::Mat matImageROI

的混乱结果

1 个答案:

答案 0 :(得分:0)

通过探索有关cv::MatQImage之间转换的其他问题,似乎在一些特定的投资回报率规模上,步幅变得“非标准”。例如,从this post开始,我发现只需要将cv::Mat::AUTO_STEP更改为imageROI.bytesPerLine() 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()中使用cv::Mat QImageQGraphicsScene时出现问题,但在使用时会出现问题openGL(带QOpenGLWidget)。我想最简单的解决方法就是将ROI限制为具有均匀的大小。