这里将记录一些收集的Mat和QImage间转换的方法,但这些方法不一定是最好的。
一、将cv::Mat转换为QImage
1、共享数据内存
QImage mat_to_qimage_ref(cv::Mat &mat, QImage::Format format)
{
return QImage(mat.data, mat.cols, mat.rows, mat.step, format);
}
注意:cv::Mat中的内存可能进行扩展(4字节对齐),mat.step表示实际的航长度。如果没有这个参数,结果可能正确,也可能不正确,如下例所示。
QImage mat_to_qimage_ref(cv::Mat &mat, QImage::Format format)
{
return QImage(mat.data, mat.cols, mat.rows, format);
}
注意:在OpenCV中,图像颜色平面的顺序默认是BGR,因此,应先将其转换为RGB格式。
cv::cvtColor(src, dst, CV_BGR2RGB);
2、拷贝数据
QImage mat_to_qimage_cpy(mat.data, mat.cols, mat.rows,
QImage::Format_ARGB32)
{
QImage(mat.rows, mat.cols, QImage::Format_ARGB32);
for (int i = 0;i != image.height(); ++i) {
memcpy(image.scanline(i), mat.ptr(i), mat.step);
}
}
上例中的方法看似正确,实际上是有问题的。因为创建QImage时,并不能指定每一行应该有多少字节。下面的方法是正确的解
QImage mat_to_qimage_cpy(cv::Mat const &mat,
QImage::Format format)
{
return QImage(mat.data, mat.cols, mat.rows,
mat.step, format).copy();
}
二、将QImage转换为cv::Mat
1、共享内存
cv::Mat qimage_to_mat_ref(QImage &img, int format)
{
return cv::Mat(img.height(), img.width(),
format, img.bits(), img.bytesPerLine());
}
2、拷贝内存
cv::Mat qimage_to_mat_cpy(QImage const &img, int format)
{
return cv::Mat(img.height(), img.width(), format,
const_cast<uchar>(img.bits()),
img.bytesPerLine()).clone();
}
这里使用了const_cast,可能并不是一个好的方法。
参考文献:
[1] http://qtandopencv.blogspot.com/2013/08/how-to-convert-between-cvmat-and-qimage.html