【重明】机器视觉QT/C++实现工业相机二次开发框架

工业相机二次开发是机器视觉行业必不可少的技能之一。
而如何实现一个框架,能够兼容所有工业相机二次开发,从而支持多种类型的工业相机,就是机器视觉行业的进阶技能了。
请添加图片描述
重明工业相机二次开发项目就是在实现相机二开框架的基础上,完成了海康工业相机的二次开发。
项目源码下载地址:
https://www.roundvision.cc/softwaredevelopment/qt/chongming/
技术栈:
1、C++
2、 QT 5.14.2
3、Opencv 4.5.5
4、工业相机SDK二次开发
重明工业相机二次开发项目框架如下图所示:
在这里插入图片描述
整个项目分前端部分的界面设计,和后端部分的工业相机框架设计。

1、界面GUI实现

重明的界面实现非常简洁,主要为三个部分:
左侧的相机列表,中间的图像显示,右侧的相机参数属性列表。
在这里插入图片描述
控制窗口的实现非常简单,其实就是一排按钮加一个QListWidget列表,用来显示所有检测到的工业相机。
视觉窗口用来显示图像,采用QT的视图模型框架,采用QGrapicsScene来实现的。
属性窗口主要涉及到了QT的MVD框架,即Model-View-Delegate框架,模型-视图-代理,通过视图代理,完成了对各个不同属性参数类型的支持,完成了相机参数属性Int,double,bool,cmd,string等多种类型的显示。

2、后端框架接口

实现了前端界面,现在我们可以考虑,如何抽象工业相机接口类,实现对不同工业相机的无差别接入,达到工业相机二次开发框架的效果呢?
这里可以借用QT插件的便利性,来设计工业相机抽象插件接口:

 //相机接口类
class CameraInterface
{
public:CameraInterface(const CameraMetaInfo& info){m_cameraInfo = info;}virtual ~CameraInterface() {}//获取相机用户定义名称virtual std::string UserName(){return m_cameraInfo.UserDefineID;}//获取相机序列号virtual std::string Serial(){return m_cameraInfo.Serial;}//获取相机参数列表virtual uint32_t getParamList(std::vector<CameraParam>& paramList) = 0;//判断相机是否连接virtual bool isConnect() = 0;//判断相机是否拉流virtual bool isGrabbing() = 0;//初始化相机对象virtual uint32_t acquire() = 0;//释放相机virtual uint32_t release() = 0;//连接相机virtual uint32_t connect() = 0;//断开连接virtual uint32_t disconnect() = 0;//创建拉流资源virtual uint32_t creatStream() = 0;//销毁拉流资源virtual uint32_t destroyStream() = 0;//开启拉流virtual uint32_t startGrabbing() = 0;//停止拉流virtual uint32_t stopGrabbing() = 0;//导入配置文件virtual uint32_t loadConfig(const std::string path) = 0;//导出配置文件virtual uint32_t saveConfig(const std::string path) = 0;//获取配置文件格式virtual std::string configFormat() = 0;//读取相机参数virtual uint32_t readParam(CameraParam& param) = 0;//写入相机参数virtual uint32_t writeParam(CameraParam& param) = 0;//获取实时图像virtual uint32_t getImageLast(cv::Mat& image) = 0;//获取图像队列virtual CameraImageQueue& ImageQueue(){return m_imageQueue;}protected:CameraImageQueue m_imageQueue;//图像队列std::vector<CameraParam> m_cameraParams;//相机参数列表CameraMetaInfo m_cameraInfo;//相机元信息
};

通过抽象设计统一的相机行为接口,在通过层层封装,即可达到框架效果。

如何实现相机图像队列

相机出图速度是有差异的,而我们处理相机出图也会有所耗时,如果你是出一张图像处理一张,然后再去拿一张图像,那很容易造成丢帧的问题。所以设计一个缓冲队列是非常有必要的。

我们的图像队列内部会包含两个队列,一个空闲队列,一个工作队列。
在我们相机图像队列这个应用场景下,生产者就是相机SDK的回调函数,该回调函数会生成相机的原始图像数据,我们在回调函数内将原始图像数据加入到队列中。
加入到队列是先看空闲队列有没有位置,如果有则加入到空闲队列,然后触发信号量激活消费者。如果空闲队列没有位置,则从工作队列取出最旧的图像,将原始数据加入到该位置。
我们的消费者,就是我们的取图线程,我们软件会不停的从队列中的工作队列中尝试取出图像,当工作队列为空时,会阻塞在信号量中,当生产者生产了一张图像后,会激活该信号量使取图线程取到图像。
图像队列代码实现:


#define TIME_OUT_MS		5000	//取图超时时间
#define ImageQueueSize	10		//图像队列长度宏定义class CameraImageQueue
{
public:CameraImageQueue();CameraImageQueue(int maxSize);//向图像队列中加入图像uint32_t Put(const cv::Mat& m);//从图像队列中取出图像uint32_t Take(cv::Mat& m);//队列是否为空bool Empty();//队列是否为满bool Full();//队列当前长度size_t Size();
private:bool isFull() const{bool full = workImageQueue.size() >= m_queueSize;return full;}bool isEmpty() const{bool empty = workImageQueue.empty();return empty;}bool NotFull() const{bool full = workImageQueue.size() >= m_queueSize;return !full;}bool NotEmpty() const{bool empty = workImageQueue.empty();return !empty;}private:std::mutex m_mutex;std::condition_variable m_condition;std::queue<cv::Mat> freeImageQueue;//空闲队列std::queue<cv::Mat> workImageQueue;//工作队列uint8_t m_queueSize;bool m_needStop;
};

THE END

项目源码下载地址:
https://www.roundvision.cc/softwaredevelopment/qt/chongming/
项目由丰富的视频教程,见BiliBili:
在这里插入图片描述
视频链接:https://www.bilibili.com/video/BV1pp4y1n7X9

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

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

相关文章

解决方案:reactNative通过webview跳转微信智能客服空白webview页面

在reactNative中使用webview跳转微信智能客服&#xff0c;功能正常&#xff0c;从微信退回到App时&#xff0c;会有一个空白的webview页面&#xff0c;在使用感觉上不是那么的顺滑。解决这个可以在webview中使用onLoadEnd方法来解决这个问题 在react-native-webview中onLoadEn…

计算机视觉开发工程师怎么考?报考难度大吗?证书含金量高吗?

为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署要求&#xff0c;深入实施人才强国战略和创新驱动发展战略&#xff0c;加强全国数字化人才队伍建设&#xff0c;持续推进人工智能专业人员…

Android 事件机制探讨(1)

事件的传递主要有三个方法&#xff1a;dispatchTouchEvent(事件分发)、onInterceptTouchEvent(事件拦截)、onTouchEvent(事件消费)。如下图&#xff1a; 仔细看的话&#xff0c;图分为3层&#xff0c;从上往下依次是Activity、ViewGroup、View事件从左上角那个白色箭头开始&…

缓存穿透、缓存击穿、缓存雪崩以及解决方案

Java面试题 缓存穿透 缓存中和数据库中都没有数据被大量请求&#xff0c;这些请求直接穿透到数据库中&#xff0c;失去了缓存层存在的意义&#xff0c;导致数据库压力过大。 解决方案&#xff1a; 1.数据库中获取不到数据时&#xff0c;将null值放入到缓存中。Redis缓存中可以…

【IC前端虚拟项目】MVU子模块DS文档编写与注意事项

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 DS文档顾名思义就是Design Specification,设计规格文档,对应的就是我们实际一个模块的设计思路和细节: DS - Design Specification(设计规格):"DS" 表示设计规格,它是在架构规格之后,…

法规更新美国玩具标准ASTM F963-17有更新,最新标准为ASTM F963-23

美国材料试验协会 (ASTM)在10月13日发布了新的玩具安全标准&#xff1a;ASTM F963-23&#xff0c;ASTM F963-17美国联邦法规16 CFR 1250还在使用当中&#xff0c;出口美国的玩具的厂商要引起重视。 ASTM F963-17是什么标准&#xff1f; ASTM F963-17是美国玩具检测标准&#…

Java基于SpringBoot+Vue的大学生入学审核系统的设计与开发,附源码、数据库

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

npm包管理工具

npm包管理工具 npm简介npm环境搭建npm命令npm包管理npm package.jsonnpm依赖管理npm脚本管理npm全局包npm 配置npm仓库npm私有包

FMEA软件——如何实现FMEA预期质量目标?

免费试用FMEA软件-免费版-SunFMEA ​为了确保FMEA的有效实施并实现预期的质量目标&#xff0c;可以从以下几点进行&#xff1a; 1. 明确目标和范围&#xff1a;在开始FMEA分析之前&#xff0c;明确界定项目的目标和范围。这有助于确定关注的重点&#xff0c;并为后续的分析工…

JavaScript实现拖拽

JavaScript实现拖拽 使用mousedown, mousemove, mouseup事件 mousedown事件触发后&#xff0c;开始拖拽 mousemove时&#xff0c;需要通过event.clientX和clientY获取拖拽位置&#xff0c;并实时更新位置 mouseup时&#xff0c;拖拽结束 <!DOCTYPE html> <html lang&q…

NFS网络共享存储服务技术攻略

目录 一.NFS 1.定义 2.特点 3.原理 二.服务端NFS配置文件 1.主配置文件 2.文件格式 3.相关命令 三.实验&#xff1a;NFS共享存储服务配置 1.服务端安装nfs-utils和rpcbind软件包 2.服务端新建共享目录给权限 3.服务端修改配置文件/etc/exports 4.服务端关闭防火墙…

C#开源免费的Blazor图表库

前言 今天分享一款基于ApexCharts.js封装的、C#开源免费的Blazor图表库&#xff1a;Blazor-ApexCharts。 10款值得推荐的Blazor UI组件库 全面的ASP.NET Core Blazor简介和快速入门 ApexCharts.js介绍 ApexCharts.js开源地址&#xff1a;GitHub - apexcharts/apexcharts.js:…

python.24.1.16函数

python自带函数 自定义函数 参数的使用

Java工具类——json字符串格式化处理

在我们拿到一团未经格式化的json字符串时&#xff0c;非常不方便查看&#xff0c;比如这样 {"APP_HEAD": {"TOTAL_NUM": "-1","PGUP_OR_PGDN": "0"},"SYS_HEAD": {"RET": [{"RET_CODE": &qu…

如何做用户分层和标签体系

“活动作了一场接一场&#xff0c;简直要累死了&#xff0c;拉进来的客户也没有多少&#xff0c;投入产出完全不成比例&#xff0c;怎么办&#xff1f;“ “有那么多注册用户&#xff0c;但是GMV怎么才这么点&#xff0c;他们怎么不买啊&#xff0c;难道都是羊毛党&#xff1f;…

使用python计算两个日期之前的相差天数,周数

在Python中&#xff0c;你可以使用datetime模块来计算两个日期之间相差的天数和周数。示例代码&#xff1a; from datetime import datetime# 定义两个日期字符串 date_string1 2023-01-01 date_string2 2023-03-01# 将日期字符串转换为datetime对象 date_format %Y-%m-%d …

el-select中多选回显数据后没法重新选择和更改

<el-form-item label"展示内容" prop"videoId"><el-select class"modal-input" multiple v-model"form.videoId"><el-optionclass"modal-input"v-for"(item) in videoIdTypes":key"item.id&q…

JAVA代码学习(先识)

2023年将会持续于B站、CSDN等各大平台更新&#xff0c;可加入粉丝群与博主交流:838681355&#xff0c;为了老板大G共同努力。 【商务合作请私信或进群联系群主】 环境变量设置 a. 下载安装包 因为Java程序必须运行在JVM之上&#xff0c;所以&#xff0c;第一件事情就是安装J…

Java面试题116-125

116、JSP和Servlet有哪些相同点和不同点&#xff0c;他们之间的联系是什么&#xff1f; JSP是Servlet技术的扩展&#xff0c;本质上是Servlet的简易方式&#xff0c;更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于&#xff0c;Ser…

2019年认证杯SPSSPRO杯数学建模D题(第二阶段)5G时代引发的道路规划革命全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 D题 5G时代引发的道路规划革命 原题再现&#xff1a; 忙着回家或上班的司机们都知道交通堵塞既浪费时间又浪费燃料&#xff0c;甚至有的时候会带来情绪上的巨大影响&#xff0c;引发一系列的交通问题。据报道&#xff0c;每年交通拥堵使得美国…