一、开发环境
1、Ubuntu16.04;
2、Qt 5.5.1;
3、OpenCV 3.3.1
二、前期准备
1、下载QT Creator
sudo apt-get install cmake qt5-default qtcreator
2、安装opencv
这个就自行百度,我就跳过。
二、QT显示图片和视频
1、配置qt环境
(1)打开QT Creator 选择如下两项:
(2)编辑pro文件,加入opencv库
#-------------------------------------------------
#
# Project created by QtCreator 2019-05-15T15:48:17
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QT_WIND
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
#system
INCLUDEPATH += /usr/local/include \
/usr/include \
/usr/lib/x86_64-linux-gnu
LIBS += -L/usr/local/lib
LIBS += -L/usr/lib
#opencv3.3
INCLUDEPATH += /usr/include \
/usr/include/opencv \
/usr/include/opencv2/
LIBS += -L /usr/lib/ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs
LIBS += -L /usr/lib/libopencv_*.so
2、设置GUI界面
(1)进入mainwindow.ui
(2) 这里设置两个按键两个label,第一个按键camera控制视频输出,第二个按键image控制图片显示。
具体操作:
step1:在布局上(下图左)放置2个label和2个button,并拖动到你喜欢的位置,并可改成自己喜欢的名字!定义好外观之后关键的是要对各个控件修改好相应的对象名(右上),这个关系到控件和代码的紧密衔接。
step2:需要给每个按键(button)设置一个行为,即槽函数,比如对pushButton_open按键,可以直接右击该按键,然后选择转到槽,选择clicked()信号,开发环境会直接在代码里生成一个槽函数 on_pushButton_open_clicked(),目前是空白的,我们稍后根据需要再写实现代码。
(3) 编写槽函数代码
这是控制摄像头输出视频的代码(目前只是打开功能)
void MainWindow::on_pushButton_clicked()
{
//QString filename("/home/bw/qt_project/QT_QWINDOW/QT_WIND/cat.jpeg");
//QImage* img=new QImage;
//img->load(filename); //加载图像
//img->scaled(img->width(),img->height(),Qt::KeepAspectRatio); //根据图片的大小缩放到合适的大小显示
//ui->label->setGeometry(0,0,400,300);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label->resize(img->width(),img->height());
//ui->label->setPixmap(QPixmap::fromImage(*img));
if (capture.isOpened())
capture.release(); //decide if capture is already opened; if so,close it
capture.open(0); //open the default camera
if (capture.isOpened())
{
rate= capture.get(CV_CAP_PROP_FPS);
capture >> frame;
if (!frame.empty())
{
cvtColor( frame, frame, CV_BGR2RGB );
img_frame = QImage( (const unsigned char*)(frame.data), frame.cols, frame.rows, QImage::Format_RGB888 );
ui->label->setGeometry(0,0,320,240);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label->resize(img_frame.width(),img_frame.height());//根据图片的大小缩放到合适的大小显示
ui->label->setPixmap(QPixmap::fromImage(img_frame));
timer = new QTimer(this);
timer->setInterval(1000/rate); //set timer match with FPS
connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
timer->start();
}
}
}
这是显示一张图片的代码
void MainWindow::on_pushButton_2_clicked()
{
src = imread("/home/bw/qt_project/QT_QWINDOW/QT_WIND/cat.jpeg");
cvtColor( src, src, CV_BGR2RGB );
img_mat = QImage( (const unsigned char*)(src.data), src.cols, src.rows, QImage::Format_RGB888 );
ui->label_2->setGeometry(0,320,320,240);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label_2->resize(img_mat.width(),img_mat.height());//根据图片的大小缩放到合适的大小显示
ui->label_2->setPixmap(QPixmap::fromImage(img_mat));
}
《注意》:OpenCV3.0以后,图像采用Mat格式进行存储,Qt中图像存储采用的是QImage类,因此,如果需要再Qt中显示OpenCV处理过程中的图像,需要将Mat类对象表示的图像转换为QImage类对象表示的图像。同时,由Mat格式采用BGR的存储顺序,而QImage格式采用的是RGB存储顺序,因此,转换过程分为两步:
1)存储格式转换:BGR --> RGB;
2)类型转换:Mat类 ---> QImage;
完成QImage类对象转换后,在Qt界面中显示QImage类对象,可以采用QLabel或者QGraphicsView,两种方法分别如下面的示例所示。
(4) 总的代码
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
///auto get next frame
void MainWindow::nextFrame()
{
capture >> frame;
if (!frame.empty())
{
cvtColor( frame, frame, CV_BGR2RGB );
img_frame = QImage( (const unsigned char*)(frame.data), frame.cols, frame.rows, QImage::Format_RGB888 );
ui->label->setGeometry(0,0,320,240);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label->resize(img_frame.width(),img_frame.height());//根据图片的大小缩放到合适的大小显示
ui->label->setPixmap(QPixmap::fromImage(img_frame));
}
}
void MainWindow::on_pushButton_clicked()
{
//QString filename("/home/bw/qt_project/QT_QWINDOW/QT_WIND/cat.jpeg");
//QImage* img=new QImage;
//img->load(filename); //加载图像
//img->scaled(img->width(),img->height(),Qt::KeepAspectRatio); //根据图片的大小缩放到合适的大小显示
//ui->label->setGeometry(0,0,400,300);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label->resize(img->width(),img->height());
//ui->label->setPixmap(QPixmap::fromImage(*img));
if (capture.isOpened())
capture.release(); //decide if capture is already opened; if so,close it
capture.open(0); //open the default camera
if (capture.isOpened())
{
rate= capture.get(CV_CAP_PROP_FPS);
capture >> frame;
if (!frame.empty())
{
cvtColor( frame, frame, CV_BGR2RGB );
img_frame = QImage( (const unsigned char*)(frame.data), frame.cols, frame.rows, QImage::Format_RGB888 );
ui->label->setGeometry(0,0,320,240);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label->resize(img_frame.width(),img_frame.height());//根据图片的大小缩放到合适的大小显示
ui->label->setPixmap(QPixmap::fromImage(img_frame));
timer = new QTimer(this);
timer->setInterval(1000/rate); //set timer match with FPS
connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
timer->start();
}
}
}
void MainWindow::on_pushButton_2_clicked()
{
src = imread("/home/bw/qt_project/QT_QWINDOW/QT_WIND/cat.jpeg");
cvtColor( src, src, CV_BGR2RGB );
img_mat = QImage( (const unsigned char*)(src.data), src.cols, src.rows, QImage::Format_RGB888 );
ui->label_2->setGeometry(0,320,320,240);//前两个参数表示label左上角位置后面分别是宽和高
//ui->label_2->resize(img_mat.width(),img_mat.height());//根据图片的大小缩放到合适的大小显示
ui->label_2->setPixmap(QPixmap::fromImage(img_mat));
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.hpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWidgets/QMainWindow>
#include <QTimer>
#include "opencv2/opencv.hpp"//添加Opencv相关头文件
using namespace cv;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void nextFrame();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
Mat src,frame;
VideoCapture capture;
double rate; //FPS
QTimer *timer;
QImage img,img_mat,img_frame; //将用到的定义全部声明,应该没有必要,我习惯
QString img_name;
};
#endif // MAINWINDOW_H
3、测试