問題描述
我想以這種方式使用 OpenCV 的 imread()
從 qrc 讀取圖像:
I want to read an image from a qrc using imread()
of OpenCV in this way:
Mat img = imread(":/TempIcons/logo.png");
但最終的
but the final img
size is [0x0]. I have also tried:
Mat img = imread("qrc://TempIcons/logo.png");
但我得到的大小是一樣的.我不想在 QImage
中加載圖像,然后在 cv::Mat
中轉換它.有沒有辦法以簡單的方式做到這一點?如果是,我該怎么做?.
but the size I get is the same. I don't want to load the image in a QImage
to then transform it in a cv::Mat
. Is there a way to do this in a easy way?. If it is, how can I do it?.
謝謝
推薦答案
正如@TheDarkKnight 所指出的,imread
不知道 Qt 資源.但是,您可以編寫自己的 loader,它使用 QFile
從資源中檢索二進制數據,并使用 imdecode
(由 imdecode
在內部完成)code>imread) 讀取圖像:
As @TheDarkKnight pointed out, imread
is not aware of Qt resources. You can however write your own loader, that uses QFile
to retrieve the binary data from the resource, and uses imdecode
(as done internally by imread
) to read the image:
Mat loadFromQrc(QString qrc, int flag = IMREAD_COLOR)
{
//double tic = double(getTickCount());
QFile file(qrc);
Mat m;
if(file.open(QIODevice::ReadOnly))
{
qint64 sz = file.size();
std::vector<uchar> buf(sz);
file.read((char*)buf.data(), sz);
m = imdecode(buf, flag);
}
//double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
//qDebug() << "OpenCV loading time: " << toc;
return m;
}
你可以這樣稱呼它:
Mat m = loadFromQrc("qrc_path");
或指定一個標志:
Mat m = loadFromQrc("qrc_path", IMREAD_GRAYSCALE);
<小時>
性能
我嘗試使用 loadFromQrc
加載圖像,并使用 QImage 并轉換為 Mat
asmaloney.com/2013/11/code/converting-between-cvmat-and-qimage-or-qpixmap/" rel="noreferrer">this 代碼,包括克隆和不克隆.loadFromQrc
結果比加載 QImage
并將其轉換為 Mat
快 10 倍.
I tried loading the image with loadFromQrc
, and loading the QImage
and converting to Mat
using this code, both with and without cloning. loadFromQrc
results to be 10 time faster then loading a QImage
and convert it to Mat
.
結果以毫秒為單位:
Load Mat : 4.85965
QImage to Mat (no clone): 49.3999
QImage to Mat (clone) : 49.8497
測試代碼:
#include <vector>
#include <iostream>
#include <QDebug>
#include <QtWidgets>
#include <opencv2/opencv.hpp>
using namespace cv;
Mat loadFromQrc(QString qrc, int flag = IMREAD_COLOR)
{
QFile file(qrc);
Mat m;
if(file.open(QIODevice::ReadOnly))
{
qint64 sz = file.size();
std::vector<uchar> buf(sz);
file.read((char*)buf.data(), sz);
m = imdecode(buf, flag);
}
return m;
}
cv::Mat QImageToCvMat( const QImage &inImage, bool inCloneImageData = true )
{
switch ( inImage.format() )
{
// 8-bit, 4 channel
case QImage::Format_RGB32:
{
cv::Mat mat( inImage.height(), inImage.width(), CV_8UC4, const_cast<uchar*>(inImage.bits()), inImage.bytesPerLine() );
return (inCloneImageData ? mat.clone() : mat);
}
// 8-bit, 3 channel
case QImage::Format_RGB888:
{
if ( !inCloneImageData )
qWarning() << "ASM::QImageToCvMat() - Conversion requires cloning since we use a temporary QImage";
QImage swapped = inImage.rgbSwapped();
return cv::Mat( swapped.height(), swapped.width(), CV_8UC3, const_cast<uchar*>(swapped.bits()), swapped.bytesPerLine() ).clone();
}
// 8-bit, 1 channel
case QImage::Format_Indexed8:
{
cv::Mat mat( inImage.height(), inImage.width(), CV_8UC1, const_cast<uchar*>(inImage.bits()), inImage.bytesPerLine() );
return (inCloneImageData ? mat.clone() : mat);
}
default:
qWarning() << "ASM::QImageToCvMat() - QImage format not handled in switch:" << inImage.format();
break;
}
return cv::Mat();
}
int main(int argc, char *argv[])
{
QString url = "...";
{
double tic = double(getTickCount());
Mat m1 = loadFromQrc(url);
double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
qDebug() << "Load Mat: " << toc;
if(m1.data != NULL)
{
imshow("m1", m1);
waitKey(1);
}
}
// {
// double tic = double(getTickCount());
// QImage img;
// img.load(url);
// Mat m2 = QImageToCvMat(img, false);
// double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
// qDebug() << "QImage to Mat (no clone): " << toc;
// if(m2.data != NULL)
// {
// imshow("m2", m2);
// waitKey(1);
// }
// }
// {
// double tic = double(getTickCount());
// QImage img;
// img.load(url);
// Mat m3 = QImageToCvMat(img, true);
// double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
// qDebug() << "QImage to Mat (clone): " << toc;
// if(m3.data != NULL)
// {
// imshow("m3", m3);
// waitKey(1);
// }
// }
waitKey();
return 0;
}
這篇關于使用 OpenCV 的 imread() 從 qrc 讀取圖像的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!