1 说明:
=====
1.1 完整汽车车牌的识别,包括汽车车牌的定位,提取,字符分割显示和车牌识别四大部分。
1.2 目前这已经是一项成熟的技术,本文主要通过汽车车牌的字符分割并显示车牌号码,熟悉python和opencv的技术。
1.3 本文已经写了2篇相关文章,汽车车牌的定位、提取,本文重点讲解蓝色小轿车的汽车车牌的字符分割、保存、显示技术。
1.4 讲解非常清楚,注释详细,通俗易懂,并复习opencv的threshold函数。
2 操作和效果图:
3 声明:
=====
3.1 汽车和车牌:来自今日头条免费正版图库,仅供学习。
如有冒犯,请谅解,仅供学习
3.2 汽车车牌提取:
1.png,提取出来的汽车车牌
3.3 参考我的上一篇文章:
《一步一步详细讲解:python+opencv的车牌提取大全》
3.4 环境:
python3.8,深度操作系统deepin-linux,微软编辑器vscode,opencv版本4.2.0。
===重点===
4 代码讲解:
========
4.1 第1步:导入模块:
import cv2import numpy as np
4.2 第2步:图片的预处理
# 2-1:读取抠出来的蓝色车牌,汽车提取出来的车牌img=cv2.imread('/home/xgj/Desktop/carcut/1.png')cv2.imshow('carblurpai',img)cv2.waitKey(0)# 2-2:图像归一化img_resize = cv2.resize(img,(136,36),interpolation=cv2.INTER_AREA) # 2-3:灰度化+二值化img_gray_1 = cv2.cvtColor(img_resize,cv2.COLOR_BGR2GRAY)ret1,img_thre_1 = cv2.threshold(img_gray_1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)# 2-4:高斯模糊img_gaus = cv2.GaussianBlur(img_resize,(3,5),0) # 2-5:灰度处理img_gray = cv2.cvtColor(img_gaus,cv2.COLOR_BGR2GRAY) # 2-6:图像黑白的二值化ret,img_thre = cv2.threshold(img_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
4.3 第3步:判断底色和字体色,当然经过预处理后肯定符合,主要是处理后将相关指标存储起来以备后面调用。
# 3-1:初始化定义列表white=[]black=[]height=img_thre.shape[0] width=img_thre.shape[1] white_max=0black_max=0# 3-2:计算每一列的黑白像素总和for i in range(width): line_white=0 line_black=0 for j in range(height): if img_thre[j][i]==255: line_white+=1 if img_thre[j][i]==0: line_black+=1 white_max=max(white_max,line_white) black_max=max(black_max,line_black) white.append(line_white) black.append(line_black)# 3-3:arg为true表示黑底白字,False为白底黑字arg=Trueif black_max
4.4 第4步:定义函数,找结尾end,这个时候就需要第3步的相关参数
#---第4步:定义函数找到结束点---def find_end(start,arg,black,white,width,black_max,white_max): end=start+1 for m in range(start+1,width-1): #0.98与下面的0.02对应 if (black[m] if arg else white[m])>(0.98*black_max if arg else 0.98*white_max): end=m break return end
4.5 第5步:分割字符和保存字符,注意cv2格式的显示、保存和操作enter下一步。
n=1start=1end=2word = []while n(0.02*white_max if arg else 0.02*black_max): start=n #调用前面的函数,找结束点end end=find_end(start,arg,black,white,width,black_max,white_max) n=end if end-start>5: cj=img_thre[1:height,start:end] #保存分割的图片 cv2.imwrite("/home/xgj/Desktop/carcut/result/%s.jpg" % (n),cj) cv2.imshow('solocutlicense',cj) word.append(cj) cv2.waitKey(0)cv2.waitKey(0)cv2.destroyAllWindows()
4.6 第6步:用matplotlib将汽车车牌在一张图中并排显示,顺带复习matplotlib。
from matplotlib import pyplot as plt #这个可以放在前面for i,j in enumerate(word): plt.subplot(1,8,i+1) plt.imshow(word[i],cmap='gray')plt.show()
5 完整代码:
#---第1步:导出模块---import cv2import numpy as np#---第2步:图片的预处理---# 2-1:读取抠出来的蓝色车牌img=cv2.imread('/home/xgj/Desktop/carcut/1.png')cv2.imshow('carblurpai',img)cv2.waitKey(0)# 2-2:图像归一化img_resize = cv2.resize(img,(136,36),interpolation=cv2.INTER_AREA) # 2-3:灰度化+二值化img_gray_1 = cv2.cvtColor(img_resize,cv2.COLOR_BGR2GRAY)ret1,img_thre_1 = cv2.threshold(img_gray_1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)# 2-4:高斯模糊img_gaus = cv2.GaussianBlur(img_resize,(3,5),0) # 2-5:灰度处理img_gray = cv2.cvtColor(img_gaus,cv2.COLOR_BGR2GRAY) # 2-6:图像黑白的二值化ret,img_thre = cv2.threshold(img_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) #---第3步:判断底色和字色---# 3-1:初始化定义列表white=[]black=[]height=img_thre.shape[0] width=img_thre.shape[1] white_max=0black_max=0# 3-2:计算每一列的黑白像素总和for i in range(width): line_white=0 line_black=0 for j in range(height): if img_thre[j][i]==255: line_white+=1 if img_thre[j][i]==0: line_black+=1 white_max=max(white_max,line_white) black_max=max(black_max,line_black) white.append(line_white) black.append(line_black)# 3-3:arg为true表示黑底白字,False为白底黑字arg=Trueif black_max(0.98*black_max if arg else 0.98*white_max): end=m break return end#---第5步:分割字符并保存字符---n=1start=1end=2word = []while n(0.02*white_max if arg else 0.02*black_max): start=n #调用前面的函数,找结束点end end=find_end(start,arg,black,white,width,black_max,white_max) n=end if end-start>5: cj=img_thre[1:height,start:end] #保存分割的图片 cv2.imwrite("/home/xgj/Desktop/carcut/result/%s.jpg" % (n),cj) cv2.imshow('solocutlicense',cj) word.append(cj) cv2.waitKey(0)cv2.waitKey(0)cv2.destroyAllWindows()#---第6步:---再加用matplotlib展示from matplotlib import pyplot as plt #这个可以放在前面for i,j in enumerate(word): plt.subplot(1,8,i+1) plt.imshow(word[i],cmap='gray')plt.show()
6 cv2.threshold函数:
===============
6.1 cv2.threshold用来调节图片二值化的效果的一个函数,其参数不一样效果不同。
6.2 如图:
0.png
6.3 上述代码:
#图像黑白的二值化cv2.threshold个参数#第1步:导入模块import cv2import numpy as npfrom matplotlib import pyplot as plt#第2步:读取图片img = cv2.imread('/home/xgj/Desktop/carcut/66.jpg', 0) #1是原图,0是灰色#如果读取1,然后用matplotlib显示可能与真实的原图不一样#img = cv2.imread('/home/xgj/Desktop/carcut/66.jpg', 1) #第3步:各参数调用ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)ret, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)ret, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)ret, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)ret, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)#第4步:定义各列表titles = ['original image', 'Binary', 'binary-inv', 'trunc', 'tozero', 'tozero-inv']images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]#第5步:matplotlib显示0图,即灰色图,不会有异常#如果调用1,显示原图,matplotlib显示就会不一样#cv2:opencv读取图像为b,g,r方法#plt函数是rgb方式读取的for i in range(6): plt.subplot(2, 3, i+1) plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]) plt.yticks([])plt.show()
6.4 设置为1,读取图片:
6.5 bgr和rgb转换:省略,我有介绍过。
7 不足小结:新能源汽车的白色绿色底的车牌有小bug。