Но у некоторых людей возникают проблемы конвертировать изображения cv::Mat в QImage.
Итак, это очень просто вот функция:
/* Параметры: image - изображение которое хотим превратить в QImage
qim - уже загруженный в память буфер под данные. Может быть равен нулю.
Возвращает новое преобразованное в QImage с копированием данных
*/
QImage* createQImage(cv::Mat image,QImage* qim)
{
if(!image.data)
return 0;
cv::Mat color;
//Если один канал у изображения
if(1==image.channels())
{
//Делаем трехканальное изображение. К сожалению разработчики Qt не учли возможность
//рисования серых изображений
color.create(cv::Size(image.cols,image.rows),CV_8UC3);
std::vector ls;
ls.push_back(image);
ls.push_back(image);
ls.push_back(image);
cv::merge(ls,color);
}else{
color = image;
}
QImage* pImage=0;
if(0==qim)
{
pImage = new QImage(color.cols,color.rows,QImage::Format_RGB888);
}else{
if((qim->width()==color.cols)&&(qim->height()==color.rows))
{
pImage = qim;
}else{
delete qim;
pImage = new QImage(color.cols,color.rows,QImage::Format_RGB888);
}
}
//
IplImage im = (IplImage)color;
//По неизвестным причинам pImage->bytesPerLine() и im.widthStep могут не совпадать
if(pImage->bytesPerLine()!=im.widthStep)
{
//Копирование по строкам
for(int i=0;iheight();i++)
{
memcpy(pImage->bits()+i*pImage->bytesPerLine(),color.data+im.widthStep*i,im.widthStep);
}
}else{
//Копирование всего изображения
memcpy(pImage->bits(),color.data,im.imageSize);
}
return pImage;
}
Вот и все. Надею кому-то будет полезно!
А вот как-то так (в контексте чтения Depth-изображения с Kinect'а) не проще?
ОтветитьУдалитьMat matRGB(Size(640, 480), CV_8UC3);
Mat matDepth(Size(640, 480), CV_8UC3);
Mat matDepth_raw(Size(640, 480), CV_16UC1);
Mat matDepth_tmp(Size(640, 480), CV_8UC1);
freenect_sync_get_video((void **)&dataRGB, &timeStampRGB, 0, FREENECT_VIDEO_RGB);
freenect_sync_get_depth((void **)&dataDepth, &timeStampDepth, 0, FREENECT_DEPTH_10BIT);
matRGB.data = (uchar *)dataRGB;
matDepth_raw.data = (uchar *)dataDepth;
matDepth_raw.convertTo(matDepth_tmp, CV_8UC1, 255.0 / 2048.0);
cvtColor(matDepth_tmp, matDepth, CV_GRAY2RGB);
QImage imageRGB = QImage((uchar *)matRGB.data, matRGB.cols /*640*/, matRGB.rows /*480*/, matRGB.step /**/, QImage::Format_RGB888);
QImage imageDepth = QImage((uchar *)matDepth.data, matDepth.cols /*640*/, matDepth.rows /*480*/, matDepth.step /**/, QImage::Format_RGB888);
При автоматическом удалении cv::Mat будет освобождена память. Соответственно QImage будут хранить в себе указатель на очищенную память, что в итоге приведет к ошибке доступа к памяти (Memory Access Violation)
ОтветитьУдалитьПри автоматическом удалении cv::Mat будет освобождена память. Соответственно QImage будут хранить в себе указатель на очищенную память, что в итоге приведет к ошибке доступа к памяти (Memory Access Violation)
ОтветитьУдалить