我无法使用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 matImage
。
(中)来自QImage
和QRect
的预期结果(大致对应于手工绘制的绿色矩形)。
(右)来自cv::Mat matImageROI
答案 0 :(得分:0)
通过探索有关cv::Mat
和QImage
之间转换的其他问题,似乎在一些特定的投资回报率规模上,步幅变得“非标准”。例如,从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
QImage
或QGraphicsScene
时出现问题,但在使用时会出现问题openGL(带QOpenGLWidget
)。我想最简单的解决方法就是将ROI限制为具有均匀的大小。