印度车牌识别中Character Segmentation无法分割全部字符如何优化
印度车牌识别字符分割不全问题优化方案
问题场景
在进行印度车牌识别开发时,存在字符分割无法完整提取所有字符的问题:例如车牌号为MH20EE7601时,仅能分割得到H20EE7.,部分场景下甚至无法识别到任何数字。
相关参考图片如下:
现有代码如下:
gray = cv2.cvtColor(box, cv2.COLOR_RGB2GRAY) gray = cv2.resize(gray, None, fx = 3, fy = 3, interpolation = cv2.INTER_CUBIC) blur = cv2.GaussianBlur(gray, (5,5), 0) ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) rect_kern = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) dilation = cv2.dilate(thresh, rect_kern, iterations = 1) try: contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) except: ret_img, contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) sorted_contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0])
其他参考图片:
可直接落地的优化步骤
- 新增对比度增强环节:印度车牌普遍存在反光、字符褪色的问题,直接用OTSU二值化容易丢失边缘较淡的字符信息,可在灰度化之后加自适应直方图均衡处理:
# 加在灰度化之后、高斯模糊之前 clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) gray = clahe.apply(gray) - 调整形态学操作逻辑:现有5x5卷积核+单次膨胀的组合,容易把相邻字符的轮廓连在一起,也会吞掉比较窄的字符(比如数字1),建议把卷积核缩小,用开运算替代单纯的膨胀,避免字符粘连和轮廓丢失:
# 替换原有的形态学、膨胀代码 rect_kern = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, rect_kern, iterations=1) # 后续findContours直接用morph变量即可 - 新增有效轮廓过滤规则:现有代码直接对所有轮廓排序,会把车牌边框、固定铆钉、表面污渍等非字符轮廓纳入统计,也会漏掉尺寸不符合字符规范的有效轮廓。可参考印度车牌单字符高宽比1.53、面积占车牌总面积1/301/10的标准做筛选:
# 加在轮廓提取之后、排序之前 plate_h, plate_w = gray.shape valid_contours = [] for ctr in contours: x,y,w,h = cv2.boundingRect(ctr) aspect_ratio = h/w area = w*h min_area = (plate_h * plate_w)/35 max_area = (plate_h * plate_w)/8 if 1.2 < aspect_ratio < 3.5 and min_area < area < max_area: valid_contours.append(ctr) sorted_contours = sorted(valid_contours, key=lambda ctr: cv2.boundingRect(ctr)[0]) - 如果仍存在字符粘连问题,可叠加垂直投影法辅助分割:统计二值图每一列的白色像素数量,像素数为0的位置就是天然的字符分割线,用这个规则可以把连在一起的字符切开。
内容的提问来源于stack exchange,提问作者Shivani Vig
相关产品推荐
相关产品推荐






