Read an image from a qrc using imread() of OpenCV(使用 OpenCV 的 imread() 从 qrc 读取图像)
问题描述
我想以这种方式使用 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 读取图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 OpenCV 的 imread() 从 qrc 读取图像
基础教程推荐
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01