第一个Qt开发的OpenCV程序

OpenCV计算机视觉开发实践:基于Qt C++ - 商品搜索 - 京东

下载安装Qt:https://download.qt.io/archive/qt/5.14/5.14.2/qt-opensource-windows-x86-5.14.2.exe

下载安装OpenCV:https://opencv.org/releases/

下载安装CMake:Download CMake

这些软件安装完成完成后,我们可以开始用Qt编写OpenCV程序了。

【例2.2】第一个Qt开发的OpenCV程序

(1)在桌面上找到Qt Creator 4.11.1 (Community),双击打开Qt Creator,我们准备新建一个控制台项目,项目名是hello。在Qt Creator主界面的Projects旁点击New按钮,如图2-31所示。

图2-31

然后在出现的"新建项目",选中"Qt Console Application",如图2-32所示。

图2-32

点击Choose按钮,然后输入项目名称和创建路径,路径建议用全英文路径,如图2-33所示。

图2-33

随后连续点击下一步,直到向导结束出现编辑窗口,我们可以看到一个自动生成了一个main函数了。我们来简单修改下程序,使之既能输出图形对话框,又能在命令窗口中输出字符串,代码如下:

复制代码
#include <QApplication>
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv); 		//定义应用程序对象
    QString text = "helloworld"; 		//定义一个字符串并赋值
    // 创建并显示消息对话框
    QMessageBox::information(nullptr, "hi", text);
    puts("helloworld"); 					//在控制台窗口输出字符串
    return a.exec(); 					//进入事件循环
}

QApplication是Qt应用程序中必不可少的一部分,它负责管理应用程序的生命周期,处理事件循环,设置应用的整体样式等。QString是Qt框架中处理文本数据的核心类之一。它提供了强大的字符串处理能力,支持多种文本编码和操作,我们定义字符串text,并通过QMessageBox::information将其在消息对话框上输出。然后,用C函数puts在控制台上输出字符串helloworld。程序很简单,没啥好讲,若学过Qt,一看便懂。

由于这个项目原本是控制台项目,因此如果要输出图形消息框,还需要在项目配置文件中进行一些修改,打开hello.pro,在文件开头添加"QT+=widgets",如下所示:

复制代码
QT+=widgets

Widgets是在Qt中创建用户界面的主要元素。Widgets可以显示数据和状态信息,接收用户输入,并为应该组合在一起的其他小部件提供容器。QT+的意思是加上widgets模块。如果此时运行程序,则可以出现消息对话框并可以在控制台上输出字符串helloworld。

(2)Qt项目能运行了,但还不是一个OpenCV程序,下面我们加上OpenCV代码。首先要在工程配置文件中添加OpenCV库和头文件的路径,在hello.pro的末尾添加代码如下:

复制代码
INCLUDEPATH += D:/opencvBuild/install/include/

LIBS += -L D:/opencvBuild/install/x64/mingw/lib/libopencv_*.a

宏INCLUDEPATH用来指定头文件所在路径,LIBS用来指定库文件所在路径,两个宏都要用一个+,并且LIBS+=右边要用-L来指定路径,这个写法和gcc指定库路径写法类似。

下面我们添加源代码,在Qt Creator中打开main.cpp,输入代码如下:

复制代码
#include <QApplication>
#include <QMessageBox>
#include <opencv2/opencv.hpp>
#include <QDebug>
#include <QDir>
#include <iostream>

using namespace cv;  //所有OpenCV类都在命名空间cv下
using namespace std;

void f()   //自定义函数,实现两幅图片混合
{
    double alpha = 0.5; double beta; double input;
    Mat src1, src2, dst; //创建Mat对象,Mat用于存储图片的矩阵类,dst用于存放混合后的图片

    //提示用户输入第一幅图片的权值alpha
    qDebug() <<"线性混合:";
    qDebug() << "输入第一幅图片的权重alpha [0.0-1.0]: ";
    cin >> input;   //用户输入

    //如果用户输入值介于0和1之间,则用该输入值作为alpha的值
    if (input >= 0 && input <= 1)
        alpha = input;

    QString currentPath = QDir::currentPath();  //获取当前路径
    qDebug() <<"当前路径是:"<< currentPath;

    //读取两幅大小必须一样的JPG图片
    src1 = imread("p1.jpg");
    src2 = imread("sbh.jpg");

    if (src1.empty()) { cout << "Error loading src1" << endl; return; }
    if (src2.empty()) { cout << "Error loading src2" << endl; return; }

    beta = (1.0 - alpha);
    addWeighted(src1, alpha, src2, beta, 0.0, dst);//将图1与图2线性混合
    imshow("res",dst); 	//显示混合后的图片
    waitKey(0); 			//等待按键响应后退出,0改为5000就是5秒后自动退出
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);   	//定义应用程序对象
    QString text = "helloworld";  	//定义一个字符串并赋值

    cv::Mat image = cv::imread("d:/test.jpg");  //读取d盘上test.jpg文件
    if (image.empty()) { 			//判断文件是否为空
       return -1;  					//为空返回-1,结束程序
    }
   std::string strTitle = text.toStdString(); //把QString字符串转为std::string字符串
    
   namedWindow(strTitle, cv::WINDOW_AUTOSIZE); //创建一个标题是strTitle窗口
   imshow(strTitle, image); 	//在标题为strTitle的窗口中显示图像
   waitKey(0); 					//等待用户按键
   destroyWindow(strTitle);		//销毁标题是strTitle的窗口

   // 创建并显示消息对话框
   QMessageBox::information(nullptr, "hi", text);
   f();
   return a.exec();
}

上述代码的自定义函数f功能将图片p1.jpg和sbh.jpg两幅图片进行混合,它们的大小必须一样。这两幅图片必须复制到D:\ex\build-hello-Desktop_Qt_5_14_2_MinGW_64_bit-Debug目录下。其中,OpenCV库中的API函数imread用来从文件中读取图片。API函数addWeighted用于将两张相同大小、相同类型的图片进行融合,第二个参数alpha表示第一幅图片所占的权重,第四个参数beta表示第2个图片所占的权重。权重越大的图片显示得越多,比如我们输入alpha为0.9,则主要显示第一幅图片。main中的代码比较简单,主要是从d盘读取一个图片文件test.jpg,然后调用f。

(2)复制动态链接库到exe文件所在文件夹。首先我们打开以下路径来查看exe文件:

复制代码
D:\ex\build-hello-Desktop_Qt_5_14_2_MinGW_64_bit-Debug\debug

图2-4

这个路径是我们程序生成的hello.exe文件所在的路径,hello.exe是一个Windows下的可执行文件,是不是觉得很神奇,MinGW能在编译阶段加载Linux下的静态库(.a)文件,最终生成了Windows下的.exe文件。但hello.exe还需要加载OpenCV源码编译出来的动态链接库后才能运行。打开目录D:\opencvBuild\install\x64\mingw\bin\,把该目录下的libopencv_core4100.dll、libopencv_highgui4100.dll、libopencv_imgcodecs4100.dll和libopencv_imgproc4100.dll四个文件复制到hello.exe文件所在文件夹。

(3)运行程序,在Qt Creator中点击点击左下角的三角运行按钮或直接按快捷键Ctrl+R来运行项目。运行结果如图2-4所示。

随便按一个键盘键,则会显示helloworld信息框,关闭信息框,会让我们在控制台窗口上输入权值,这里我们输入0.9,可以看到输入第一幅图片权重是0.9后,sbh.jpg显示的效果就淡了很多,如图2-5所示。

图2-5

如图图片不能加载,请确认p1.jgp和sbh.jpg是否复制到以下路径:

复制代码
D:\ex\build-hello-Desktop_Qt_5_14_2_MinGW_64_bit-Debug

以及,test.jpg是否复制到d盘。在这个程序中,我们即加载了绝对路径下的图片文件(test.jpg),也加载了当前路径下的图片文件(p1.jpg和sbh.jpg)。这3个文件平时可以到工程目录的res文件夹下找到。

至此,基于Qt Creator的OpenCV的开发环境搭建起来了。

相关推荐
weifexie2 小时前
ruby可变参数
开发语言·前端·ruby
王磊鑫2 小时前
重返JAVA之路-初识JAVA
java·开发语言
千野竹之卫2 小时前
3D珠宝渲染用什么软件比较好?渲染100邀请码1a12
开发语言·前端·javascript·3d·3dsmax
liuluyang5303 小时前
C语言C11支持的结构体嵌套的用法
c语言·开发语言·算法·编译·c11
凌叁儿3 小时前
python保留关键字详解
开发语言·python
明飞19874 小时前
C_内存 内存地址概念
c语言·开发语言
代码不停4 小时前
Java中的异常
java·开发语言
兮兮能吃能睡5 小时前
Python中的eval()函数详解
开发语言·python
狄加山6755 小时前
Qt模型-视图架构
开发语言·qt
Aphelios3805 小时前
TaskFlow开发日记 #1 - 原生JS实现智能Todo组件
java·开发语言·前端·javascript·ecmascript·todo