摘要
在车牌识别以及别的需要文本识别的场景中都需要对图像中的文本进行正确的切分以便于下一步的识别,类似人的阅读计算机在识别文本时只能一个一个的来,精准的切分字符是识别的必要条件。
算法
假设我们已经从包含整辆车的图片中得到了只包含车牌的区域,如图一所示,那么任务就是如何把图一中出现的字母和数字单独分开。

注意到图一的左上角有干扰项,所以在后续处理时要做相应的去噪处理,这个在下面会讲。
很显然如果我们可以找到每一个字符最小外接矩形那么就可以精准的从图一中把每一个字符拿出来单独识别。要实现这一步是很简单的,CV中已经内嵌了所有我们需要的函数,只要调用就行。
算法的大概过程如下:
step1:变换图一的颜色空间,RGB2GRAY,为了能够使用CV的其他重要函数
step2:对step1的图像进行二值化处理
step3:在step2 结果图中利用findContours()函数检测连通区域的轮廓
step4:针对step3 到的轮廓检测其最小外接矩形,boundingRect()函数。
step5:根据step4 的矩形完成分割。
附上代码:
import cv2
import argparse
ap=argparse.ArgumentParser()
ap.add_argument("-i","--images",required=True,help="path to the images to be classified")
args=vars(ap.parse_args())
def segmenteCharacter():
img = cv2.imread(args['images'])
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(5,5),0)
ret, im_th = cv2.threshold(gray,90,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
im_th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,75, 10)
im_th = cv2.bitwise_not(im_th)
im2, ctrs, hier = cv2.findContours(im_th.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
sorted_ctrs = sorted(ctrs, key = lambda ctr: cv2.boundingRect(ctr)[0])
#cv2.drawContours(gray,ctrs,-1,(0,255,0),3)
print len(ctrs)
cv2.imshow('bitwise',im_th)
cv2.waitKey(0)
for i, ctr in enumerate(sorted_ctrs):
x,y,w,h = cv2.boundingRect(ctr)
aspectRatio = w/float(h)
heightRatio = h/float(im_th.shape[0])
keepHight = heightRatio > 0.4 and heightRatio < 0.95
keepAspectRatio = aspectRatio < 1.0 and aspectRatio > 0.15
#roi = im2[y:y+h,x:x+w]
#cv2.imshow('character'+str(i),roi)
if keepAspectRatio and keepHight:
roi = im2[y:y+h,x:x+w]
cv2.imshow('character'+str(i),roi)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imshow('marked areas',img)
cv2.waitKey(0)
if __name__ == '__main__':
segmenteCharacter()