文章目录
- 1、配置OpenCV4.5.1
- 1.1 下载OpenCV4.5.1
- 1.2 安装OpenCV4.5.1
- 1.3 CMAKE编译OpenCV
- 1.4 下载OpenCV4.5.1
- 2、测试QT程序
- 2.1 创建项目
- 2.2 效果
1、配置OpenCV4.5.1
1.1 下载OpenCV4.5.1
第一步去官网下载OpenCV-4.5.1,由于之前官网下载不了,因此我这边给出一个百度网盘链接,提取码5205。
1.2 安装OpenCV4.5.1
下载好了之后会得到这样一个图标,双击运行即可:
安装的目录我是选择当前的这个文件夹,看到网上说最好和qt是一个盘符的,也正好我的qt是安装在d盘的。
安装好之后会得到一个文件夹,里面包含构建好的build和source,其中build指的是微软平台编辑器可以直接运行的环境,source则是需要我们利用cmake去转换的文件,因为qt使用的是MinGW编译器(底层是gcc和g++),所以需要我们自行编译。
1.3 CMAKE编译OpenCV
打开CMAKE,打开OpenCV的source文件路径,选择目标文件的生成路径,我设置的是D:/Opencv/opencv/Qt_OpenCV_Build
,如下图所示:
之后点击左下角的Configure:
之后会弹出一个指定的本地编译器,这个就选择MinGW,如下图所示:
下一步会要求我们选择编译c文件和c++文件的编译器(第三个那个Fortran不用管),这里我们用QT中的gcc和g++;QT的这两个工具的路径如下图所示:
选择好之后CMAKE就开始工作了,下图红色字体表示的是有些错误,或者编译未通过,这个需要我们按照他的提示去填一些内容。
编译完之后,有些错误我们先不管,先下拉,找到with_qt和with_open_gl,把这两个打上勾,然后继续点击configure。其中with_open_gl也是经常会用到的,后续可能会用到里面的一些库,和opencv有交叉的地方。opencv是从图像中获取数据,opengl是从数据生成图片,进行渲染。
再次编译后,会出下如下错误,这时候我们需要逐个修改路径:修改前和修改后的路径如下图所示(注意: OPENGL中出现的错误不用管,修改了QT中的错误,其他错误自然就好了): 其实在这篇文章中也详细提到了这个,从这一步开始,后面的步骤和这篇文章 Qt配置OpenCV教程,亲测已试过(详细版)大差不差,但是我觉得还是要写完,毕竟每个人的环境可能会有出入。
完了之后,就会发现一切正常了。
最后,点击Generate,生成makefile文件,完成之后,关闭Cmake即可,此时进入之前我们新建的文件夹
1.4 下载OpenCV4.5.1
- 进入之前我们新建的文件夹
D:\Opencv\opencv\Qt_OpenCV_Build
- 将鼠标放在该文件夹界面内,按住shift键,同时点击鼠标右键,点击在此处打开Powershell窗口(s),进入Windows Powershell,输入
mingw32-make -j 8
- 按回车键执行该命令,这里的-j 8是为了让CPU进行多任务处理,可以加快编译速度。这个过程可能会持续一个多小时。
- 100%完成之后,输入
mingw32-make install
- 完成之后退出,另外再将如下路径加入环境变量即可
D:\Opencv\opencv\Qt_OpenCV_Build\install\x64\mingw\bin
2、测试QT程序
2.1 创建项目
- 首先,创建QT应用程序,选择minGW作为编译器
- 在test1.pro中如图所示位置加上如下代码
INCLUDEPATH += D:/Opencv/opencv/Qt_OpenCV_Build/install/include/opencv2 \ #这两个是必加的
D:/Opencv/opencv/Qt_OpenCV_Build/install/include
LIBS += D:/Opencv/opencv/Qt_OpenCV_Build/lib/libopencv_*.a
其中libopencv_*.a表示以libopencv开头,以a结尾的所有静态库文件,由于.a是拓展名,跟在dll后面。 注意反斜杠不要搞错了, \的意思是后面还有内容
- 可以按ctrl+s或者点击qmake进行构建
- 首先设置ui界面,用到了两个label和三个pushbutton,label设置了样式表,所以有背景颜色,样式表中加入了如下代码
QLabel{background-color:rgb(200,101,102);}
- ui界面如下:
- mainwindows.h的代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QTimer>
#include <QImage>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h> //防止报错 'CV_BGR2RGB' was not declared
using namespace cv;
using namespace std;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QImage Mat2QImage(Mat cvImg);
private slots:
void openCamara(); // 打开摄像头
void readFarme(); // 读取当前帧信息
void closeCamara(); // 关闭摄像头。
void takingPictures(); // 拍照
private:
Ui::MainWindow *ui;
QTimer *timer;
QImage imag;
Mat cap,cap_gray,cap_tmp; //定义一个Mat变量,用于存储每一帧的图像
VideoCapture capture; //声明视频读入类
};
#endif // MAINWINDOW_H
- mainwindows.cpp的代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
using namespace cv;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->take, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->close, SIGNAL(clicked()), this, SLOT(closeCamara()));
}
//打开摄像头
void MainWindow::openCamara()
{
capture.open(0); //从摄像头读入视频如果设备只有一个摄像头就传入参数0
qDebug("open");
if (!capture.isOpened()) //先判断是否打开摄像头
{
qDebug("err");
}
timer->start(20); // 开始计时,20ms获取一帧
}
//读取摄像头信息
void MainWindow::readFarme()
{
capture>>cap; //读取当前帧
if (!cap.empty()) //判断当前帧是否捕捉成功 **这步很重要
{
imag = Mat2QImage(cap);
imag = imag.scaled(ui->camera->width(), ui->camera->height(),
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致
//imshow(name, cap); //若当前帧捕捉成功,显示
ui->camera->setPixmap(QPixmap::fromImage(imag)); // 将图片显示到label上
}
else
qDebug("can not ");
}
// 拍照
void MainWindow::takingPictures()
{
capture>>cap; //读取当前帧
if (!cap.empty()) //判断当前帧是否捕捉成功 **这步很重要
{
imag = Mat2QImage(cap);
imag = imag.scaled(ui->photo->width(), ui->photo->height(),
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致
//imshow(name, cap); //若当前帧捕捉成功,显示
ui->photo->setPixmap(QPixmap::fromImage(imag)); // 将图片显示到label上
}
else
qDebug("can not ");
}
//关闭摄像头,释放资源,必须释放***
void MainWindow::closeCamara()
{
timer->stop(); // 停止读取数据。
}
// 图片转换(网上抄的)
QImage MainWindow::Mat2QImage(Mat cvImg)
{
QImage qImg;
if(cvImg.channels()==3) //3 channels color image
{
cv::cvtColor(cvImg,cvImg,CV_BGR2RGB);
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols, cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_RGB888);
}
else if(cvImg.channels()==1) //grayscale image
{
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols,cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_Indexed8);
}
else
{
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols,cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_RGB888);
}
return qImg;
}
MainWindow::~MainWindow()
{
delete ui;
}
2.2 效果
最终的效果如下
补充一个小技巧:shift+r
可以预览ui界面