真的!只需 “六步” 实现图像特定物体识别!!!
一、概况
在一个 "大数据智能太阳能光伏" 项目中,有这么一个需求:
通过无人机(大疆)对整片光伏区域进行航拍(包括红外图像与可见光图像),再航拍的图片通过4G/5G实时传输到应用程序,应用程序基于计算机视觉技术,自动识别出图片中光伏组件可能存在的故障,并结合其他实时监控与分析数据,从而判断光伏组件是否存在故障并给出报警,下图是该需要的整体业务路程。
这是一个人工智能在计算机视觉领域的典型应用,要实现这些功能涉及到技术非常多如:无人机图像传输,图像识别,光伏组件实时数据监测与分析等,本文从“怎样分离出原始图片中的特定区域(光伏组件串)“这个很小的片段入手, 来阐述计算机视觉分析究竟个什么样子。文中不涉及到任何算法的原理与细节,我们先梳理实现的整体步骤,并先让代码能跑起来可以看到实际的运行结果。
二、整体思路
通过上面的描述,我们的目标非常清晰,就是要从一张带光伏组件的照片中,分离出来一块块的光伏组件串,下图为原始图片与结果输出后的图片。
那应该如何实现这个功能呢?
整体实现流程大概可分为如6个步骤
1 读取原始图片-->2 转化图片的色彩空间-->3 获取二值化图片 -->4 对图片进行形态学处理-> 5 获取图片轮廓- > 6 切割并保存区域图片
下面对每一个步骤进行说明并提供相应的代码
代码实现使用OpenCV,OpenCV是一个开源的计算机视觉库,它轻量,功能强大,实现了图像处理和计算机视觉方面的诸多算法,可以运行在Linux、Windows、Android和Mac OS操作系统上。同时提供了Python、Ruby、MATLAB等语言的接口。
1、读取原始图片
整个功能实现的过程,就是对图片不断变化的过程。所有,首先需要将磁盘上的图片文件读取到内存并转化为opencv能处理的数据,该数据是一个三维数组(300,400,3),每个维度分别表示高、宽、通道数,数组中的值表示每个像素点不同通道的取值0-255之间,同时由于原始文件的尺寸比较大(3000*4000)为了方便查看,将原始文件等比例缩小。下面是函数实现,传入图片路径与图片缩小比例(默认为1不缩小)返回缩小后的原始图片数组。
2、转化图片的色彩空间
彩色的图片默认的是RGB色彩空间,RGB分别代表三个基色(R-红色、G-绿色、B-蓝色),具体的色彩值由三个基色叠加而成,一张彩色图片就是由三个基色取不同的值叠加而成。
那为什么还要转化到HSV色彩空间呢?因为RGB通道并不能很好地反映出物体具体的颜色信息,而相比RGB,HSV通过,色调、饱和度、能够非常直观的表达色彩的色调,明亮、与鲜艳程度,方便进行颜色之间的对比。 比如红色在HSV空间中H取值的范围为0~10和160~180,不同的色彩可以通过不同的H、S、V的不同取值范围进行区分,在下面转化二值化图片处理中就会使用HSV的取值范围。
下面是获取HSV图片的函数,传入原始图片数据,返回HSV图片数据。
下图为HSV图像
3、获取二值化图片
对于RGB或者HSV图片,每个像素点的值由0-255的数值组成,而在选取某个区域时,需要标识出感兴趣的区域,与不感兴趣的区域,这是一个典型的非1即0问题。而二值化图像就具有该特征,即每个像素点的值只能是0或者255,对应的颜色就只有黑色与白色,如下图,光伏组件是白色区域,其他的背景是黑色区域。
具体实现:先设定一个HSV的阀值,二值化的核心原理就是利用阀值作为分隔条件,如大于阀值为0(黑色)小于阀值为255(白色)。可以使用窗口动态调节阀值,通过实时观测二值化分割效果来确定阀值(通过窗口动态获取阀值的方法可以参考《滑动块动态获取二值化阀值》),这里我们初步选取的阀值如下:
下面函数用来对HSV图片进行二值化,函数传入HSV图片与最低阀值和最高阀值,返回的结果为二值化图片,一个数值由0或255构成二维数组(见打印结果)
二值化图片
4、对图片进行形态学处理
通过二值化处理之后的图片,可以明显的区分光伏组件串,但是存在一个问题:即光伏组件串直接的缝隙被分开了,我们希望能去掉缝隙将组件串作为一个整体识别出来,而这就需要用到图像形态学处理。
形态学处理一般包括两个操作"腐蚀”与"膨胀",其目的是为了改变物体的形状,通过字面意思也很好理解,腐蚀就是”变瘦”,膨胀就是”变胖”。
下面的函数进行形态学处理,函数传入二值化图片,返回处理过后的图片。
进过形态学处理过后的效果,相比原来二值化图片,处理后的光伏组件串之间的间隙消除了。
5、获取组件串轮廓区域
通过上面5个步骤的处理,终于得到了一张背景为黑色,目标物体为白色的图片,接下来就需要将图片中白色区域轮廓识别出来,代码如下函数,传入一个形态学处理过后的二值化图片,返回所有的组件轮廓, 代码含义可见注释。
6、切割并保存区域图片
最后一步,根据轮廓数据在原始图片上进行区域切割并将切割后图片保存至磁盘,实现函数如下,传入轮廓区域与原始图片,返回轮廓处理的数量。
全部完整代码如下:
为了方便阅读与整理思路,将每个处理步骤封装为一个函数,并使用一个总函数来组合每个处理步骤。
三、总结
至此,整个光伏组件串的识别与分离就基本完成,当然,这只是项目需求中功能很小的一部分demo验证代码,后续整体解决方案(比如:大疆无人机的图像实时传输,红外图片的故障识别,可见光图片的特定故障识别)我会持续更新。。。。。。
版权声明: 本文为 InfoQ 作者【攀岩飞鱼】的原创文章。
原文链接:【http://xie.infoq.cn/article/252b9e301cb100453ad97ed11】。文章转载请联系作者。
评论