cv :: Mat到QImage并返回 [英] cv::Mat to QImage and back

查看:1199
本文介绍了cv :: Mat到QImage并返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

//对不起我的英语。

告诉我,我做错了什么?
我读了很多关于这个。并写了一些代码,但我有一个可怕的结果。

Tell me please, what I am doing wrong? I have read a lot about this. And write some code, but I have a terrible result.

我理解
在Opencv CV_8UC3 >

以这种格式读取cv :: Mat:

to read cv::Mat in this format I can do:

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

因此,要将cv :: Mat转换为QImage,我可以这样做:

So, to convert cv::Mat to QImage I can do:

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;
}

我做了temp mat,因为我想在QImage中有数据的副本。

I made temp mat becouse I want to have copy of data in QImage.

然后。
要转换它我必须做:

Then. To convert it back I Have to do:

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)强>使cv Mat与BGR颜色。我不知道这个函数里面有什么 cvtColor(res,res,CV_BGR2RGB);但是我决定
如果 cvtColor(res,res,CV_BGR2RGB) strong>更改地点R和B,这会将这些颜色的地方拖回,因为我没有找到 CV_BGR2RGB

短示例程序

#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);

     QImage qim1  = Mat2QImage(mat1);

     cv::Mat mat2 = QImage2Mat(qim1);

     QImage qim2 = Mat2QImage(mat2); 

     cv::Mat mat3 = QImage2Mat(qim2);



     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();
}

和.pro档案

INCLUDEPATH += /usr/local/include/opencv /usr/local/include/opencv2
LIBS += -lopencv_core -lopencv_imgproc\
                                       -lopencv_highgui
QT       += gui
QT       += core
SOURCES += \
    QcvMat.cpp \

我有一个BAD结果!

And I have got a BAD result!!!

有一些?人们,我需要帮助!

Is there some? People,I need help!

我添加了一些调试信息来获取cv :: Mat.step和QImage.bytesPerLine(),它是不同的。

I added some debug info to get cv::Mat.step and QImage.bytesPerLine() and it is different.

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

可能会出现问题?

推荐答案

代码看起来不错,只有一个例外。

内存管理。 cv :: Mat 在此主体中不起作用 QImage 。记住, QImage 正在使用写时复制机制,并为每个副本共享内存。
cv :: Mat 也共享内存,但它不做写的复制(我也是新开放cv(2周),所以我可以'另外一件事是,当你创建 QImage 时,会出现这样的情况:内存映像正在使用此内存,并且不会占用它的所有权。

最后的结果是,在Linux和Qt5上,您的代码崩溃,因为内存管理的问题。在你的屏幕截图上,你可以看到在第二个窗口的顶部,奇怪的事情发生,你看到一些记忆垃圾。

Code looks fine with one exception.
Memory management. cv::Mat doesn't work like QImage in this mater. Remember that QImage is using copy on write mechanism and shares memory for each copy. cv::Mat also shares memory but it doesn't do copy on write (I'm also new with open cv (2 weeks) so I can't explain yet exactly how it works but I've stumbled on some crushes because of that)!
Another thing is that when you are creating QImage from memory image is using this memory and doesn't take ownership of it.
Final outcome is that on Linux and Qt5 your code is crashes because of problems with memory management. On your screen shot you can see at the top of second window that something strange is going on and you see some memory trash.

所以我已经更正了你的转换功能作品完美:

So I've corrected your conversion functions it works perfectly:

QImage Mat2QImage(cv::Mat const& src)
{
     cv::Mat temp; // make the same cv::Mat
     cvtColor(src, temp,CV_BGR2RGB); // cvtColor Makes a copt, that what i need
     QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
     dest.bits(); // enforce deep copy, see documentation 
     // of QImage::QImage ( const uchar * data, int width, int height, Format format )
     return dest;
}

cv::Mat QImage2Mat(QImage const& src)
{
     cv::Mat tmp(src.height(),src.width(),CV_8UC3,(uchar*)src.bits(),src.bytesPerLine());
     cv::Mat result; // deep copy just in case (my lack of knowledge with open cv)
     cvtColor(tmp, result,CV_BGR2RGB);
     return result;
}

所以我们都要在open-CV中做一个关于内存管理的阅读: )。

So we both have to do a reading about memory management in open-CV :).

OFFTOPIC:

在Linux上的qt项目中包含openCV的最佳方式是添加到pro文件如:

OFFTOPIC:
Best way to include openCV in qt projects on Linux is to add to pro file something like:

# add open CV
unix {
    CONFIG += link_pkgconfig
    PKGCONFIG += opencv
}

将代码移动到另一台机器时,不会出现路径问题。

You will be free of path problems when moving code to another machine.

这篇关于cv :: Mat到QImage并返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆