真的!只需 “六步” 实现图像特定物体识别!!!( 二 )


下面是获取HSV图片的函数,传入原始图片数据,返回HSV图片数据 。
def get_hsv_image(original_image):"""获取hsv色彩空间图片1) 先将BGR色彩转化为HSV色彩"""hsv_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2HSV)# 将BGR色彩转化为HSV色彩cv2.imshow("HSV Image", hsv_image)print(hsv_image.shape)return hsv_image
HSV图片
3、获取二值化图片
对于RGB或者HSV图片,每个像素点的值由0-255的数值组成,而在选取某个区域时,需要标识出感兴趣的区域,与不感兴趣的区域,这是一个典型的非1即0问题 。而二值化图像就具有该特征,即每个像素点的值只能是0或者255,对应的颜色就只有黑色与白色,如下图,光伏组件是白色区域,其他的背景是黑色区域 。
具体实现:先设定一个HSV的阀值,二值化的核心原理就是利用阀值作为分隔条件,如大于阀值为0(黑色)小于阀值为255(白色) 。可以使用窗口动态调节阀值,通过实时观测二值化分割效果来确定阀值(通过窗口动态获取阀值的方法可以参考 《滑动块动态获取二值化阀值》),这里我们初步选取的阀值如下:
lower = np.array([44, 57, 130])upper = np.array([120, 191, 249])mask_image = get_mask_image(hsv_image, lower, upper)# 获取二值化图像 通过HSV的高低阈值,提取图像部分区域

真的!只需 “六步” 实现图像特定物体识别!!!

文章插图
下面函数用来对HSV图片进行二值化,函数传入HSV图片与最低阀值和最高阀值,返回的结果为二值化图片,一个数值由0或255构成二维数组(见打印结果)
def get_mask_image(hsv_image, lower, upper):"""获取二值化图片1)通过阀值获取二值化图像"""mask_image = cv2.inRange(hsv_image, lower, upper)# 获取二值化图片cv2.imshow("Mask Image", mask_image)print(mask_image)print(mask_image.shape)return mask_image
二值化图片
4、对图片进行形态学处理
通过二值化处理之后的图片,可以明显的区分光伏组件串,但是存在一个问题:即光伏组件串直接的缝隙被分开了,我们希望能去掉缝隙将组件串作为一个整体识别出来,而这就需要用到图像形态学处理 。
形态学处理一般包括两个操作"腐蚀”与"膨胀",其目的是为了改变物体的形状,通过字面意思也很好理解,腐蚀就是”变瘦”,膨胀就是”变胖” 。
下面的函数进行形态学处理,函数传入二值化图片,返回处理过后的图片 。
def get_morphology_image(mask_image):"""对二值化图像进行形态学处理-消除噪音影响1) 先进行膨胀处理膨胀就是使用算法,来将图像的边缘扩大些 。作用就是将目标的边缘或者是内部的坑填掉,去掉较小的孔洞2) 再进行腐蚀处理腐蚀:腐蚀会把物体的边界腐蚀掉,主要应用在去除白噪声,也可以断开连在一起的物体"""kernel = np.ones((5, 5), np.uint8)dialationIamge = cv2.dilate(mask_image, kernel, iterations=1)# 膨胀处理eroded_iamge = cv2.erode(dialationIamge, kernel, iterations=1)# 腐蚀处理cv2.imshow("Eroded Iamge ", eroded_iamge)# 显示形态学处理过后的图片return eroded_iamge
进过形态学处理过后的效果,相比原来二值化图片,处理后的光伏组件串之间的间隙消除了 。
5、获取组件串轮廓区域
通过上面5个步骤的处理,终于得到了一张背景为黑色,目标物体为白色的图片,接下来就需要将图片中白色区域轮廓识别出来,代码如下函数,传入一个形态学处理过后的二值化图片,返回所有的组件轮廓,代码含义可见注释 。