一般创建Qt项目,都会第一时间想到Qt creator,这个IDE确实好用,可自由选择编译器(mingw或Visual studio),但要同时结合OpenCv框架,整个配置过程太繁琐了,好像需要用到Cmake工具。综合考虑了一下,在Visual Studio中创建Qt+OpenCv项目要简单一些。
项目开始之前需要需要在Visual studio中配置好Qt和OpenCv的开发环境,不会的看这两篇:
Visual Studio 2019中使用Qt,步骤详解_Xx_Studying的博客-CSDN博客_vs2019 使用qt
VS2019中配置OpenCv4.5.5,保姆级教程_Xx_Studying的博客-CSDN博客_vs2019配置opencv
环境搭建好之后,即可编写Qt+OpenCv项目了。
(注意:在VS中创建的Qt项目,生成的是ui对象,不是ui指针,用的不习惯可以自己改成ui指针,同时要注意new和delete,另外项目树中也没有Pro文件)
该项目来源《OpenVCv3和Qt5计算机视觉应用开发》
本人的基本环境:Windows11、Opencv4.5.5、visual studio2019.
1、创建空项目
双击打开vs2019
新建项目
随后直接下一步进行创建。
空项目完成之后,双击ui文件,进行界面绘制:
这时候呢们的按键颜色会和我不同, 不要着急,选中按钮控件右击,点击改变样式表:
添加几行代码即可 ,下面的绿色按钮同理,不过背景颜色改为:background-color:#99ff99;
然后对各个控件进行重新命名,如下
改完之后附上详细代码吧:
main.cpp
#include "Fist_Qt_OpenCV.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Fist_Qt_OpenCV w;
w.show();
return a.exec();
}
First_Qt_OpenCv.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include "ui_Fist_Qt_OpenCV.h"
class Fist_Qt_OpenCV : public QMainWindow
{
Q_OBJECT
public:
Fist_Qt_OpenCV(QWidget *parent = nullptr);
~Fist_Qt_OpenCV();
private:
Ui::Fist_Qt_OpenCVClass *ui;
void loadSettings();//加载设置,
void saveSettings();//保存设置,程序运行关闭后,再次打开保留上次的状态,如单选框或复选框的状态
protected:
void closeEvent(QCloseEvent* event); //覆盖原来的虚函数,用来关闭程序,进行提示
private slots:
void on_inputPushButton_pressed();
void on_outputPushButton_pressed();
};
First_Qt_OpenCv.cpp
#include "Fist_Qt_OpenCV.h"
Fist_Qt_OpenCV::Fist_Qt_OpenCV(QWidget *parent)
: QMainWindow(parent),ui(new Ui::Fist_Qt_OpenCVClass)
{
ui->setupUi(this);
loadSettings();
connect(ui->inputPushButton, &QPushButton::pressed, this, &Fist_Qt_OpenCV::on_inputPushButton_pressed);
}
Fist_Qt_OpenCV::~Fist_Qt_OpenCV()
{
delete ui;
}
void Fist_Qt_OpenCV::on_inputPushButton_pressed()
{
//QFileDialog用于选择计算机上的文件或文件夹,使用时需包含相应的头文件
//QDir用于访问计算机上的文件夹,并获得有关文件夹路径的各种类型的信息,使用时需包含相应的头文件
//
QString fileName = QFileDialog::getOpenFileName(this, "open Input Image", QDir::currentPath(), "Images (*.jpg *.png *.bmp)");
if (QFile::exists(fileName))
{
ui->inputLineEdit->setText(fileName);
}
}
void Fist_Qt_OpenCV::on_outputPushButton_pressed()
{
QString fileName = QFileDialog::getSaveFileName(this, "Select Output Image", QDir::currentPath(), "Images (*.jpg *.png *.bmp)");
if (!fileName.isEmpty())
{
ui->outputLineEdit->setText(fileName);
using namespace cv;
Mat inpImg, outImg;
inpImg = imread(ui->inputLineEdit->text().toStdString());//将Qt的Qstring转换为C++ std::string类
if (ui->mediaBlurRaioButton->isChecked())
{
cv::medianBlur(inpImg, outImg, 5);
}
else if (ui->gaussianBlurRaioButton->isChecked())
{
cv::GaussianBlur(inpImg, outImg, Size(5,5),1.25);
}
imwrite(fileName.toStdString(), outImg);
if (ui->displayImageCheckBox->isChecked())
{
imshow("Output Image", outImg);
}
}
}
void Fist_Qt_OpenCV::closeEvent(QCloseEvent* event)
{
//QcloseEvent是众多Qt事件类(QEvent)中的一个
//QMessageBox类可用来显示简单的图标、文本或信息
int result = QMessageBox::warning(this, "Exit", "Are you sure you want to close this program?", QMessageBox::Yes, QMessageBox::No);
if (result == QMessageBox::Yes)
{
saveSettings();
event->accept();
}
else
{
event->ignore();
}
}
void Fist_Qt_OpenCV::loadSettings()
{
QSettings settings("Packt","Fist_Qt_OpenCV",this);
ui->inputLineEdit->setText(settings.value("inputLineEdit", "").toString());
ui->outputLineEdit->setText(settings.value("outputLineEdit", "").toString());
ui->mediaBlurRaioButton->setChecked(settings.value("mediaBlurRadioButton",true).toBool());
ui->gaussianBlurRaioButton->setChecked(settings.value("gaussianBlurRaioButton", false).toBool());
ui->displayImageCheckBox->setChecked(settings.value("displayImageCheckBox", false).toBool());
}
void Fist_Qt_OpenCV::saveSettings()
{
QSettings settings("Packt", "Hello_OpenCV_Qt", this);
settings.setValue("inputLineEdit", ui->inputLineEdit->text());
settings.setValue("outputLineEdit", ui->outputLineEdit->text());
settings.setValue("mediaBlurRadioButton", ui->mediaBlurRaioButton->isChecked());
settings.setValue("gaussianBlurRaioButton", ui->gaussianBlurRaioButton->isChecked());
settings.setValue("displayImageCheckBox", ui->displayImageCheckBox->isChecked());
}
这是小项目的主要代码,再次强调,在VS中创建的Qt项目,生成的是ui对象,不是ui指针,我自己改成ui指针。具体细节看我代码,一般的地方都有注释,关于一些类,可以参考Qt和OpenCv手册。
最后,这个小项目是选择文件路径下的一副图片,然后是选择对图像进行中值模糊处理或高斯模糊处理,并将处理后的图像存于指定路径下。
运行示例:
按回车,在指定路径下已经生成了高斯模糊后的图片;
原图:
高斯模糊后的图片:
小白的学习摸索之路,欢迎讨论指正。