怎么在wordpress上设计网站,wordpress 两个用户名,WordPress如何清空评论,网站开发设计各部门职责工业相机二次开发是机器视觉行业必不可少的技能之一。 而如何实现一个框架#xff0c;能够兼容所有工业相机二次开发#xff0c;从而支持多种类型的工业相机#xff0c;就是机器视觉行业的进阶技能了。 重明工业相机二次开发项目就是在实现相机二开框架的基础上#xff0c…工业相机二次开发是机器视觉行业必不可少的技能之一。 而如何实现一个框架能够兼容所有工业相机二次开发从而支持多种类型的工业相机就是机器视觉行业的进阶技能了。 重明工业相机二次开发项目就是在实现相机二开框架的基础上完成了海康工业相机的二次开发。 项目源码下载地址 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::vectorCameraParam 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::vectorCameraParam 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::queuecv::Mat freeImageQueue;//空闲队列std::queuecv::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