在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/2cv::IMREAD_REDUCED_COLOR_2 = 17,      //图像转换为3通道BGR彩色图像,图像大小减少1/2cv::IMREAD_REDUCED_GRAYSCALE_4 = 32,  //将图像转换为单通道灰度图像,图像尺寸减小1/4cv::IMREAD_REDUCED_COLOR_4 = 33,      //将图像转换为3通道BGR彩色图像,图像大小减少1/4cv::IMREAD_REDUCED_GRAYSCALE_8 = 64,  //将图像转换为单通道灰度图像,图像尺寸减小1/8cv::IMREAD_REDUCED_COLOR_8 = 65,      //将图像转换为3通道BGR彩色图像,图像大小减少1/8cv::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_AUTOSIZEcv::namedWindow("scenery", cv::WINDOW_AUTOSIZE);cv::VideoCapture cap; //cv::VideoCapture类型用于打开视频文件//打开指定的视频文件if(!cap.open("/Users/liwanyu/Downloads/opencvDemo/day1/video/videoload/video/scenery.mp4")){qDebug() << "打开视频文件失败";}//打开网络视频//cap.open("https://vd2.bdstatic.com/mda-njqbvdg1h8kdqez1/720p/h264/1666686182583726512/mda-njqbvdg1h8kdqez1.mp4?v_from_s=hkapp-haokan-hna&amp;auth_key=1703093507-0-0-fc2c4688c205be7eedb5e09162e45f57&amp;bcevod_channel=searchbox_feed&amp;pd=1&amp;cr=2&amp;cd=0&amp;pt=3&amp;logid=1907408427&amp;vid=14746953470406117750&amp;klogid=1907408427&amp;abtest=");cv::Mat frame; //用于保存视频帧//在while循环中循环播放视频while(1){//视频文件按照帧从视频流中读出来,每33毫秒换帧,如果在这33毫秒中有键盘事件发生就退出视频帧播放cap.read(frame); //cap >> frameif(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 

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

        

Public Member Functions:

默认的空构造:

   cv::VideoCapture::VideoCapture();

 重载的构造:

  cv::VideoCapture::VideoCapture(const String &filename, int apiPreference = CAP_ANY);

功能:

        打开视频文件或捕获摄像头设备或IP视频流(网络传输视频流),默认使用API首选项(CAP_ANY)进行视频捕获

参数:

        filename要打开的视频文件名、捕获设备的索引号(一般为0表示默认摄像头),或者是 IP 视频流地址

        apiPreference可选参数,用于指定视频捕获 API 的首选项。默认值为 CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开

 cv::VideoCapture::VideoCapture(const String &filename, int apiPreference, const std::vector<int> &params);

功能: 

         打开视频文件或捕获摄像头设备或IP视频流(网络传输视频流),默认使用API首选项(CAP_ANY)进行视频捕获

参数:       

        filename要打开的视频文件名、捕获设备的索引号(一般为0表示默认摄像头),或者是 IP 视频流地址

        apiPreference可选参数,用于指定视频捕获 API 的首选项。默认值为 CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开

        params:可选不定参数,以向底层视频捕获库传递附加的特定参数

例如:

       

 cv::VideoCapture cap("video.mp4", cv::CAP_FFMPEG, {cv::CAP_PROP_FRAME_WIDTH, 640, cv::CAP_PROP_FRAME_HEIGHT, 480});

        在此示例中,传递了一组参数来设置所捕获视频帧的宽度和高度。使用了 cv::CAP_PROP_FRAME_WIDTHcv::CAP_PROP_FRAME_HEIGHT,这些常量表示帧的宽度和高度属性,然后将期望的值分别设置为 640 和 480。这意味着设置了捕获的每个视频帧的宽度为 640 像素,高度为 480 像素。

 cv::VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY);

功能:

         打开摄像机进行视频捕获

参数:

        index:捕获设备的索引号,用于指定要打开的特定设备。通常情况下,0 表示默认摄像头,1 表示第二个摄像头,以此类推。如果你的系统上有多个摄像头或其他捕获设备,可以通过指定不同的索引号来选择打开哪个设备

        apiPreference可选参数,用于指定视频捕获 API 的首选项。默认值为 CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开

cv::VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY,  int apiPreference, const std::vector<int> &params); 

功能:

        使用API首选项和不定参数打开摄像机进行视频捕获。

参数:      

        index:捕获设备的索引号,用于指定要打开的特定设备。通常情况下,0 表示默认摄像头,1 表示第二个摄像头,以此类推。如果你的系统上有多个摄像头或其他捕获设备,可以通过指定不同的索引号来选择打开哪个设备

        apiPreference可选参数,用于指定视频捕获 API 的首选项。默认值为 CAP_ANY,表示尝试使用任何可用的视频捕获 API 来打开

        params:可选不定参数,以向底层视频捕获库传递附加的特定参数

参考文档:

OpenCV: Image file reading and writing

OpenCV: High-level GUI

OpenCV: cv::VideoCapture Class Reference

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

千帆 AppBuilder 初体验,不仅解决解决了我筛选简历的痛苦,更是让提效10倍!

文章目录 &#x1f31f; 前言&#x1f31f; 什么是百度智能云千帆 AppBuilder&#x1f31f; 百度智能云千帆 AppBuilder 初体验&#x1f31f; 利用千帆AppBuilder搭建简历小助手&#x1f31f; 让人眼前一亮的神兵利器 - 超级助理 &#x1f31f; 前言 前两天朋友 三掌柜 去北京…

PostGIS学习教程十四:更多的空间连接

PostGIS学习教程十四&#xff1a;更多的空间连接 在上一节中&#xff0c;我们看到了ST_Centroid(geometry)和ST_Union([geometry])函数&#xff0c;以及一些简单的示例。在本节中&#xff0c;我们将用它们做一些更详细的事情。 提示&#xff1a;写完文章后&#xff0c;目录可以…

Jmeter 性能 —— 监控服务器!

Jmeter监控Linux需要三个文件 JMeterPlugins-Extras.jar (包&#xff1a;JMeterPlugins-Extras-1.4.0.zip)JMeterPlugins-Standard.jar (包&#xff1a;JMeterPlugins-Standard-1.4.0.zip)ServerAgent-2.2.3.zip 1、Jemter 安装插件 在插件管理中心的搜索Servers Performan…

MySQL运维实战(1.2)安装部署:使用二进制安装部署

作者&#xff1a;俊达 引言 上一篇我们使用了RPM进行安装部署&#xff0c;这是一种安装快速、简化部署和管理过程、与操作系统提供的包管理工具紧密集成的部署方法。此外&#xff0c;当你需要更高的灵活性和自定义性&#xff0c;并且愿意承担一些额外的手动配置和管理工作&am…

HBuilderX项目配置使用uview

配置uview&#xff0c;先安装再配置 如果没有package.json文件&#xff0c;先打开终端&#xff0c;执行命令 npm init -y 然后就会生成 package.json 安装 使用npm安装uview npm install uview-ui2.0.36 安装好之后&#xff0c;可以看到package.json里面已经显示版本了 查…

Unity中Shader旋转矩阵(四维旋转矩阵)

文章目录 前言一、围绕X轴旋转1、可以使用上篇文章中&#xff0c;同样的方法推导得出围绕X轴旋转的点阵。2、求M~rotate~ 二、围绕Y轴旋转1、可以使用上篇文章中&#xff0c;同样的方法推导得出围绕Y轴旋转的点阵。2、求M~rotate~ 三、围绕Z轴旋转1、可以使用上篇文章中&#x…

2000+线下门店数字化转型,盘活近500+门店账号!

伴随着社交媒体的快速发展&#xff0c;消费者的注意力开始往线上转移。社交媒体在消费者购买决策过程中发挥着越来越重要的作用&#xff0c;逐渐成为大家获取信息、产品种草并购买下单的平台。 今年双十一期间&#xff0c;抖音商城多数品类销售额均呈现大幅增长趋势&#xff0c…

MPI安装与程序设计

MPI MPI&#xff08;Message Passing Interface&#xff09;是一种用于编写并行程序的标准和库&#xff0c;用于在分布式内存系统中进行消息传递和并行计算。MPI提供了一组函数和语义&#xff0c;用于在多个进程之间进行通信和同步&#xff0c;以实现并行计算和并行任务的协调…

ASP.Net实现姓名添加查询(三层架构)

目录 演示功能&#xff1a; 点击启动生成页面 点击搜索模糊查询 点击添加跳转新界面 点击Button添加姓名 步骤&#xff1a; 1、建文件 2、添加引用关系 3、根据数据库中的列写Models下的XueshengModels类 4、DAL下的DBHelper&#xff08;对数据库进行操作&#xff09;…

现代 CPU 技术发展

介绍 这篇文章主要是介绍CPU技术的发展&#xff0c;包括最近几十年CPU性能提升和半导体工艺发展&#xff0c;当前技术发展方向。希望可以帮助软件开发者理解CPU指令集和组成运行原理、CPU性能提升的现状和瓶颈、CPU技术发展方向会如何影响软件开发/设计的框架和编程思想。 提示…

HTML---盒子模型

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.盒子模型概述 HTML中的盒子模型是一种用于描述和布局元素的概念。每个 HTML 元素都可以被表示为一个矩形的盒子&#xff0c;这个盒子包括四个部分&#xff1a;内容区域、内边距、边框和外边距…

【计算机系统结构实验】实验5 多核编程(OpenMP编程)

5.1 实验目的 加深对多核处理器架构的理解&#xff1b; 掌握使用OpenMP进行多线程编程的基本方法&#xff1b; 学习Windows和OpenEuler环境下多核编程的过程和time命令&#xff1b; 5.2 实验平台 需要多核处理器的计算机和微软编程工具Visual Studio 2012。Taishan服务器&…

互联网加竞赛 python图像检索系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python图像检索系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c…

JDBC学习,从入门到入土

JDBC引入 JDBC概念&#xff1a; JDBC是使用Java语言操作关系型数据库的一套API。全称&#xff1a;&#xff08;Java DataBase Connectivity&#xff09;Java数据库连接 JDBC的本质&#xff1a; 官方定义的一套操作所有关系型数据库的规则&#xff0c;即接口。 各个数据库厂…

C# WPF上位机开发(业务主流程才是核心)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说了很多的c# wpf编程技术&#xff0c;里面有控件&#xff0c;有绘图&#xff0c;有数据库&#xff0c;有多线程等技术。但是他们都属于实…

数据结构之进阶二叉树(二叉搜索树和AVL树、红黑树的实现)超详细解析,附实操图和搜索二叉树的实现过程图

绪论​ “生命有如铁砧&#xff0c;愈被敲打&#xff0c;愈能发出火花。——伽利略”&#xff1b;本章主要是数据结构 二叉树的进阶知识&#xff0c;若之前没学过二叉树建议看看这篇文章一篇掌握二叉树&#xff0c;本章的知识从浅到深的对搜索二叉树的使用进行了介绍和对其底层…

数据结构 | 查漏补缺

目录 数据的基本单位 冒泡排序 DFS和BFS中文 Prim 比较 中序线索二叉树 顺序栈 链栈 时间复杂度 循环队列 求第K个结点的值 数据的基本单位 数据元素 循环队列sq中&#xff0c;用数组elem[0‥25]存放数据元素&#xff0c;设当前sq->front为20&#xff0c;sq-&g…

MySQL——内置函数

目录 一.日期函数 1.current_date() 2.current_time() 3.current_stamp() 4.date_add() 5.date_sub() 6.datediff 7.date 8.now 二.字符串函数 1.charset() 2.concat() 3.length() 4.replace 5.substring(str,postion,length) 6.instr&#xff08;string,substr…

零代码助力服装行业数字化转型

内容来自演讲&#xff1a;涂岳俊 | 广州市衣湛国际信息科技有限公司 | CEO 摘要 这篇文章讨论了为什么选择明道云零代码平台&#xff0c;以及它如何帮助服装企业解决各种问题。作者分享了自己的经验&#xff0c;并列举了一些成功的案例来证明零代码平台的优势。文章还提到了在…

[Unity错误解决]There are 2 audio listeners in the scene.

There are 2 audio listeners in the scene. Please ensure there is always exactly one audio listener in the scene. 从组件中找出包含 Audio Listener 的&#xff0c;只激活一个&#xff0c;其他的关掉