//申し訳ありませんが、英語です
教えてください、私が間違っていることは何ですか?私はこれについてたくさん読んだ。そして、いくつかのコードを書きますが、私はひどい結果を持っています。
Opencvで理解しているように、CV_8UCはQImage :: Format_RGB888と同じですが、BRGとRGBが異なる点が異なります。
cv :: Matをこの形式で読み取るには、次のようにします。
cv::Mat mat1 = cv::imread("bugero.jpg",3);
したがって、cv :: MatをQImageに変換するには、次のようにします。
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にデータをコピーしたいので一時マットを作成しました。
その後。それを元に戻すには、私はしなければなりません:
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マットを作る。私はこの関数の中で何が正確にわからないcvtColor(res、res、CV_BGR2RGB) ;、しかしcvtColor(res、res、CV_BGR2RGB);の場合は場所を変える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 \
そして、私は悪い結果を持っています!!!
いくつかありますか?人よ、助けが必要です!
Cv :: Mat.stepとQImage.bytesPerLine()を取得するためにいくつかのデバッグ情報を追加しましたが、それは異なります。
alex@lenovo /media/Files/Programming/Cpp/tests/QImagecvMat $ ./QcvMat
cv step 942
QImage bytesPerLine 944
cv step 942
QImage bytesPerLine 944
それは何を意味し、問題があるのでしょうか?
1つの例外を除いて、コードは問題なく見えます。
メモリ管理。 cv::Mat
は、この資料ではQImage
のように機能しません。 QImage
はコピーオンライトメカニズムを使用しており、コピーごとにメモリを共有することに注意してください。 cv::Mat
メモリも共有しますが、コピーオンライトは行いません(私もopen cv(2週間)の新機能です。そのため、正確にどのように機能するかはまだ説明できませんが、それが原因でクラッシュが発生しました)。 !
もう1つは、メモリイメージからQImage
を作成するときに、このメモリを使用していて、その所有権を取得しないことです。
最終的な結果として、LinuxおよびQt5では、メモリ管理の問題が原因でコードがクラッシュします。スクリーンショットでは、2番目のウィンドウの上部に何か奇妙なことが起こっていることがわかり、メモリのごみが残っています。
だから私はそれが完全に機能するあなたの変換関数を修正しました:
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でのメモリ管理についての読み取りを行う必要があります:)。
オフトピック:
LinuxのqtプロジェクトにopenCVを含める最良の方法は、次のようなproファイルに追加することです。
# add open CV
unix {
CONFIG += link_pkgconfig
PKGCONFIG += opencv
}
コードを別のマシンに移動するときに、パスの問題がなくなります。
どうもありがとう!本当に作品です!だが。なぜ記憶が損なわれるのですか?最初。私はいくつかのメモリ負荷incv :: Matを持っています
cv::Mat mat1 = cv::imread("bugero.jpg",3);
mat1 - [=====================================]
次に、このcvMatのコピーを他のcv:Matに置きます
cv::Mat temp(src.cols,src.rows,src.type());
cvtColor(src, temp,CV_BGR2RGB);
mat1 - [=========================================]
temp - [=========================================]
次に、このデータからQImageを作成しますQImage dest = QImage((uchar *)temp.data、temp.cols、temp.rows、temp.step、QImage :: Format_RGB888);
mat1 - [============================================]
temp - > [============================================]
/
dest --/
そして、一時は範囲外になり、それを自分で削除しますか? QImageはそれの所有権を取得しないため、temp1とdestのメモリはfreeとマークされ、コンパイラは他のデータを置くことができますか?私は正しいですか?