在将QImage
转换为cv::Mat
(OpenCV的矩阵类型)时,需要考虑到图像的颜色空间与数据存储格式。QImage
默认使用RGB颜色空间,而OpenCV通常使用BGR颜色空间。因此,转换过程中不仅需要转换数据类型,还需要转换颜色空间。
下面是一个示例代码,展示如何将QImage
转换为cv::Mat
:
#include <QImage>
#include <opencv2/opencv.hpp>
cv::Mat QImageToCvMat(const QImage &inImage)
{
cv::Mat outMat;
switch (inImage.format())
{
// 8位,4通道,带有Alpha通道的图片,如PNG
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
case QImage::Format_RGB32:
{
cv::Mat tempMat(inImage.height(), inImage.width(), CV_8UC4,
const_cast<uchar*>(inImage.bits()), inImage.bytesPerLine());
cv::cvtColor(tempMat, outMat, cv::COLOR_RGBA2BGR);
break;
}
// 8位,3通道,通常的RGB图片
case QImage::Format_RGB888:
{
cv::Mat tempMat(inImage.height(), inImage.width(), CV_8UC3,
const_cast<uchar*>(inImage.bits()), inImage.bytesPerLine());
cv::cvtColor(tempMat, outMat, cv::COLOR_RGB2BGR);
break;
}
// 灰度图片
case QImage::Format_Grayscale8:
{
cv::Mat tempMat(inImage.height(), inImage.width(), CV_8UC1,
const_cast<uchar*>(inImage.bits()), inImage.bytesPerLine());
outMat = tempMat.clone();
break;
}
default:
qWarning("Unsupported QImage format!");
break;
}
return outMat;
}
说明
- 格式判断:首先判断
QImage
的格式。常见的格式有RGB888
、ARGB32
和Grayscale8
。 - 创建临时Mat:根据
QImage
的格式创建一个临时的cv::Mat
。这一步是为了处理数据格式和颜色空间转换。- 对于
RGB
或带Alpha通道的RGB
图像,使用CV_8UC3
或CV_8UC4
。 - 对于灰度图像,使用
CV_8UC1
。 const_cast<uchar*>(inImage.bits())
用于获取图像数据的指针,inImage.bytesPerLine()
获取每行的字节数。
- 对于
- 颜色空间转换:使用
cv::cvtColor
函数进行颜色空间转换,通常是从RGB
转换到BGR
,或从RGBA
转换到BGR
。 - 克隆数据:对于灰度图像,直接克隆临时Mat到输出Mat,因为不需要颜色空间转换。
使用示例
QImage qImage = QImage("path_to_image.png");
cv::Mat cvMat = QImageToCvMat(qImage);
// 接下来可以使用cvMat进行OpenCV的操作
这样,你就可以将QImage
成功转换为cv::Mat
,并在OpenCV的框架下进行后续处理。