基于 STM32 的新型激光测距控制系统的设计

基于 STM32 的新型激光测距控制系统的设计

闵小
(陕西理工大学(物理与电信工程学院)电子专业1502班,陕西 汉中 723003)
指导老师:韩团军

[摘要] 设计了一种基于STM32的摄像头与DT50激光传感器联合控制的精确距离测量系统。该系统基于DT50 的数字显示界面,通过图像处理技术对摄像头的图像进行检测、匹配与识别,实现了一般控制系统关于距离的零误差测量。经实际测试,该系统具有测量精度高,性能稳定,实时性强等特点,具有很高的使用价值和推广价值。
[关键词] 测距控制; DT50; CMOS 摄像头;图像分割与识别; STM32

Design of a new laser ranging control system based on STM32

Min Xiao
(Grade15,Class 2 ,Major Electronics,School of Physics and Telecommunication Engineering of Shaanxi University of Technology, Hanzhong 723003,China)
Tutor: Han Tuan Jun

Abstract:This paper, a STM32 based on the camera and DT50 laser sensor that are combined to control the precise distance measurement system is designed. The digital display interface system based on DT50, detection, matching and recognition of camera images by image processing technology, accomplish the control system on the zero-error measurement of the distance. Through the strict experiment, the system has the characteristics of high measurement precision, stable performance and strong real-time, and has high value of use and popularization.
Key words:Distance control; DT50; CMOS Camera; Image Segmentation and recognition; STM32

1. 绪论

1.1 本文研究背景与意义

自从1960年,人类第一台红宝石激光器诞生以来,激光就十分广泛的应用在检测领域。其中激光测距是激光最早的应用之一。较普通光而言,激光有很多优势。较强的方向性使激光在发出后几乎是一条平行的光线,这是将其应用于测距工作的基础。同时,激光的亮度非常高,被称之为“最亮的光”。此外,激光是最好的单色光源,这也是激光在光谱技术及光学测量中得到广泛应用的原因。激光的发展和应用不仅对光学领域的理论革新产生了巨大的影响,同时也对现代工业中的技术创新工作奠定了重要的基础。激光测距(laser distance measuring)是以激光器作为光源进行测距。根据激光工作的方式分为连续激光器和脉冲激光器。氦氖、氩离子、氪镉等气体激光器工作于连续输出状态,用于相位式激光测距;双异质砷化镓半导体激光器,用于红外测距;红宝石、钕玻璃等固体激光器,用于脉冲式激光测距。由于激光所具有的高亮度、高方向性、高单色性等特性,使得激光很快就应用于各类测量领域[1-3]。激光测距仪具有其他测距仪无法比拟的优点。正因为如此,激光测距仪自问世以来得到了迅速发展。现在它已经发展到第五代并且生产了很多种。此外,它正朝着小型化和智能化的方向发展。激光测距仪为实现快速,非接触式距离测量的毫米级精度带来了新的革命。随着微电子技术的发展,电路部分趋于集成和数字化,极大地提高了系统的可靠性。与光电测距仪相比,它不仅可以日夜工作,还可以提高测距精度,显着降低质量和功耗,使人造地球卫星和月球等远程目标的距离测量成为现实。
回顾激光测距仪的发展历程,人们会发现随着技术的不断革新和逬步,这类产品的功能越来越强大。除了自动化、集成化程度明显提升之外,测量的精度也越来越高。此外,仪器操作起来相对简便,能够实现测量数据的实时获取,具有较高的实用性。目前,这类仪器已经走出军用及科研领域,在工业产业中得到了较为广泛的应用,创造出了巨大的价值。在诸如油田勘测、铁路建设等比较特殊的作业环境领域,如果测距仪的体积、重量太大,携带起来非常不方便,会给工作人员带来负担。同时,随着工业经济的逬一步发展,各个行业对工作效率逐渐有了新的认识。对于测距工作来说,人们希望能够以更快的速度获得更加精准的测量结果,且测量过程要尽可能减少对人工的依赖。同时在恶劣的外界环境下,激光测距仪依旧能够正常工作,且具备较高的自动化水平,操作起来将更加容易。
随着近些年激光技术的不断发展,使得激光测距技术无论在军事应用方面,还是在科学技术、生产建设方面,都显得尤为重要。由其所组成的更具自动化的激光测距控制系统对当今的社会生产和生活领域更是产生了十分明显的影响。因此,对新型激光测距控制系统的开发不仅具有很重要的研究意义,而且还具备很高的实际应用价值以及推广价值。

1.2 论文主要工作

本文所设计的新型激光测距控制系统是基于德国SICK公司生产的中量程DT50激光测距传感器,其能够提供80mm到5000mm的感应量程,能够对不同材质和颜色的物体可靠地测量,适用于非常宽泛的应用现场,如运动物体位置检测、工业自动化和生产智能管理、工业监控信号触发控制、汽车安全车距测量等。其内部有一个LED显示屏,用来显示测量的数据,这个数据显示只有观察者能看到,因而要想使计算机得到这个数据,就需要设计测量控制系统及接口。
传统的测量控制系统会通过采集DT50的电流信号,经过A/D转换后,再经过一系列的数字信号处理如中值滤波、卡尔曼滤波等方式来去除噪声信号,算法处理较为复杂,最终得到处理后的数字量也很难与真实数字量完全相等,往往会存在一定偏差。针对上述不足,提出了一种摄像头图像识别LED屏的数字量的测量方法,该方法算法较为简单,能充分的发挥摄像头的识别功能,适用于静止、低速和中高速控制系统。最终能够准确的得到当前物体的真实距离,并将数据通过串口传送至计算机端,方便设计者对数据的读取与后续处理。

2. 系统方案设计

本系统主体硬件方面由OV7725摄像头模块、DT50激光传感器模块、RS232串口模块以及SD卡模块所组成,其中摄像头用来识别DT50上LED屏上的数字量,并通过RS232串口模块远程传输到计算机客户端实现测距信息的实时显示,而SD卡负责保存程序代码、摄像头图像以及相关数据。软件方面采用MicroPython系统可以通过Python脚本语言开发单片机程序,同时使用Opencv3.4.3以及其他图像处理库,可以缩短系统开发时间,提高系统开发效率。
通过以上硬件与软件的结合共同组成了激光测距控制系统的整体结构,并能够实现对测距数据的精准识别以及远程传输功能。系统基本结构组成如图2.1所示。
在这里插入图片描述

图2.1 系统基本结构

2.1 硬件介绍

本文采用OpenMV[4]摄像头模组,DT50激光传感器以及HC-05蓝牙模块等设计硬件电路。本小节旨在介绍以上几种硬件功能。
OpenMV摄像头模组是一款小巧,低功耗,低成本的电路板。该模组采用STM32F765VI ARM Cortex M7 处理器,并提供μSD卡槽以及OV7725感光元件。通过移植MicroPython[5]操作系统到处理器上,使得处理器不仅能够支持Python语言对硬件资源的控制,而且还能利用Python的高级数据结构实现复杂的机器视觉算法。采用该模组能够大幅度减少本系统的整体电路设计。OpenMV摄像头模组如图2.2所示。

在这里插入图片描述

图2.2 OpenMV摄像头模组
如图2.3所示,DT50激光传感器是德国SICK公司生产的中量程DT50激光测距传感器,其能够提供80mm到5000mm的感应量程,能够对不同材质和颜色的物体可靠地测量,适用于非常宽泛的应用现场,如运动物体位置检测、工业自动化和生产智能管理、工业监控信号触发控制、汽车安全车距测量等。其内部有一个LED显示屏,用来显示测量的数据。 如图2.4所示,HC-05蓝牙模块是主从一体的蓝牙串口模块,简单的说,当蓝牙设备与蓝牙设备配对连接成功后,我们可以忽视蓝牙内部的通信协议,直接将将蓝牙当做串口用。当建立连接,两设备共同使用一通道也就是同一个串口,一个设备发送数据到通道中,另外一个设备便可以接收通道中的数据。

在这里插入图片描述

图2.3 DT50激光传感器           图2.4 HC-05蓝牙模块

2.2 硬件设计

本系统的设计核心是通过摄像头识别DT50激光传感器上的LED屏幕显示的数字量,并将识别结果通过蓝牙发送至远程终端。首先将DT50传感器LED屏幕水平向上放置,然后固定OpenMV摄像头模组于DT50传感器LED屏幕上方合适高度,使得图像能够清晰可见即可,再按图2.5所示连接STM32芯片与蓝牙模块,使系统能够与计算机终端通信。其中OpenMV摄像头模组使用Type-C接口外接5V电源供电,DT50使用自带电池供电,HC-05蓝牙模块供电由STM32芯片提供。由于该系统只需要从DT50激光传感器上的LED屏幕上获取数据,故在系统运行期间只需为DT50激光传感器提供电源即可,无需设计额外的硬件电路。而HC-05蓝牙模块[6-7]需要从STM32处理器获取图像的处理结果即识别到的数字量发送至计算机终端,故需要与STM32芯片串口端连接。
在这里插入图片描述

图2.5 STM32与HC-05蓝牙接线图

3. 系统软件设计

软件设计可分为远程数据传输和数字识别两个部分,远程数据传输部分通过蓝牙模块实现,数字识别部分利用图像处理算法实现。软件设计思路如下:
首先配置HC-05蓝牙模块,设置其波特率为115200,停止位为1,无校验位。使其能够利用串口向计算机终端正常发送数据。然后进行摄像头的配置,设置图像分辨率为640×480,图像输出格式为灰度图,以减少对图像数据的处理量,提高系统运算速度。最后对摄像头所得到的图像进行特征提取并与特征模板匹配,即可得到识别结果。软件流程如图3.1所示。
在这里插入图片描述

图3.1 软件流程图

3.1 硬件配置

HC-05蓝牙模块的配置需要利用USB转TTL模块与PC端串口调试助手实现通信,USB-蓝牙接线方式如图3.2所示。
在这里插入图片描述

图3.2 USB-蓝牙连线
通过AT指令对蓝牙名称、配对码以及波特率进行配置,设置蓝牙名称为CeJuYi,配对码为1234,波特率为115200。配置指令如下。
1. AT+NAME="CeJuYi"       修改蓝牙模块名称为CeJuYi
2. AT+ROLE=0              蓝牙模式为从模式
3. AT+CMODE=1             蓝牙连接模式为任意地址连接模式,也就是说该模块可以被任意蓝牙设备连接
4. AT+PSWD=1234           蓝牙配对密码为1234
5. AT+UART=115200,0,0     蓝牙通信串口波特率为115200,停止位1位,无校验位

为了能够使STM32芯片同蓝牙通信,配置STM32芯片UART3的波特率为115200。同时配置摄像头分辨率640×480,图像输出格式为灰度图。配置代码如下。

import sensor,image,time
from pyb import UART
sensor.reset()                                 #启动摄像头
sensor.set_framesize(sensor.VGA)               #设置分辨率640X480
sensor.set_pixformat(sensor.GRAYSCALE)         #设置图像以灰度输出
sensor.skip_frames(time = 2000#设置跳过帧数
uart = UART(3,115200#初始化UART3波特率为115200

3.2 数字识别

数字识别具体可分为图像预处理、数字区域分割、数字字符匹配三大部分[8-9]。图像预处理的作用是滤除噪声增强图像信息;数字区域分割的作用是将单个数字所在区域从图像中分割出来;数字字符匹配的作用是分析每个分割出来的图像区域特征并对其特征进行提取,利用提取到的图像区域特征与已知数字特征进行一一对比,从而判断图像区域中的数字字符量。下面将详细介绍各个部分的处理过程。

3.2.1 图像预处理

图像预处理需要经过图像矫正、高斯滤波、二值化以及众数滤波四个步骤,才能得到质量较好的图像[10]。由于摄像头本身存在畸变的原因,在进行数字识别前,必须对图像进行畸变矫正。否则图像中的数字可能发生一定的变形,不利于我们对数字的识别。一般矫正图像有二个选择,一种是安装可以减少畸变的镜头,另一种是利用软件算法对图像进行矫正。在本文中采用软件对图像进行矫正。对矫正后的图像进行高斯滤波以减少图像中的噪声对后续算法执行的影响。再通过二值化和众数滤波得到只有黑(0)和白(255)两种亮度的二值化图像。原始灰度图像经过预处理后如图3.3所示。
在这里插入图片描述

图3.3 预处理图像

3.2.2 数字区域分割

数字区域分割顾名思义就是将图像中各个数字所在区域分割开来,并得到图像中各个数字所在区域的位置和大小信息。实际算法在执行过程中会寻找每一个数字的外接矩形并返回相应矩形区域位置和大小信息。这就要求各个数字之间不能有所连接,否则将会造成区域划割错误。经过大量实验发现影响数字区域分割准确性的主要因素是由于小数点与左右数字相连通,导致数字区域分割出错。又由于摄像头与DT50传感器LED屏幕之间的位置是固定不变的,所以小数点在图像中的位置也是固定的。基于这一点,我们可以将图像中原先位置的小数点先去除掉,然后将其当前位置适当向下平移后再重新补上小数点就可以使得各个数字所对应连通域之间相互独立。此时再对各个数字区域进行分割就能够得到准确的分割图像结果。为了更加直观的体现算法的作用及效果,可对比数字区域分割前(图3.4)和数字区域分割后(图3.5)图像以作说明。
在这里插入图片描述

图3.4 数字区域分割前

在这里插入图片描述

图3.5 数字区域分割后

3.2.3 数字字符匹配

通过对图像中每个数字区域进行分割,使得我们可以对单个数字进行特征提取。数字字符匹配的方法很多,但基于数码管的特征,并经过实验得出,采用“穿线匹配法”识别效率最高,可以满足应用要求[11]。穿线匹配法是按照7段数码管的特征来匹配的,如图3.6所示。
7段数码管的特征是ABCDEFG 7个显示段组成,垂直的4个段,水平的有3个段,每个段的粗细长短基本一致,通过提取这7个显示段的特征来判断实际显示的数字。一些数字显示仪器的匹配算法也是根据数码管的显示特征来进行的。匹配是在数字分割之后进行,这种方法的优点还在于这种处理方法不需要进行归一化与细化处理。数字字符匹配过程如下:

(1)通过字符的水平三分之一穿线与三分之二穿线将数字水平平分为三个部分;
(2)每一部分由中间开始从上到下进行扫描,如果在一部分中间存在笔段,就将其记为“255”,反之记为“0”;“(1)、(2)”两步用来检测DEFG是否存在笔段;
(3)将数字通过竖直二分之一穿线垂直分成两个部分;
(4)每一部分由中间开始从左到右进行扫描,如果这一部分中间存在笔段,就将其记为“255”,反之记为“0”;“(3)、(4)”两步用来检测ABC是否存在笔段。
(5)按顺序存储7段数码管对应特征值。
在这里插入图片描述

图3.6 穿线匹配法

特别要指出的是,“1”很容易出现误判,所以“1”的特征要特别强调,因为“1”是唯一一个水平段全部不亮的字符,虽然“1”的分割图像高度与其他数字没有太大的分别,但是宽度比别的字符小很多,可以利用这两个特征准确判断“1”。另外小数点的分割图像高度和宽度与正常数字相比非常小且高度与宽度相差不大,同样也可以使用该特征进行判别。
数码管数字特征如表3.1所示,通过提取图像中每个数字对应的7段数码管特征并与下表进行一一匹配就可以得到对应的数字量,最后将各个数字量以及小数点按照其在图像中的位置关系组合起来,就实现了对整个图像的识别过程。

表3.1 数码管数字特征表

在这里插入图片描述

4. 实验结果

系统硬件结构如图4.1所示,在测试过程中,首先得到DT50稳定时4 个数字的图像,用 SD 卡保存后利用图像处理算法对其进行区域分割,得到每个数字的区域位置坐标带入图像识别算法中;然后,不断晃动 DT50或将其放入动态物体上,使DT50 数值不断改变,最终通过蓝牙发送给计算机终端,终端利用串口调试助手实时显示 DT50的变化,从而达到了系统设计的目的,实现无误差距离测量。
在这里插入图片描述

图4.1 系统硬件结构

通过图像处理技术对摄像头获取的图像进行识别,将识别结果打印在图像的空白区域,并保存在SD卡内。对比图像与识别结果,统计SD卡内的各个字符识别正确率并重复实验,最后记录各个字符前1000次的识别结果并填入表4.1中。经过实验验证发现本系统对字符的识别速率高,稳定性好,且识别率均达到了99.5%以上,可以满足实际应用的效果。

表4.1 图像识别结果统计表

在这里插入图片描述

5. 总结

本文设计的新型激光传感器测量控制系统,在仅使用摄像头这一个传感器的基础上,融合图像形态学、图形分割、图像特征提取等数字图像处理算法,打破了原来使用电流板采集时大量数字信号处理后仍存在误差且调节算法参数耗时时间长的局限性,具有很强的准确性和实时性。虽然COMS摄像头只能每 20ms 采集一帧数据,也有自身采集时间的局限性但对于静止系统和绝大多数运动系统而言,整个系统测量结果是稳定精确的,因此具有一定的实用推广价值。

致谢

在本次课程设计中,我们的课题是设计一种基于STM32的新型激光测距控制系统。在设计过程中我们遇到了很多的问题和疑惑。困扰着我们并且拖慢了我们的进程。在这里要非常感谢那些帮助了我们的同学。在完成课题时,在旁边帮我们出谋划策,帮我们优化程序,为我答疑解惑。
我还一定要感谢我的组员,他在课设中帮助我完成了部分本该我完成的任务。并且在我无法解决问题时,无私的帮助我。在他的努力下,我们小组的课题才能最终完美的完成。
在设计过程中,我得到了韩老师的悉心指导。韩老师多次帮助我分析思路,开拓视野,在我遇到困难想放弃的时候给予我最大的支持和鼓励。在我遇到不理解的问题时,韩老师会耐心给我解答。帮助我们解决了许多技术上的难题。让我不仅学习到了许多新的知识,而且也领悟了大局观,提高了自己的设计能力。在集体验收的时候,韩老师对我的设计进行一个客观的评价,给我指出了我自己设计的不足,还帮我解决了一些自己难以实现的目标,韩老师悉心指导,乐于帮助他人,并且知识面很广,每个问题韩老师都能侃侃而谈,并且可以从多个角度切入,帮我全方位的去剖析我的问题还能给我最为合适解决方案,韩老师严谨求实的治学态度,踏实坚韧的工作精神,将让我终生受益。在此,谨向韩老师致以诚挚的谢意和崇高的敬意。
最后,再次感谢韩老师在课程设计过程中对我的指导和帮助,再次感谢那些帮助我的同学们。有了你们的帮助,才能让我完成课程设计。

参考文献

[1] 胡腾飞, 张永德, 于爽. 基于AT89C52单片机的激光测距仪控制器[J]. 自动化技术与应用, 2004, 23(3):74-77.
[2] 任爱芝, 鲜浩. 激光测距仪数据采集[J]. 中北大学学报(自然科学版), 2003, 24(1):51-53.
[3] Yu K , Wu C , Sun M , et al. Fiber laser sensor for simultaneously axial strain and transverse load detection[J]. Measurement, 2015, 62:137-141.
[4] Abdelkader I , El-Sonbaty Y , El-Habrouk M . Openmv: A Python powered, extensible machine vision camera[J]. 2017.
[5] Bell, Charles. MicroPython for the Internet of Things || MicroPython Hardware[J]. 2017, 10.1007/978-1-4842-3123-4(Chapter 3):59-124.
[6] 刘希明. 基于物联网蓝牙遥控技术的智能家居系统设计[J]. 数码世界, 2016(12):195-195.
[7] 陈旭, 王志坤, 穆庆吉, et al. 基于蓝牙通信的便携式迷你测距仪[J]. 河北农机, 2017(5):66-66.
[8] 刘丹, 穆林丽, 余晓锷. 一种七段数码管式医用仪表的自动识别方法[J]. 科学技术与工程, 2010, 10(16):4037-4039.
[9] 王蓉芳, 汪仁煌, 康亚芬. 基于数码管机器视觉的小数点识别[J]. 电子测试, 2008(11):17-20.
[10] 盘思乐. 机器视觉之边缘检测算法在数码管识别中的应用[J]. 深圳信息职业技术学院学报, 2011(3):15-18.
[11] 宋薇. 数字仪表数码管显示识别设计[J]. 电子制作, 2013(11):27-28.

附录A源程序

import sensor, image, time
from image import SEARCH_EX, SEARCH_DS
from pyb import UART
sensor.reset()
sensor.set_framesize(sensor.VGA)  #分辨率640X480
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_windowing((270,167,135, 300)) #截取数字所在区域
sensor.skip_frames(time = 2000)
uart = UART(3, 115200)                         # 使用给定波特率初始化
Number_template=[                             #数字匹配模板
                    [  0,  0,  0,  0,  0,  0,255],       #0
                    [255,255,255,  0,  0,  0,  0],       #1
                    [255,  0,  0,255,  0,  0,  0],       #2
                    [  0,255,  0,255,  0,  0,  0],       #3
                    [  0,255,  0,  0,255,255,  0],       #4
                    [  0,255,255,  0,  0,  0,  0],       #5
                    [  0,  0,255,  0,  0,  0,  0],       #6
                    [  0,255,  0,255,  0,255,255],       #7
                    [  0,  0,  0,  0,  0,  0,  0],       #8
                    [  0,255,  0,  0,  0,  0,  0],       #9
                ]
Number_feature=[]  #提取的数字特征点列表
Match_result=[] #数字识别结果储存列表
point_x=0   #初始化小数点x坐标
point_y=0   #初始化小数点y坐标
point_w=0   #设置小数点的最大宽度
point_h=0   #设置小数点的最大高度
number_w=80
number_h=15
faxian=0
start_flag=0  #数字个数统计
grayscale_thres=[(230, 0)]
while(True):
       img = sensor.snapshot().lens_corr(strength = 0.6, zoom = 1.0)#图像矫正
       img.gaussian(1,unsharp=True) #高斯滤波
       img.binary(grayscale_thres)#图像二值化
       img.mode(1)#众数滤波
       for blob in img.find_blobs(grayscale_thres,area_threshold=number_w*number_h):#遍历blob目标
           start_flag+=1 #统计图像区域数字个数
       if start_flag>=3 and start_flag<6:#则表示小数点丢失
           for blob in img.find_blobs(grayscale_thres):#遍历blob目标
               #如果小数点与左右数字都连接
               if blob.h()>85:
               #寻找并去除小数点---------------------------------------------start
                    for y in range(200,223):
                       if (img.get_pixel((int)(blob.x()+blob.w()/10*1),y)==255 and img.get_pixel((int)(blob.x()+blob.w()/10*3),y)==255 and img.get_pixel((int)(blob.x()+blob.w()/10*5),y)==255 and img.get_pixel((int)(blob.x()+blob.w()/10*7),y)==255) :
                          if (point_h==0):
                             point_y=y
                          point_h+=1
                          for x in range(90,120):
                            img.set_pixel(x,y,255)#设置像素点为白色
                  #寻找并去除小数点-----------------------------------------------end
                  #添加小数点
                    img.draw_circle(125, (int)((point_y+point_h/2)), 6, color=0, thickness=1, fill=True)
               #连接“1”的上下段
               if blob.w()>20 and blob.h()<26:
                    img.draw_rectangle((blob.x()-2,blob.y(),blob.w()+4,blob.h()),color=0,fill=True)
           #去除小数点,如果小数点最多与一个数字相连接
           if point_y ==0 and point_h==0:
                   for y in range(200,220):
                        for x in range(90,120):
                           img.set_pixel(x,y,255)#设置像素点为白色
                   img.draw_circle(125, 210, 6, color=0, thickness=1, fill=True)
           point_y=0
           point_h=0
           ###---------------------------------------------------#
           ###                   A       B                   
           ###               -----------------------                      
           ###               |       |       |                   
           ###               | F     |G      |C                
           ###               |       |       |                   
           ###               -----------------------                        
           ###                   E       D                      
           ###---------------------------------------------------#
           img.median(1)
           img.erode(2)
           for blob in img.find_blobs(grayscale_thres,area_threshold=25):#遍历连通域目标
              img.draw_rectangle((blob.x()-4,blob.y()-4,blob.w()+8,blob.h()+8),color=0)#绘制外接矩形
              if blob.w()>number_w and blob.h()>30 :#数字识别
                   for y in range(blob.y(),(int)(blob.y()+blob.h()/2)):
                     if(img.get_pixel((int)(blob.x()+blob.w()/10*7),y)==0 and img.get_pixel((int)(blob.x()+blob.w()/10*7),y+1)==255):
                          Number_feature.append(0)
                          faxian=1
                          break
                   if faxian==0:
                          Number_feature.append(255)
                   else:
                      faxian=0
                   for y in range((int)(blob.y()+blob.h()/2),blob.y()+blob.h()):
                     if(img.get_pixel((int)(blob.x()+blob.w()/10*7),y)==255 and img.get_pixel((int)(blob.x()+blob.w()/10*7),y+1)==0):
                          Number_feature.append(0)
                          faxian=1
                          break
                   if faxian==0:
                          Number_feature.append(255)
                   else:
                      faxian=0
                   for y in range(blob.y(),(int)(blob.y()+blob.h()/2)):
                      if(img.get_pixel((int)(blob.x()+blob.w()/10*3),y)==0 and img.get_pixel((int)(blob.x()+blob.w()/10*3),y+1)==255):
                           Number_feature.append(0)
                           faxian=1
                           break
                   if faxian==0:
                           Number_feature.append(255)
                   else:
                       faxian=0
                   for y in range((int)(blob.y()+blob.h()/2),blob.y()+blob.h()):
                      if(img.get_pixel((int)(blob.x()+blob.w()/10*3),y)==255 and img.get_pixel((int)(blob.x()+blob.w()/10*3),y+1)==0):
                           Number_feature.append(0)
                           faxian=1
                           break
                   if faxian==0:
                           Number_feature.append(255)
                   else:
                       faxian=0
                   for x in range(blob.x(),(int)(blob.x()+blob.w()/2)):
                       if(img.get_pixel(x,(int)(blob.y()+blob.h()/2))==255 and img.get_pixel(x-1,(int)(blob.y()+blob.h()/2))==0):
                            Number_feature.append(0)
                            faxian=1
                            break
                   if faxian==0:
                            Number_feature.append(255)
                   else:
                        faxian=0
                   for x in range((int)(blob.x()+blob.w()/2),blob.x()+blob.w()):
                       if(img.get_pixel(x,(int)(blob.y()+blob.h()/2))==255 and img.get_pixel(x+1,(int)(blob.y()+blob.h()/2))==0):
                            Number_feature.append(0)
                            faxian=1
                            break
                   if faxian==0:
                            Number_feature.append(255)
                   else:
                        faxian=0
                   if(img.get_pixel((int)(blob.x()+blob.w()/2),(int)(blob.y()+blob.h()/2))==0):
                        Number_feature.append(0)
                   else:
                        Number_feature.append(255)                  
                   #判断匹配数字--------------------------------start
                   for i in range(10):
                       if(Number_template[i]==Number_feature):#匹配数字
                          Match_result.append(str(i))#保存数字
                   #判断匹配数字--------------------------------end
                   #print(Number_feature)#打印数字特征模板
                   Number_feature=[]
              elif blob.w()>number_w and blob.h()<30:
                      Match_result.append("1")
              elif blob.w()<20 and blob.h()<20 and blob.y()>150:
                      Match_result.append(".")#保存小数点
           Match_result=Match_result[::-1]
           number_str= "".join(Match_result)#将结果转换为字符串类型
           if len(number_str)==5:
              number_str+=' m'
              uart.write(number_str+'\r\n')
              img.draw_string(35, 282,number_str, color=0,scale=2,x_spacing=-7)
           Match_result=[]  #清空匹配结果列表,准备下次循环
       else:
            number_str='Error'
            uart.write('Error\r\n')
            img.draw_string(43, 282,number_str, color=0,scale=2,x_spacing=-7)
            #print('未运行测距仪')
       start_flag=0 #清空本次数字个数统计结果,等待下次循环


发布了3 篇原创文章 · 获赞 2 · 访问量 379

猜你喜欢

转载自blog.csdn.net/u010067603/article/details/104514597