有时候遇到待提取的目标与背景颜色很接近,我们无法直接用阈值处理将其分割,只能尝试其他方法,今天介绍的实例就是如此。
如上图所示,我们的目标是提取图中的字符,然后做识别,但是字符的颜色和背景很接近,如果直接用二值化处理,效果不佳。通过观察分析,发现字符颜色虽然与背景接近,但是饱和度(颜色深度)明显与背景不同,所以我们可以将原图转到HSV空间,然后在S(饱和度)通道进行阈值处理,最后进行形态学去除杂讯,得到最后的目标。
如下是用Halcon实现的代码与效果:
read_image(Image, './imgs/test.jpg')
*将原始图像进行通道分离,得到红绿蓝三个分量的图像
decompose3 (Image, Red, Green, Blue)
*将RGB三个分量的图像转化为H(色调)、S(饱和度)、V(明度)的图像
trans_from_rgb (Red, Green, Blue, ImageResultH, ImageResultS, ImageResultI, 'hsv')
*对饱和度图像阈值处理,分割出高饱和度区域,即字符区域的大致范围
threshold (ImageResultS, High, 192,255)
*区域分割,
reduce_domain (ImageResultH, High, ImageReduced)
*并进行膨胀操作
dilation_circle (ImageReduced, RegionDilation, 3.5)
*开运算,使边缘更清晰
opening_circle (RegionDilation, RegionChars, 5.5)
dev_clear_window ()
dev_display (RegionChars)
下面用OpenCV实现并显示中间步骤结果:
import cv2
import numpy as np
img = cv2.imread("test.jpg")
hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv_img)
cv2.imshow('H',h) #蓝色通道
cv2.imshow('S',s) #绿色通道
cv2.imshow('V',v) #红色通道
ret,thres_img = cv2.threshold(s,185,255,cv2.THRESH_BINARY)
cv2.imshow("thres_img", thres_img)
k1=np.ones((7,7), np.uint8)
k2=np.ones((5,5), np.uint8)
opening = cv2.morphologyEx(thres_img, cv2.MORPH_OPEN, k1)
opening = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, k2)
cv2.imshow('open', opening)
contours,hierarchy = cv2.findContours(opening, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img,contours,-1,(0,255,0),-1)
cv2.imshow('result',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
H通道:
S通道:
S通道二值化处理效果:
开运算+闭运算效果:
最终轮廓绘制效果:
当然,解决方法不唯一,这里只是演示其中一种方法
本文分享自 OpenCV与AI深度学习 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!