在MacOS上Qt配置OpenCV并进行测试

一.Qt环境准备

        上一篇博客我讲了如何下载配置OpenCV库,但是在Qt5.15.2使用OpenCV库时,出现了一个问题就是我下载的Qt5.15.2是x86架构的,不能对OpenCV库进行链接,而OpenCV库是arm架构的

        直接使用Qt5.15.2编译链接OpenCV库链接头文件是可以的,但是使用OpenCV代码就不能成功链接编译了

因此需要下载Qt6.3.1版本的, Qt6.3.1版本是arm架构的

下载完成后打开Qt  Creator在Qt版本里面加入Qt6.3.1的qmake

一般是在下载的Qt版本文件bin目录下

再在构建配套(Kit)中加入Qt6.3.1版本的构建配套

这样Qt环境就搭建好了

二.在Qt项目中加载Opencv库并编写代码测试 

1.使用Opencv加载图片

(1)在Qt中创建一个新项目

选择Qt6.3.1(arm)

(2)在.pro文件中链接OpenCV库

#链接OpenCV头文件
INCLUDEPATH +=/usr/local/include/
INCLUDEPATH +=/usr/local/include/opencv4/
INCLUDEPATH +=/usr/local/include/opencv4/opencv2
#链接OpenCV库文件
LIBS += -L/usr/local/lib -lopencv_gapi \
        -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired \
        -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm \
        -lopencv_highgui -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs \
        -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg \
        -lopencv_rgbd -lopencv_saliency -lopencv_sfm -lopencv_stereo -lopencv_structured_light \
        -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching \
        -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot \
        -lopencv_videostab -lopencv_videoio -lopencv_xfeatures2d -lopencv_shape -lopencv_ml \
        -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect \
        -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto \
        -lopencv_photo -lopencv_imgproc -lopencv_core

(3)添加新资源文件

(4)在mainwindow.cpp中编写代码在窗口加载图片

#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QDebug>
#include <QFile>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //以只读的方式打开图片文件
    QFile file(":/img/tree.jpg");
    if(!file.open(QFile::ReadOnly))  {
         qDebug() << "打开图片失败";
    }
    //将整个图片文件内容读取到一个 QByteArray 对象中
    QByteArray photo = file.readAll();
    cv::Mat img = cv::imdecode(std::vector<char>(photo.begin(), photo.end()), cv::IMREAD_COLOR);
    //判定图片是否加载成功
    if(img.empty()){
        qDebug() << "没有找到照片";
    }
    cv::namedWindow("tree", cv::WINDOW_AUTOSIZE);
    cv::imshow("tree", img);
    cv::waitKey(0); //cv::waitKey(10000);
    cv::destroyWindow("tree");
}

MainWindow::~MainWindow()
{
    delete ui;
}

 运行结果:

 (5)代码中使用的OpenCV函数分析

        1)cv::imdecode()函数
//cv::Mat是OpenCV用于处理所有图像类型的结构
//cv::imdecode() 函数将 QByteArray 转换为 OpenCV 的图像格式 cv::Mat,以便进一步处理,cv::IMREAD_COLOR表示以彩色模式加载图像
    cv::Mat img = cv::imdecode(std::vector<char>(photo.begin(), photo.end()), cv::IMREAD_COLOR);

函数原型: 

Mat cv::imdecode (InputArray buf, int flags);
Mat cv::imdecode (InputArray buf, int flags, Mat *dst);
函数功能: 
        从内存的缓存区中读取图片
参数:    buf:一个数组或字节数组
        flags:用来指定图像加载的标志,通过这个参数,可以控制图像加载的一些行为和选项
         下面是falgs的枚举类型:
            enum cv::ImreadModes {
                  cv::IMREAD_UNCHANGED = -1,            //按图像原样加载图像
                  cv::IMREAD_GRAYSCALE = 0,             //以灰度模式加载图像
                  cv::IMREAD_COLOR = 1,                 //以彩色模式加载图像
                  cv::IMREAD_ANYDEPTH = 2,              //以原始深度加载图像
                  cv::IMREAD_ANYCOLOR = 4,              //以任意颜色模式加载图像,返回一个3通道图像
                  cv::IMREAD_LOAD_GDAL = 8,             //使用gdal驱动程序加载图像       
                  cv::IMREAD_REDUCED_GRAYSCALE_2 = 16,  //将图像转换为单通道灰度图像,图像尺寸减小1/2
                  cv::IMREAD_REDUCED_COLOR_2 = 17,      //图像转换为3通道BGR彩色图像,图像大小减少1/2
                  cv::IMREAD_REDUCED_GRAYSCALE_4 = 32,  //将图像转换为单通道灰度图像,图像尺寸减小1/4
                  cv::IMREAD_REDUCED_COLOR_4 = 33,      //将图像转换为3通道BGR彩色图像,图像大小减少1/4
                  cv::IMREAD_REDUCED_GRAYSCALE_8 = 64,  //将图像转换为单通道灰度图像,图像尺寸减小1/8
                  cv::IMREAD_REDUCED_COLOR_8 = 65,      //将图像转换为3通道BGR彩色图像,图像大小减少1/8
                  cv::IMREAD_IGNORE_ORIENTATION = 128  //不根据EXIF的方向标志旋转图像(EXIF(Exchangeable Image File Format)是一种图像文件格式,用于存储数字图像中的元数据信息,例如相机设置、拍摄日期和时间、地理位置等。)
            }
        dst(可选):用于接收解码后的图像数据
返回值:
        成功: 一个Mat类型的值
        失败: NULL

例子: 

cv::Mat image;  // 定义用于存储解码后图像的 cv::Mat 对象
cv::imdecode(buffer, flags, &image);

         通过传递 &imagecv::imdecode() 函数的 dst 参数,解码后的图像数据将直接存储在 image

        也可以不使用第三个参数,直接使用返回值

cv::Mat image;  // 定义用于存储解码后图像的 cv::Mat 对象
image = cv::imdecode(buffer, flags);
        2)cv::namedWindow()函数
 //cv::namedWindow():函数将会在屏幕上打开一个窗口,窗口名为tree,cv::WINDOW_AUTOSIZE是窗口的属性:窗口的大小与载入的图片大小一致,图片会被缩放大小来适应窗口大小
    cv::namedWindow("tree", cv::WINDOW_AUTOSIZE);

 函数原型:

void cv::namedWindow(const String &winname,int flags = WINDOW_AUTOSIZE);
函数功能:
        函数namedWindow创建一个窗口,该窗口可用作图像和跟踪条的占位符。创建的窗口通过窗口名称来引用
参数:
        winname: 窗口标题,也是用于窗口标识符的窗口名称
        flags: 窗口标志
            下面是falgs的枚举类型:
            enum cv::WindowFlags {
                  cv::WINDOW_NORMAL = 0x00000000,       //用户可以调整窗口的大小(没有限制)/也可以将全屏窗口切换到正常大小
                  cv::WINDOW_AUTOSIZE = 0x00000001,     //用户无法调整窗口大小,窗口大小受显示图像的限制
                  cv::WINDOW_OPENGL = 0x00001000,       //支持opengl的窗口
                  cv::WINDOW_FULLSCREEN = 1,            //将窗口改为全屏
                  cv::WINDOW_FREERATIO = 0x00000100,    //图像尽可能地扩展(没有比例限制)
                  cv::WINDOW_KEEPRATIO = 0x00000000,    //保持图像原有的比例
                  cv::WINDOW_GUI_EXPANDED =0x00000000,  //状态栏和工具栏
                  cv::WINDOW_GUI_NORMAL = 0x00000010    //默认的窗口模式,会在图像显示时以普通窗口的形式呈现,并提供基本的窗口操作,如调整大小、移动和关闭
            }
返回值:
        无返回值
         3)cv::imshow()函数
//cv::imshow():函数将会创建一个窗口(如果这个窗口不存在,会自动调用cv::namedWindow()函数来新建一个窗口),调用cv::imshow()会将指定的图片绘制在窗口上
    cv::imshow("tree", img);

函数原型:


void cv::imshow(const String &winname, InputArray mat);
函数功能: 
        在指定窗口中显示图像
参数: 
        winname: 指定的窗口对象
        mat: 展示的图像
返回值: 
        无返回值
        4)cv::waitKey()函数
//cv::waitKey():系统暂停并等待键盘事件发生(如果传入的参数值大于零,就会等待该值的毫秒时间(如果在等待时间中有键盘事件发生,会立马继续执行后面的程序),然后继续执行后面程序,如果参数设置为0或负数,程序将会无限等待,直到有键盘事件发生)
    cv::waitKey(0); //cv::waitKey(10000);

 函数原型:

int cv::waitKey	(int delay = 0);
函数功能: 
        等待键盘事件发生
参数: 
        delay: 以毫秒为单位的延迟。0是代表“永远”的特殊值
返回值:
        返回按下的键的代码,如果在指定时间之前没有按下键,则返回-1
        5)cv::destroyWindow()函数
//cv::destroyWindow() 关闭指定的窗口并释放相关内存空间
    cv::destroyWindow("tree");

函数原型:

void cv::destroyWindow(const String &winname);	
函数功能: 
        销毁指定的窗口
参数:
        winname: 要销毁的窗口名称
返回值:
        无返回值

2.使用Opencv加载视频

(1)使用Qt创建一个新项目

(2)在.pro文件中链接OpenCV库

#链接OpenCV头文件
INCLUDEPATH +=/usr/local/include/
INCLUDEPATH +=/usr/local/include/opencv4/
INCLUDEPATH +=/usr/local/include/opencv4/opencv2
#链接OpenCV库文件
LIBS += -L/usr/local/lib -lopencv_gapi \
        -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired \
        -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm \
        -lopencv_highgui -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs \
        -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg \
        -lopencv_rgbd -lopencv_saliency -lopencv_sfm -lopencv_stereo -lopencv_structured_light \
        -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching \
        -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot \
        -lopencv_videostab -lopencv_videoio -lopencv_xfeatures2d -lopencv_shape -lopencv_ml \
        -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect \
        -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto \
        -lopencv_photo -lopencv_imgproc -lopencv_core

(3)在mainwindow.cpp中编写代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //新建一个窗口,窗口名为scenery,窗口模式为cv::WINDOW_AUTOSIZE
    cv::namedWindow("scenery", cv::WINDOW_AUTOSIZE);
    cv::VideoCapture cap; //cv::VideoCapture类型用于打开视频文件
    //打开指定的视频文件
    if(!cap.open("/Users/liwanyu/Downloads/opencvDemo/day1/video/videoload/video/scenery.mp4")){
        qDebug() << "打开视频文件失败";
    }

    cv::Mat frame; //用于保存视频帧
    //在while循环中循环播放视频
    while(1){
        //视频文件按照帧从视频流中读出来,每33毫秒换帧,如果在这33毫秒中有键盘事件发生就退出视频帧播放
        cap.read(frame); //cap >> frame
        if(frame.empty()){
            break;
        }
        cv::imshow("scenery", frame);
        if(cv::waitKey(33)>=0){
            break;
        }
    }
    cv::destroyWindow("scenery"); //关闭指定的窗口并销毁其内存空间
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行结果:

   (4)代码中使用的OpenCV函数分析

        1)cv::VideoCapture

   cv::VideoCapture 

功能:用于从视频文件、图像序列或相机中捕获视频的类

参考文档:

OpenCV: Image file reading and writing

OpenCV: High-level GUI

OpenCV: cv::VideoCapture Class Reference

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/261743.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

合并两个有序链表算法(leetcode第21题)

题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a;输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a;输入&#xff1a;l1 [], l2 [] 输…

UE4 UE5 一直面向屏幕

一直面相屏幕&#xff0c;方法很简单 新建一个蓝图&#xff0c;如下添加组件&#xff1a; 蓝图如下&#xff1a; Rotation Actor &#xff1a;需要跟随镜头旋转的物体 Update&#xff1a;一个timeline&#xff08;替代event tick 只是为了循环&#xff09; Timeline&#xff…

React-Native环境搭建(IOS)

系列文章目录 React-Native环境搭建&#xff08;IOS&#xff09; 目录 系列文章目录前言一、IOS环境搭建前置说明二、环境搭建步骤1.Homebrew安装2.安装Xcode3.Node4.watchman5.CocoaPods 三、项目启动1.初始化项目2.项目启动 总结 前言 React-Native开发环境的搭建&#xff…

16 Vue3中使用v-model绑定多选框

概述 使用v-model绑定多选框也是一种比较常见的需求&#xff0c;比如一个用户可以绑定多个角色&#xff0c;可以有多个兴趣爱好。 在本节课中&#xff0c;我们来学习一下这两种用法。 基本用法 我们创建src/components/Demo16.vue&#xff0c;在这个组件中&#xff0c;我们…

尼得科:有了“它”,无惧风雨的挑战!

尼得科株式会社的集团公司尼得科仪器株式会社 (旧日本电产三协)研发出亲水涂层了一种该涂层可提升车载摄像头的镜头在雨天等湿润环境下的可视性。 一、性能测试 二、产品特征 ・镜头单元的最外层镜片表面采用了新开发的亲水涂层 ・实现了接触角不超过45的高持久亲水性※1 ・亲水…

idea SpringBoot项目 Run Dashboard 多个启动类分组展示 失效

idea SpringBoot项目 Run Dashboard 多个启动类分组展示 想要的显示格式 失效的显示格式, 没有按照分组进行平铺展示 解决方案 勾选 展示服务树 参考文章: IDEA 打开Run Dashboard 分组启动 https://www.cnblogs.com/hanjun0612/p/10917689.html idea springBoot项目Run…

linux高级管理——shell脚本应用(三)

一、for循环语句的使用&#xff1a; 1.1 for语句的结构: 使用for循环语句时&#xff0c;需要指定-一个变量及可能的取值列表&#xff0c;针对每个不同的取值重复执行相同的命令序列&#xff0c;直到变量值用完退出循环。在这里,"取值列表”称为for语句的执行条件&#x…

【HarmonyOS开发】ArkUI实现下拉刷新/上拉加载

列表下拉刷新、上拉加载更多&#xff0c;不管在web时代还是鸿蒙应用都是一个非常常用的功能&#xff0c;基于ArkUI中TS扩展的声明式开发范式实现一个下拉刷新&#xff0c;上拉加载。 上拉加载、下拉刷新 如果数据量过大&#xff0c;可以使用LazyForEach代替ForEach 高阶组件-…

【Proteus/8086】swjtu西南交大微机与接口技术实验:计时器

实验内容: 计时器基本功能: 1)CPU必须用8086 2)计时器最小计时单位为秒。 3)以00:00格式显示计时,前2位表示分钟,后2位表示秒。 4)计时器是正计时方式 5)有暂停、继续计时功能 6&#xff09;有复位计时功能 7&#xff09;每次按下暂停键&#xff0c;能显示计时间隔时间 参考…

智能优化算法应用:基于类电磁机制算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于类电磁机制算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于类电磁机制算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.类电磁机制算法4.实验参数设定5.算法…

【Linux学习】进程间通信

目录 十四:进程间通信 14.1 进程间通信的介绍 进程间通信的概念: 为什么需要进程间通信: 常见的进程间通信方式: 14.2 进程间通信的原理 十五:进程间通信--管道 15.1 管道的介绍 管道的概念: 管道的分类: 15.2 匿名管道 匿名管道的原理: pipe函数创建匿名管道: 匿名管道实现父…

Spring Security:从入门到精通,全方位指南

Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多&#xff0c;因为相比与SpringSe…

污水处理厂可视化:让环保与科技共舞

随着科技的飞速发展&#xff0c;我们的生活环境变得越来越美好。然而&#xff0c;随着城市化进程的加快&#xff0c;污水处理问题也日益凸显。如何有效、高效地处理污水&#xff0c;成为了一个亟待解决的问题。而“污水处理厂可视化”技术的出现&#xff0c;为这个问题提供了一…

Python---TCP 客户端程序开发

1. 开发 TCP 客户端程序开发步骤回顾 创建客户端套接字对象和服务端套接字建立连接发送数据接收数据关闭客户端套接字 2. socket 类的介绍 导入 socket 模块 import socket 创建客户端 socket 对象 socket.socket(AddressFamily, Type) 参数说明: AddressFamily 表示IP地…

Debug

0、Debug的步骤 Debug(调试)程序步骤如下&#xff1a; 1、添加断点 2、启动调试 3、单步执行 4、观察变量和执行流程&#xff0c;找到并解决问题 1、添加断点 在源代码文件中&#xff0c;在想要设置断点的代码行的前面的标记行处&#xff0c;单击鼠标左键就可以设置断点&…

创建型模式 | 原型模式

一、原型模式 1、原理 原型模式&#xff0c;用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。原型模式其实就是从一个对象再创建另外一个可定制的对象&#xff0c;而且不需要知道任何创建的细节。原型像是一个模板&#xff0c;可以基于它复制好多…

Matlab论文插图绘制模板第131期—函数等高线图

在之前的文章中&#xff0c;分享了Matlab函数折线图的绘制模板&#xff1a; 函数三维折线图&#xff1a; 函数网格曲面图&#xff1a; 函数曲面图&#xff1a; 进一步&#xff0c;再来分享一下函数等高线图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数…

Python连接数据库

文章目录 一、安装mysql二、SQLyog可视化操作三、python实现数据库单表类封装1. config 文件——config.py2. 封装类&#xff08;model&#xff09;——model.py3. 测试文件——test.py 一、安装mysql 官网安装&#xff0c;或者Windows64位直接在我的资源里面上传了mysql&…

Python: 函数参数是值传递还是引用传递

是引用传递。 Python的设计哲学是一切皆对象&#xff0c;不仅体现在内置数据类型、数据结构是对象&#xff0c;还包括Python编译运行需要的一些设施&#xff0c;比如stackframe、traceback等等。所以&#xff0c;为了更方便的传递数据&#xff0c;cpython内部全部采用指针传递…

如何开发专属花店展示平台小程序?

如今&#xff0c;微信小程序已经成为了花店行业拓展客户资源的重要工具。通过开发一个专属花店小程序&#xff0c;你可以为自己的花店带来更多的曝光和客户资源。那么&#xff0c;如何开发一个专属花店小程序呢&#xff1f;接下来&#xff0c;我们将一步步为你详细讲解。 首先&…