Qt界面显示OpenCV读取的图片
前言:
1,在Qt编写的界面中显示Opencv读取的图片;
由于Qt有自己的读取文件的工具格式和图片显示格式:QImage,SetPixmap,SetPixel,setImage,…………
Qt中文件的读取是基于文件流形式或者数组形式等等,
2,OpenCV也有自己的读取图片的格式和显示图片的格式:imread(),imshow()…………
OpenCV图像文件是Mat格式;
3,如何使用Qt中的控件上能显示OpenCV读取的数据文件呢?
直接把Mat格式数据显示肯定是不能成功的,因此需要把Mat格式转换成Qt下的QImage格式;
搭建开发环境:
本例子所使用的开发环境:
1,操作系统,Win10 64bit 家庭版;16G内存;
2,OpenCV版本:3.4.6
3,Qt版本:5.12.7
4,Qt Creator版本:4.11.0
Qt Creator 作为Qt自家的IDE,对Qt本身的支持是肯定完全支持的,那么如何将OpenCV添加到开发环境中去呢?
->在项目的.pro里面的最下方添加如下代码,把编译好的OpenCV库添加进去;
#-------------------------------------------------------------------------------------
INCLUDEPATH += D:\OpenCV_Lib\OpenCV_MinGW_Build_3.4.6_Lib\include
D:\OpenCV_Lib\OpenCV_MinGW_Build_3.4.6_Lib\include\opencv
D:\OpenCV_Lib\OpenCV_MinGW_Build_3.4.6_Lib\include\opencv2
LIBS += -L D:\OpenCV_Lib\OpenCV_MinGW_Build_3.4.6_Lib\x86\mingw\lib\libopencv_*.a
#--------------------------------------------------------------------------------------
图像格式转化:
因为Qt和OpenCV分别实现了自己的图像数据结构格式(QImage, Mat),因此在使用Qt显示OpenCV打开的图像数据时,需要对图像格式进行转换:
实现步骤:
1,用OpenCV的imread()函数读取图片数据;
2,将读取出来的图像数据BGR格式或者BGRA格式转换为RGB格式,用cvtColor()函数转换;
3,将转换过的RGB格式图像数据转换成Qt中的QImage格式;
4,通过QLabel控件显示出来;
转换方法:
下面以Qt开发中的Qt界面显示作为主要的界面工具,这里主要实现cv::Mat图像数据转换到QImage;
1,首先新建一个类:命名为:QCVMatDataCorvent,并返回QImage图像数据格式:
static QImage QCVMat2QImage(const cv::Mat& mat);
2,cv::Mat作为OpenCV的基础数据格式,提供了大量的矩阵类型(cv::Mat::type),这里主要针对BGRA,BGR和灰度图进行转换;
//值得注意的是,在转化8位3通道的图像时,OpenCV和QImage使用的红蓝通道是相反的,需要使用rgbSwapped方法互换一下
//---------------------------------------------------------------------------------
QImage QCVMatDataCorvent::QCVMat2QImage(const cv::Mat& mat)
{
const unsigned char* data = mat.data;
int width = mat.cols;
int height = mat.rows;
int bytesPerLine = static_cast<int>(mat.step);
switch(mat.type())
{
//8 bit , ARGB
case CV_8UC4:
{
QImage image(data, width, height, bytesPerLine, QImage::Format_ARGB32);
return image;
}
//8 bit BGR
case CV_8UC3:
{
QImage image(data, width, height, bytesPerLine, QImage::Format_RGB888);
//swap blue and red channel
return image.rgbSwapped();
}
//8 bit Gray shale
case CV_8UC1:
{
QImage image(data, width, height, bytesPerLine, QImage::Format_Grayscale8);
return image;
}
//
default:
{
//Unsupported format
qWarning()<<"Unsupported cv::Mat type:"<<mat.type()
<<", Empty QImage will be returned!";
return QImage();
}
}
}
图片显示:
完成数据的转换后,开始对布局进行设计;
1,使用PushButton按钮,实现打开文件操作,借助Qt中的QFileDialog控件对文件进行过滤,并获取到当前选择的图片路径;
2,使用OpenCV的imread()函数读取图片数据为cv::Mat
3,使用QImage QCVMatDataCorvent::QCVMat2QImage(const cv::Mat& mat)转换Mat格式为QImage格式;
4,将QImage显示到QLabel控件上;
void MainWindow::on_OpenImgBtn_clicked()
{
QString fileName;
fileName = QFileDialog::getOpenFileName(this, "Open Image", ".", "Image Files(*.png *.jpg *.jpeg)");
if(!fileName.isEmpty())
{
showImage(fileName);
}
}
void MainWindow::showImage(QString imgPath)
{
ui->ImgLabel->setText("");
cv::Mat imgMat = cv::imread(imgPath.toStdString().c_str());
QImage img = QCVMatDataCorvent::QCVMat2QImage(imgMat);
ui->ImgLabel->setPixmap(QPixmap::fromImage(img));
resize(width()-ui->ImgLabel->width()+img.width(),
height()-ui->ImgLabel->height()+img.height());
}