【Qt】基于 Qt 显示 OpenCV 的 Mat 数据

读取图片

使用QFileDialog::getOpenFileName函数获取文件名:

1
2
3
QString filename = QFileDialog::getOpenFileName(this,tr("Open Image"),"",tr("Image File(*.bmp *.jpg *.jpeg *.png)"));
QTextCodec *code = QTextCodec::codecForName("gb18030");
std::string img_name = code->fromUnicode(filename).data();

使用cv::imread函数读取图片:

1
2
3
4
5
6
7
8
9
10
11
12
image_mat = cv::imread(img_name);

if(!image_mat.data)
{
QMessageBox msg_box;
msg_box.setText(tr("Image data is null"));
msg_box.exec();
}
else
{
//TODO: xxxx
}

cv::Mat转换为QImage

cv::Mat类对象转换为QImage类对象。注意事项:

  1. cv::Mat类通道顺序为BGR,QImgae类为RGB,因此需要先使用cv::cvtColor做色彩转换。

  2. 需要判断Mat对象的通道数,单通道和三通道处理方式略有不同:

  • 三通道RGB图片:QImage::Format_RGB888
  • 单通道图片:QImage::Format_Indexed8
1
2
3
4
5
6
7
8
9
10
cv::Mat rgbMat;
QImage img;

if (image_mat.channels() == 3)
{
cv::cvtColor(mat, rgbMat, CV_BGR2RGB);
img = QImage((const uchar*)(rgbMat.data), rgbMat.cols, rgbMat.rows, rgbMat.cols * rgbMat.channels(), QImage::Format_RGB888);
} else {
img = QImage((const uchar*)(mat.data), mat.cols, mat.rows, mat.cols * mat.channels(), QImage::Format_Indexed8);
}

QLabel显示图片

在Qt Designer中创建一个QLabel类对象img_label,并根据需求设置其长宽大小,最后通过setPixmap函数设置QImage数据。

调整图片大小时有两种设置方式:

  • 图片尺寸调整到QLabel实际尺寸:setScaledContents(true)
  • QLabel尺寸调整到图片实际尺寸:resize()
1
2
3
4
this->ui->img_label->clear();
this->ui->img_label->setPixmap(QPixmap::fromImage(img));
this->ui->img_label->setScaledContents(true);
//this->ui->img_label->resize(this->ui->img_label->pixmap()->size());

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
QString filename = QFileDialog::getOpenFileName(this,tr("Open Image"),"",tr("Image File(*.bmp *.jpg *.jpeg *.png)"));
QTextCodec *code = QTextCodec::codecForName("gb18030");
std::string img_name = code->fromUnicode(filename).data();

image_mat = cv::imread(img_name);

if(!image_mat.data)
{
QMessageBox msg_box;
msg_box.setText(tr("Image data is null"));
msg_box.exec();
}
else
{
cv::Mat rgbMat;
QImage img;

if (image_mat.channels() == 3)
{
cv::cvtColor(mat, rgbMat, CV_BGR2RGB);
img = QImage((const uchar*)(rgbMat.data), rgbMat.cols, rgbMat.rows, rgbMat.cols * rgbMat.channels(), QImage::Format_RGB888);
} else {
img = QImage((const uchar*)(mat.data), mat.cols, mat.rows, mat.cols * mat.channels(), QImage::Format_Indexed8);
}

this->ui->img_label->clear();
this->ui->img_label->setPixmap(QPixmap::fromImage(img));
this->ui->img_label->setScaledContents(true);
//this->ui->img_label->resize(this->ui->img_label->pixmap()->size());
}