欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt:OpenCV::Mat与Qt::QImage相互转换

程序员文章站 2024-03-17 18:54:16
...

前言

  Qt和OpenCV是一对形影不离的好基友(哥俩都开源,Qt又跨平台,Linux环境友好),但OpenCV的最常用的类Mat无法直接用于Qt的QImage中,原因在于,两者对图片定义和操作有所不同——Mat的主要功能是矩阵运算,拥有数之不尽的数据类型,包罗万象;而QImage侧重于图片显示,更多的操作是在图形界面上
  因此,Mat与QImage之间的相互传值,要多一步转换操作。

Mat转QImage

QImage mat2qim(Mat & mat)
{
	cvtColor(mat, mat, COLOR_BGR2RGB);
	QImage qim((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, 
		QImage::Format_RGB888);
	return qim;
}

  利用QImage提供的构造函数,可以直接转化,但是要注意,Mat默认的是BGR空间,而QImage是RGB,所以使用cvtColor函数预处理一下。如果Mat是其他颜色空间的图像,对应的,QImage也要随之而变,但简单来讲,如果没有计算需求,可以使用cvtColor函数统一转换成RGB空间。

QImage转Mat

Mat qim2mat(QImage & qim)
{
	Mat mat = Mat(qim.height(), qim.width(), 
		CV_8UC3,(void*)qim.constBits(),qim.bytesPerLine());
	return mat;
}

  同理,利用Mat的构造函数实现QImage往Mat的转换,但是要注意,QImage的通道数和数据类型,一般而言默认的是三通道八位无符号数,即CV_8UC3,如果读取的图片是浮点型灰度图,那就是CV_32FC1,如果是未知类型,可以通过QImage提供的format函数进行判断,例如:

Mat qim2mat(QImage & qim)
{
	Mat mat;
	switch(qim.format()){
		case QImage::Format_RGB888: 
			mat = Mat(qim.height(), qim.width(), 
				CV_8UC3,(void*)qim.constBits(),qim.bytesPerLine());
			break;
		case QImage::Format_ARGB32_Premultiplied:
			mat = Mat(qim.height(), qim.width(), 
				CV_8UC4,(void*)qim.constBits(),qim.bytesPerLine());
			break;
	}
	return mat;
}

  可以根据程序需求写对应的case,QImage的类型可以参考官方API:QImage::Format