我在互联网上搜索了一下,但是找不到将QImage
(或QPixmap
)转换为OpenCV Mat
的方法。我该如何实现?
非常感谢任何帮助。
cv::MatMat mat(img.height(), img.width(), CV_8UC4, (cv::Scalar*)img.scanLine(0));
适用于RGBA8888。 - Kaaf在您发布这个问题的一年后,互联网上已经有了很好的答案:
但我认为,如果您同时使用Qt和OpenCV,则类型 QImage
可能只是用于显示,因此您可能希望使用 QPixmap
,因为它针对显示进行了优化。所以这就是我做的事情:
cv :: Mat
,如果要显示图像,请使用第二篇文章中介绍的非复制方法转换为 QPixmap
。 cv :: Mat
中进行图像处理。 Mat2QPixmap()
的函数来获取实时结果。 QPixmap
转换为 cv :: Mat
,考虑到每种类型的目的,这样做没有意义。 cv::Mat mat(image.height(), image.width(),CV_8UC3, image.bits());
// image.scanline() does not exist,
//and height/width is interchanged for a matrix
再次强调,假设QImage是RGB888格式(即QImage::Format_RGB888)
我尝试使用OpenCV 3.1+风格的代码:
void qimage_to_mat(const QImage& image, cv::OutputArray out) {
switch(image.format()) {
case QImage::Format_Invalid:
{
cv::Mat empty;
empty.copyTo(out);
break;
}
case QImage::Format_RGB32:
{
cv::Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine());
view.copyTo(out);
break;
}
case QImage::Format_RGB888:
{
cv::Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine());
cvtColor(view, out, cv::COLOR_RGB2BGR);
break;
}
default:
{
QImage conv = image.convertToFormat(QImage::Format_ARGB32);
cv::Mat view(conv.height(),conv.width(),CV_8UC4,(void *)conv.constBits(),conv.bytesPerLine());
view.copyTo(out);
break;
}
}
}
void mat_to_qimage(cv::InputArray image, QImage& out)
{
switch(image.type())
{
case CV_8UC4:
{
cv::Mat view(image.getMat());
QImage view2(view.data, view.cols, view.rows, view.step[0], QImage::Format_ARGB32);
out = view2.copy();
break;
}
case CV_8UC3:
{
cv::Mat mat;
cvtColor(image, mat, cv::COLOR_BGR2BGRA); //COLOR_BGR2RGB doesn't behave so use RGBA
QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32);
out = view.copy();
break;
}
case CV_8UC1:
{
cv::Mat mat;
cvtColor(image, mat, cv::COLOR_GRAY2BGRA);
QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32);
out = view.copy();
break;
}
default:
{
throw invalid_argument("Image format not supported");
break;
}
}
}
cv::Mat to_cvmat(QImage img)
{
img = img.convertToFormat(QImage::Format_RGB888, Qt::ColorOnly).rgbSwapped();
return cv::Mat(img.height(), img.width(), CV_8UC3, img.bits(), img.bytesPerLine()).clone();
}