VS2019+opencv4.5.1+Qt5.12.10配置+Qt设计图片处理GUIDemo实操 全记录


寒假进组,硬件软件都有任务,软件方面要求:
用Qt设计一个图片处理的GUI(Graphical User Interface 图形用户界面),功能包括
1、读取图片
2、直方图分析
3、阈值可调的二值化处理
4、多线程批量读取、灰度转换和保存图片,并能显示处理时长以及处理进度。
从零开始(几乎没有c++基础)到完成大概用了4天时间,搜资料的时候发现这样的demo没什么人写,虽然代码也是从网上各种帖子上拼拼凑凑改改写完的,但也值得汇总一下,鉴于自己也是新手,就从环境配置到编写代码的每一个过程都写一写,希望也能帮助到入门的新手们,下面开始叭


VS2019+opencv4.5.1+Qt5.12.10配置

VS2019+opencv4.5.1配置

主要参考这篇文章:VS2017配置opencv教程(超详细!!!)
确实超详细…其中的第六步勾选微软符号服务器我觉得挺重要的,我是补上了这一步之后程序才跑成功的。
第五步属性管理需要说一下,我在配置的时候,点开Debug|X64,并没有Microsoft.Cpp.x64.user这个文件,所以自己新建了一个项目属性表命名为property,然后按照步骤配置好之后就直接把这个属性表保存了下来,这样的话以后每新建一个需要用到opencv的项目时,都可以在Debug|X64里添加进这个属性表,就不需要再重新设置了,挺方便的。


VS2019+Qt5.12.10配置

主要参考这两篇文章:VS2017专业版使用最新版Qt5.9.2教程
我装Qt的时候遇到了一些麻烦,主要是在官网上下载的Qt6打开QtCreator后说我没有license就用不了,所以重新下了个5.12,因为它是长期支持的版本。


Demo实操全记录

图像处理demo测试

因为自己c++几乎无基础,加上第一次接触opencv,所以第一步打算先将任务里涉及到的用opencv做的图片处理过程先实现了,也算是给自己涨涨信心。
学习opencv推荐它的官方教程网站:opencv官方教程(英文)
选择自己的版本,再点选各个模块
opencv
图像处理模块Imgproc module还有一个大佬的翻译版:opencv(c++)图像处理(Imgproc模块)

读取图片

OpenCV里用来读取图片的是imread函数

直方图分析

opencv官方教程里有直方图分析的示例代码,我用的是Histogram Calculation 直方图计算。直方图
它的代码里使用的每一个函数都可以通过点击直接跳转到定义,而且每一个示例还有主要代码的解释(Explanation),对于初学者来说太友好了!吹吹吹吹吹!代码展示
自己尝试的话可以新建一个项目,添加属性表,copy这个代码然后改一下需要打开的图片,就可以看到RGB三通道的直方图。
附上代码链接:Histogram Calculation


二值化且阈值可调

不出意外,在官方教程文档里找到了示例,OpenCV Tutorials->Image Processing (imgproc module) ->Basic->Basic Thresholding Operations
二话不说打开示例开始学习叭:Basic Thresholding Operations
附:这些示例里找文件路径的代码都比较复杂,自己试的时候可以直接定义读取文件的路径

//.cpp
String path = "D:\\VS\\Repo\\picture\\3.jpg";
Mat img = imread(path,IMREAD_COLOR);

图像处理的单独测试到此结束,下面把Qt结合起来。


Vs创建Qt项目

创建Qt Widgets Application

1、VS2019首页->创建新项目->搜索Qt->Qt Widgets Application(也许在其他版本里是Qt GUI Application)
创建新项目
然后会弹出来一个Qt Widgets Application Wizard,由于我没有Release的需求,所以只选择了Debug
Qt Widgets Application Wizard
最后Finish。
2、由于我们要用到opencv所以要设置属性:打开属性管理器,Debug|x64,添加设置好使用opencv相关的属性表Property。


设计Demo界面

1、解决方案资源管理器里的Resource Files中有一个.ui文件,左键双击后会弹出一个Qt Designer界面,在这里面可以将组件拖进图形界面来进行设计。
.ui文件
Qt Designer
设计好之后记得保存,然后在解决方案管理器里点击该.ui文件,右键->编译,在\source\repos\QtWidgetsApplication2\x64\Debug\uic下就会出现一个编译后的.h头文件。编译后的头文件
这样一来,刚建好项目时出现的这个报错就会消失了,因为现在工程里有ui_QtWidgetsApplication2.h这个文件了。
在这里插入图片描述
现在根据题目要求先设计好GUI界面如下,并且每一个组件都按照功能命名(部分label除外),编写组件控制函数时方便区分,设计好之后记得保存和编译。
在这里插入图片描述
界面设计好了,接下来就开始编写组件的控制函数


读取图片

1、首先在QtWidgetsApplication2.h头文件里添加slot槽函数

//.h文件
private slots:
    //函数名的命名方式:on_控件类名_触发方式()
    //声明读取图片函数
    void on_action_Button_ReadImg_clicked();

2、在QtWidgetsApplication2.cpp源文件里将组件和槽函数用connect函数连接起来

//.cpp
//connect(控件, 触发方式, this, 触发的槽函数);
connect(ui.ReadImg, SIGNAL(clicked()), this, SLOT(on_action_Button_ReadImg_clicked()));

ui.ReadImg是一个QPushButton类,继承于QAbstractButton类,它包含signal:clicked,当按钮被激活时就发送信号,触发槽函数。QT官方参考文档:QAbstractButton clicked
3、然后定义on_action_Button_ReadImg_clicked()函数

//.cpp
//因为用到了opencv里的函数,所以需要添上用到的库
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
//为了方便调试代码,声明了一个全局变量
Mat img = imread("D:\\VS\\Repo\\QtWidgetsApplication1\\picture\\3.jpg", IMREAD_COLOR);

void QtWidgetsApplication2::on_action_Button_ReadImg_clicked()
{
   
   
    Mat img1;
    //将imread得到的BRG Mat转换成RGB Mat
    cvtColor(img, img1, COLOR_BGR2RGB);
    //将RGB Mat格式转化为QImage格式
    QImage disImage = QImage((const unsigned char*)(img1.data), img1.cols, img1.rows, QImage::Format_RGB888);
    //用QPixmap获得QImage图像,用label显示QPixmap格式图像,并根据label的大小来缩放QImage的大小
    ui.dislabel->setPixmap(QPixmap::fromImage(disImage.scaled(ui.dislabel->size(), Qt::KeepAspectRatio)));
}

这里是用Qt里的label来显示图片,参考了这篇博文 Qt OpenCV 在界面显示图片 通过Lable方式 和GraphicsView 方式.
(目前只注重实现,Mat转QImage以及label显示QImage的原理暂不做深入研究,挖个坑待更新)
贴一个演示动图
读取图片


直方图分析

1、首先在QtWidgetsApplication2.h头文件里添加slot槽函数

//.h文件
private slots:
    //函数名的命名方式:on_控件类名_触发方式()
    //声明直方图分析函数
    void on_action_Button_HistAna_clicked();

2、在QtWidgetsApplication2.cpp源文件里将组件和槽函数用connect函数连接起来

//.cpp
//connect(控件, 触发方式, this, 触发的槽函数);
connect(ui.HistAna, SIGNAL(clicked()), this, SLOT(on_action_Button_HistAna_clicked()));

3、然后是直方图分析的实现

//.cpp
//Mat Hist(Mat src)里用到了std::Vector
using namespace std;

//定义了一个Hist函数,输入图像,返回它的直方图,格式均为Mat类
//从官方示例copy来的代码,没仔细研究,注重功能实现
Mat Hist(Mat src)
{
   
   
    //! [Separate the image in 3 places ( B, G and R )]
    vector<Mat> bgr_planes;
    split(src, bgr_planes);
    //! [Establish the number of bins]
    int histSize = 256;
    //! [Set the ranges ( for B,G,R) )]
    float range[] = {
   
    0, 256 }; //the upper boundary is exclusive
    const float* histRange = {
   
    range };
    //! [Set histogram param]
    bool uniform = true, accumulate = false;

    //! [Compute the histograms]
    Mat b_hist, g_hist, r_hist;
    calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&bgr_planes[2], 1, 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值