2016-04-08 5 views
1

Я не могу правильно преобразовать и/или показать ROI с помощью QRect в QImage и создать изображение cv :: Mat из QImage. Проблема симметрична, то есть я не могу правильно получить ROI с помощью cv :: Rect в cv :: Mat и создания QImage из Mat. Удивительно, но все работает нормально, когда ширина и высота cv :: Rect или QRect равны.Как конвертировать ROI из/в QImage в/из cv :: Mat?

В дальнейшем мое полноразмерное изображение - это 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. (средний) ожидаемый результат от QImage и QRect (что примерно соответствует зеленому прямоугольнику, нарисованному вручную). (справа) перепутались вверх результат от cv::Mat matImageROI

+0

Я использую Qt 5.6 и openCV 3.1, Mac OS X 10.10.5, Macbook Pro Retina. –

ответ

0

, исследуя другие вопросы, касающиеся преобразований между cv::Mat и QImage, кажется, шаг становится «нестандартным» в некоторых конкретных размерах ROI. Например, из 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());

Для наоборот, то есть, создавая QImage из ROI cv :: Mat, можно было бы использовать свойство 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);

Update

Для случая нечетных размеров ROI, хотя это не является проблемой, когда используя либо imshow() с cv::Mat или QImage в QGraphicsScene, это становится проблемой при использовании openGL (с QOpenGLWidget). Я думаю, что простейшим обходным решением является просто ограничение ROI, чтобы иметь даже размеры.