問題描述
//對不起我的英語.
請告訴我,我做錯了什么?我已經(jīng)閱讀了很多關(guān)于這方面的內(nèi)容.并寫了一些代碼,但結(jié)果很糟糕.
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.
據(jù)我所知在 Opencv 中 CV_8UC3 與 QImage::Format_RGB888 相同,除了相應(yīng)的 BRG 和 RGB.
As I understand in Opencv CV_8UC3 is the same as QImage::Format_RGB888 , except BRG and RGB accordingly.
以這種格式讀取 cv::Mat 我可以這樣做:
to read cv::Mat in this format I can do:
cv::Mat mat1 = cv::imread("bugero.jpg",3);
所以,要將 cv::Mat 轉(zhuǎn)換為 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;
}
我制作了臨時墊,因為我想在 QImage 中復(fù)制數(shù)據(jù).
I made temp mat becouse I want to have copy of data in QImage.
那么.要將其轉(zhuǎn)換回我必須做的:
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);用 BGR 顏色制作 cv Mat.我不完全知道這個函數(shù)里面有什么cvtColor(res, res,CV_BGR2RGB);,但我決定如果 cvtColor(res, res,CV_BGR2RGB); 改變 R 和 B 的位置,這將改變這種顏色的位置,因為我沒有找到 CV_BGR2RGB.
I have inserted cvtColor(res, res,CV_BGR2RGB); to make cv Mat with BGR colors. I do not exactly know what in inside this function cvtColor(res, res,CV_BGR2RGB);, But I decided that if cvtColor(res, res,CV_BGR2RGB); change places R and B, that will chage places of this colors back, because I did not found CV_BGR2RGB.
所以,我寫了一個簡短的示例程序
So, I wrote short sample program
#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
我得到了一個糟糕的結(jié)果!!!
And I have got a BAD result!!!
有嗎?各位,我需要幫助!
Is there some? People,I need help!
我添加了一些調(diào)試信息來獲取 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
這是什么意思,可能有什么問題?
What does it means and may be problem in it?
推薦答案
代碼看起來不錯,但有一個例外.
內(nèi)存管理.cv::Mat
在這個材料中不像 QImage
那樣工作.請記住,QImage
使用寫時復(fù)制機制并為每個副本共享內(nèi)存.cv::Mat
也共享內(nèi)存,但它不會在寫入時進行復(fù)制(我也是 open cv 的新手(2 周),所以我無法確切解釋它是如何工作的,但我'因為那個,我偶然發(fā)現(xiàn)了一些迷戀)!
另一件事是,當(dāng)您從內(nèi)存中創(chuàng)建 QImage
時,圖像正在使用此內(nèi)存并且不擁有它的所有權(quán).
最終結(jié)果是,在 Linux 和 Qt5 上,您的代碼由于內(nèi)存管理問題而崩潰.在屏幕截圖中,您可以在第二個窗口的頂部看到發(fā)生了一些奇怪的事情,并且您會看到一些內(nèi)存垃圾.
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.
所以我更正了你的轉(zhuǎn)換函數(shù),它完美地工作:
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;
}
所以我們都必須閱讀有關(guān) open-CV 中內(nèi)存管理的內(nèi)容:)
So we both have to do a reading about memory management in open-CV :).
離題:
在 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.
這篇關(guān)于cv::Mat 到 QImage 并返回的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!