Forever忠
技术员
技术员
  • 最后登录2020-10-19
  • 发帖数39
  • 金币363枚
  • 贡献勋章0枚
  • 社区居民
阅读:194回复:11

机器视觉软件开发完整过程记录——第二段

楼主#
更多 发布于:2020-10-16 15:41
        第二阶段我开始子模块开发,顾名思义,所谓模块,一定要脱离主程序,封装成库或者插件,给主程序提供接口和使用文档,同时要给该模块配备对应的DEMO程序。很多程序员为了偷懒,都是在主程序加几个类,就说这是自己的一个模块,内行看门道外行看热闹,一旦我看见程序里有耦合性强的功能性类,我就一个想法,把它干掉,因为如果类扩展性差,就污染了主程序。所以,宁愿晚几天完成,也不要匆匆交差,程序员都必须要有强迫症的特征,这样方便自己也方便后人维护,代码可读性更强,复用性强,扩展性更强,我一直认为可读性强的代码才是优质代码,不要写别人看不懂的东西,因为时间久了,你自己也看不明白。

        我参与过百万行级别代码的开发,和十几个人一起合作开发过一个视觉软件;也见到过几个小几万行级别的视觉软件,一两个人维护;也完全独立开发过完整的视觉软件。给我最大的体验就是,代码量大的软件,如果模块分明架构清晰,一样可以完全理解;代码量小的软件,如果界面和逻辑杂糅、算法和软件杂糅、没有模块概念,就算几千行也看不明白,因为你根本一行也不想看,逻辑全靠猜,夸张的说,看着都反胃。。。建议大家多去GitHub上看看评分较高的代码,养成好的个人习惯,为了自己也为了战友!
       我的第二阶段大概也是一个月的时间,有兴趣的朋友可以看看上篇文章:

       上篇文章《机器视觉软件开发完整过程记录-第一段》链接如下:http://www.ihalcon.com/read-15737.html
       第一阶段结尾我提到了,第二阶段计划完成绘图模块、相机模块、通信模块、图像保存模块。
  • 绘图模块:视觉软件中有一些绘制ROI和显示绘图结果等操作,例如halcon中的draw系列和show系列算子,为了软件的灵活性和后期脱离halcon库运行,我放弃了halcon自身所带的绘图函数及显示窗口,采用QT封装一个绘图模块。整个模块我创建了三个基类:鼠标操作基类、基础图形绘制类、基础图形显示类。其中鼠标操作子类:图形移动子类、图形拉动子类、图形旋转子类;基础图形绘制子类:绘制矩形、绘制圆形、绘制椭圆、绘制多边形、绘制圆环、绘制扇形等检测ROI的绘制子类;基础图形显示子类:显示点、线、圆、矩形、多边形、波形图等图像上需要显示的检测结果辅助绘图。
  • 相机模块:相机模块我采用了经典的工厂模式,设计了一个相机操作基类:主要定义了设置曝光、设置增益、读取帧率、设置ROI等相机的基本操作,子类就是不同相机SDK对基类抽象接口的一个实现。界面主程序通过单例的模式访问具体类型的相机类,从而实现相机的访问和参数设置。这里有几个特殊的地方,一个就是面阵相机的触发模式,一个就是面阵相机和线阵相机的区别。
  •        面阵相机触发分为软触发和硬触发,其中软触发就是通过相机SDK发送触发指令,从而相机拍照。这种方式不用外接线,操作简单,但是不适合飞拍;硬触发是客户通过IO直接触发相机,软件通过回调函数获取图片。这种方式适合飞拍,但是得外接线,一般5V电压,所以具体情况具体对待。
  •        线阵相机有帧触发和线触发两个概念,帧触发指图像开始合成,线触发指一行图片的触发,一般我们会设置一个图像高度,当帧触发开始,图像线触发达到该图像高度的时候,相机会返回一张图片。当然帧触发和线触发也可以采用内部触发和外部触发,这里只介绍外触发,帧触发需要接5V电压,上升沿或下降沿触发;线触发需要接编码器AB项,如果不考虑点击方向,可以只接一相,例如A+和A-
  •      相机出来的图像一般是裸指针,我们需要将它转换Hobject处理,QImage显示,前面写过一篇文章《分享相机buffer、Hobject、QImage的转换问题》链接如下:http://www.ihalcon.com/read-15719.html
  • 通信模块:通信包括TCP/IP无协议客户端/服务器、串口无协议、Modbus、EIP、FINS等,这里由于项目进度原因,我先开发廖TCP/IP无协议服务器和自定义的通信协议,前面写过一篇文章分享QT开发TCP/IP服务器模块相关问题(源码公开》链接如下:http://www.ihalcon.com/read-15754.html
  •       这里不重复叙述,不过通信一般是最不可靠的部分,都会存在沾报、掉报、阻塞假死等各种问题,有兴趣的朋友可以交流下。
  • 图像保存模块:这个模块相对比较简单,没有太多的设计模式,只提一点,就是我加入了图像队列缓存的机制,并将图像保存线程的优先程度调低,这样既可以不影响取图和运算的时间,也可以保证在机台空闲的时候保存缓存队列的图片,不至于丢图。后期还需要做图像复测和MES系统传输,提前做好准备。

      总结:
      这个月,我开发了三个模块,以库的形式给到主程序集成,并对三个模块开发了接口文档和库配套的DEMO界面。在开发过程中,我也有过偷懒的想法,例如直接在主程序写一个集成QTcpServer的子类来实现服务器通信就完事了,一天就可以搞定,但是这样以后我的通信一旦有掉报沾报等问题,就很难在出程序定位。所以我以牺牲项目进度的代价,选择了封装成单独模块,并配上服务器测试程序。这样逻辑清晰,后期出问题也方便脱离主程序进行测试维护。好了,下个月见,期待自己的《机器视觉软件开发完整过程记录——第三段》,第三段计划完成:算法运行架构、工具类型定义、预处理模块。加油中年~
喜欢2

最新打赏:0人

wbazwsd
技术员
技术员
  • 最后登录2020-10-16
  • 发帖数362
  • 金币490枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
沙发#
发布于:2020-10-16 15:46
膜拜大佬啊,学习学习
sanor
初学者
初学者
  • 最后登录2020-10-16
  • 发帖数94
  • 金币84枚
  • 贡献勋章0枚
  • 社区居民
板凳#
发布于:2020-10-16 23:04
嗯,学习学习,值得推广
sc6231565
管理员
管理员
  • 最后登录2020-10-18
  • 发帖数1078
  • 金币25842枚
  • 贡献勋章0枚
  • 社区明星
  • 最爱沙发
  • 原创写手
  • 喜欢达人
  • 忠实会员
  • 社区居民
地板#
发布于:2020-10-16 23:10
都会存在沾报、掉报、主要可以是通过增加结束符,读取信息的边界,就可以避免
      阻塞假死等各种问题,当对方已经下线,还一直发,会存在这个问题,需要每次发送下判断socket是否有效
qawwss56
技术员
技术员
  • 最后登录2020-10-17
  • 发帖数331
  • 金币533枚
  • 贡献勋章0枚
  • 社区居民
4楼#
发布于:2020-10-17 09:38
嗯,学习学习,值得推广
caicai1001
技术员
技术员
  • 最后登录2020-10-19
  • 发帖数356
  • 金币987枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
5楼#
发布于:2020-10-17 12:33
嗯,学习学习,值得推广
gzc633
初学者
初学者
  • 最后登录2020-10-19
  • 发帖数158
  • 金币9枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
6楼#
发布于:2020-10-17 13:12
厉害了,向大神学习。
gzc633
初学者
初学者
  • 最后登录2020-10-19
  • 发帖数158
  • 金币9枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
7楼#
发布于:2020-10-17 13:25
学习下,思路~~~~~~~~~~~~~~~~~~~~~~~~
Mediation
高级工程师
高级工程师
  • 最后登录2020-10-19
  • 发帖数1229
  • 金币7791枚
  • 贡献勋章2枚
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 追星一族
8楼#
发布于:2020-10-17 16:37
学习学习,多谢楼主分享经验,受益匪浅
_____Jiang
技术员
技术员
  • 最后登录2020-10-18
  • 发帖数82
  • 金币131枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
9楼#
发布于:2020-10-18 10:37
骚年,请让我加入你!!!
214877973
技术员
技术员
  • 最后登录2020-10-19
  • 发帖数141
  • 金币294枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
10楼#
发布于:2020-10-18 11:55
mark,持续关注。
walkersir
高级工程师
高级工程师
  • 最后登录2020-10-20
  • 发帖数90
  • 金币5897枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
11楼#
发布于:2020-10-19 16:18
学习,持续关注。。。。
多年视觉平台框架,算法研发
游客

返回顶部
支付

欢迎打赏,请选择打赏金额

  • 1元
  • 6元
  • 10元
  • 66元
  • 100元

支付即代表同意《本站支付协议》 有疑问请联系客服