LINUX.ORG.RU

Я

 cvmat, , , ,


1

1

Добрый день. Я прочитал много по этой теме, но никак не выходить сделать нормально работающее решение.
(Предположение 1)
Насколько я понимаю ОпенСиВишный CV_8UC3 и Кутешный QImage::Format_RGB888 - одно и тоже за исключением порядка бит BGR и RGB , соответственно.

Чтоб из OpenCV загрузить картинку в формате CV_8UC3 я могу сделать

cv::Mat mat1 = cv::imread("bugero.jpg",3); 

А для конвертации я делаю:

QImage Mat2QImage(cv::Mat const& src)
{
     cv::Mat temp(src.cols,src.rows,src.type());
     cvtColor(src, temp,CV_BGR2RGB);
     QImage dest= QImage((uchar*) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
     return dest;
}

Я умышленно создаю ещё одну cv:Mat, так как хочу чтоб QImage имел копию данных.

Дальше, из предположения 1, я пишу такой код для конвертации обратно в cv::Mat

cv::Mat QImage2Mat(QImage const& src)
{
     QImage temp = src.copy();
     cv::Mat res(temp.height(),temp.width(),CV_8UC3,(uchar*)temp.bits(),temp.bytesPerLine());
     cvtColor(res, res,CV_BGR2RGB); 
     return res;
}
Я использую ещё раз cvtColor(res, res,CV_BGR2RGB); Для превращения Qtешного RGB в OpenCvшный BGR. Я не нашел константы CV_RGB2BGR, но сделал вывод, что если CV_BGR2RGB поменяет местами B и R, то она сделает тоже самое и наоборот.
Дальше я написал небольшую программу для теста
#include <QApplication>
#include <QtGui>
#include <cv.h>
#include "opencv2/highgui/highgui.hpp"

QImage Mat2QImage(cv::Mat const& src)
{
     cv::Mat temp(src.cols,src.rows,src.type()); // make the same cv::Mat
     cvtColor(src, temp,CV_BGR2RGB); // cvtColor Makes a copt, that what i need
     QImage dest= QImage((uchar*) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
     return dest;
}

cv::Mat QImage2Mat(QImage const& src)
{
     QImage temp = src.copy(); 
     cv::Mat res(temp.height(),temp.width(),CV_8UC3,(uchar*)temp.bits(),temp.bytesPerLine());
     cvtColor(res, res,CV_BGR2RGB); // make convert colort to BGR ! 
     return res; 
}


int main(int argc, char *argv[])
{
     QApplication a(argc, argv);
     QWidget W1;
     QWidget W2;
     QLabel imlab1(&W1);
     QLabel imlab2(&W2);
     W1.setWindowTitle("Convert cv::Mat to QImage First time"); 
     W2.setWindowTitle("Convert cv::Mat to QImage Second time");    




     cv::Mat mat1 = cv::imread("bugero.jpg",3);//read image 
     QImage qim1  = Mat2QImage(mat1);// create first convertation
     cv::Mat mat2 = QImage2Mat(qim1);//convertation back to cv::Mat
     QImage qim2 = Mat2QImage(mat2); // create second convertaation
     cv::Mat mat3 = QImage2Mat(qim2); // second convertation back to cv::Mat



     cv::imshow("First Mat",mat1);
     imlab1.setPixmap(QPixmap::fromImage(qim1)); 
     W1.setFixedSize(qim1.size()); 
     cv::imshow("Convert QImage to cv::Mat firstly",mat2);
     imlab2.setPixmap(QPixmap::fromImage(qim2));
     W2.setFixedSize(qim2.size()); 
     cv::imshow("Convert QImage to cv::Mat secondly",mat2);
     W1.show();
     W2.show();

     return a.exec();
}
Вот ещё мой файл проекта
INCLUDEPATH += /usr/local/include/opencv /usr/local/include/opencv2
LIBS += -lopencv_core -lopencv_imgproc\
                                       -lopencv_highgui
QT       += gui
QT       += core
SOURCES += \
    QcvMat.cpp \

Рузультат плачевный :-(



Последнее исправление: vsrmis (всего исправлений: 1)

хе, где-то там альфа-канал

visual ★★★
()
Ответ на: комментарий от rimsleur

sin_aУпс, а как теперь изменить Заголовок? Он не позволяет редактировать.

Изменил код, чтоб тот выводил step из opencv, и bytesPerLine из QImage

alex@lenovo /media/Files/Programming/Cpp/tests/QImagecvMat $ ./QcvMat 
cv step  942 
QImage  bytesPerLine  944 
cv step  942 
QImage  bytesPerLine  944 

Итого: Они разнятся. Но что это означает и как с этим бороться?

хе, где-то там альфа-канал

rimsleur Может быть, но как это определить и как изменить?

vsrmis
() автор топика
Ответ на: комментарий от vsrmis

Итого: Они разнятся. Но что это означает и как с этим бороться?

Какое разрешение по горизонталии у исходной картинки, 314? Без остатка только 942 делиться на 3, значит оно корректное, его и надо передавать.

rimsleur
()

для того, чтобы убрать полосы вверху изображения попробуй сделать смещение для temp.data

как-то так:

 QImage dest = QImage((uchar*) &temp.data[3000], temp.cols, temp.rows, temp.step, QImage::Format_RGB888)

rimsleur
()
Ответ на: комментарий от rimsleur

Да, разрешение картинки 314*640. 314 * 3 это действительно 942, значит в одной строке должно быть 942 байта. Но какого чёрта в QImage 944? От куда ещё эти лишние 2 байта? Как вы посоветовали я сделал смещение только не на 3000 на на temp.step*7

Image dest= QImage((uchar*) &temp.data[temp.step*7], temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
Итого, полоса вверху действительно уменьшилась, но зато появилась полоса внизу. Что это значит? Мне кажется, что именно эти 2 байта портят картину. Если помножить 2 байта в каждой строке на высоту картинки 600, то выйдет 1200 лишних байт.Но как их учесть? http://images.gameru.net/image/direct/9f65d842f4.png

vsrmis
() автор топика
Ответ на: Решено! от vsrmis

Огромное всем спасибо! Подсказали ответ на stackoverflow

Тонко.

anonymous
()
Ответ на: комментарий от vsrmis

А разве вы не видели полную фотографию всем известной «Лены»?

Неа, это какая-то порно-актриса?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.