最近在学习使用qt和opencv在界面上显示输入的图片,发现直接Mat mat无法在ui界面上显示,成功实现的解决办法如下。
思路是:借助QLabel->setPixmap来绘制图片,首先需要将Mat类型转化为QImage类型,然后再将QImage类型转化为QPixmap类型,才可以在QLabel上画图。
下面函数可以将Mat类型转化为QImage
//图片转化
QImage MatToImage(Mat &mat)
{
//输入图像为三通道
if (mat.type() == CV_8UC3)
{
//复制输入的mat数据
const uchar* pSrc = (const uchar*)mat.data;
//创建与输入Mat尺寸相同的QImage
QImage image(pSrc, mat.cols, mat.rows,(mat.cols)*3, QImage::Format_RGB888);
//将RGB转换为BGR
return image.rgbSwapped();
}
//输入图像为单通道
else if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
//设置颜色表(用于将颜色索引转换为qRgb值)
image.setColorCount(256);//灰度级数256
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
//复制输入
uchar *pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar *pDest = image.scanLine(row);//对图像的一行进行扫描,获取本行中个像素的内存地址
//复制src的内存的前num个字节内容给dest
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
//输入图像为四通道
else if (mat.type() == CV_8UC4)
{
qDebug() << "CV_8UC4";
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
qDebug() << "ERROR:Mat could not be converted to QImage";
return QImage();
}
}
只有单通道、三通道和四通道可以转化为QImage类型,其他类型的图片无法进行转换。返回值类型是QImage。
下面将QImage转换为QPixmap,借助QLabel显示
QPixmap pix;
pix = QPixmap::fromImage(pix.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->label->setPixmap(pix);