车牌识别Python程序Word文档格式.docx
《车牌识别Python程序Word文档格式.docx》由会员分享,可在线阅读,更多相关《车牌识别Python程序Word文档格式.docx(29页珍藏版)》请在冰豆网上搜索。
PROVINCE_START=1000
#读取图片文件
defimreadex(filename):
returncv2.imdecode(np.fromfile(filename,dtype=np.uint8),cv2.IMREAD_COLOR)
defpoint_limit(point):
ifpoint[0]<
0:
point[0]=0
ifpoint[1]<
point[1]=0
#根据设定的阈值和图片直方图,找出波峰,用于分隔字符
deffind_waves(threshold,histogram):
up_point=-1#上升点
is_peak=False
ifhistogram[0]>
threshold:
up_point=0
is_peak=True
wave_peaks=[]
fori,xinenumerate(histogram):
ifis_peakandx<
ifi-up_point>
2:
wave_peaks.append((up_point,i))
elifnotis_peakandx>
=threshold:
up_point=i
ifis_peakandup_point!
=-1andi-up_point>
4:
returnwave_peaks
#根据找出的波峰,分隔图片,从而得到逐个字符图片
defseperate_card(img,waves):
part_cards=[]
forwaveinwaves:
part_cards.append(img[:
wave[0]:
wave[1]])
returnpart_cards
#来自opencv的sample,用于svm训练
defdeskew(img):
m=cv2.moments(img)
ifabs(m['
mu02'
])<
1e-2:
returnimg.copy()
skew=m['
mu11'
]/m['
]
M=np.float32([[1,skew,-0.5*SZ*skew],[0,1,0]])
img=cv2.warpAffine(img,M,(SZ,SZ),flags=cv2.WARP_INVERSE_MAP|cv2.INTER_LINEAR)
returnimg
defpreprocess_hog(digits):
samples=[]
forimgindigits:
gx=cv2.Sobel(img,cv2.CV_32F,1,0)
gy=cv2.Sobel(img,cv2.CV_32F,0,1)
mag,ang=cv2.cartToPolar(gx,gy)
bin_n=16
bin=np.int32(bin_n*ang/(2*np.pi))
bin_cells=bin[:
10,:
10],bin[10:
:
10],bin[:
10,10:
],bin[10:
10:
mag_cells=mag[:
10],mag[10:
10],mag[:
],mag[10:
hists=[np.bincount(b.ravel(),m.ravel(),bin_n)forb,minzip(bin_cells,mag_cells)]
hist=np.hstack(hists)
#transformtoHellingerkernel
eps=1e-7
hist/=hist.sum()+eps
hist=np.sqrt(hist)
hist/=norm(hist)+eps
samples.append(hist)
returnnp.float32(samples)
#不能保证包括所有省份
provinces=[
"
zh_cuan"
"
川"
zh_e"
鄂"
zh_gan"
赣"
zh_gan1"
甘"
zh_gui"
贵"
zh_gui1"
桂"
zh_hei"
黑"
zh_hu"
沪"
zh_ji"
冀"
zh_jin"
津"
zh_jing"
京"
zh_jl"
吉"
zh_liao"
辽"
zh_lu"
鲁"
zh_meng"
蒙"
zh_min"
闽"
zh_ning"
宁"
zh_qing"
靑"
zh_qiong"
琼"
zh_shan"
陕"
zh_su"
苏"
zh_sx"
晋"
zh_wan"
皖"
zh_xiang"
湘"
zh_xin"
新"
zh_yu"
豫"
zh_yu1"
渝"
zh_yue"
粤"
zh_yun"
云"
zh_zang"
藏"
zh_zhe"
浙"
classStatModel(object):
defload(self,fn):
self.model=self.model.load(fn)
defsave(self,fn):
self.model.save(fn)
classSVM(StatModel):
def__init__(self,C=1,gamma=0.5):
self.model=cv2.ml.SVM_create()
self.model.setGamma(gamma)
self.model.setC(C)
self.model.setKernel(cv2.ml.SVM_RBF)
self.model.setType(cv2.ml.SVM_C_SVC)
#训练svm
deftrain(self,samples,responses):
self.model.train(samples,cv2.ml.ROW_SAMPLE,responses)
#字符识别
defpredict(self,samples):
r=self.model.predict(samples)
returnr[1].ravel()
classCardPredictor:
def__init__(self):
#车牌识别的部分参数保存在js中,便于根据图片分辨率做调整
f=open('
config.js'
)
j=json.load(f)
forcinj["
config"
]:
print(c)
ifc["
open"
self.cfg=c.copy()
break
else:
raiseRuntimeError('
没有设置有效配置参数'
def__del__(self):
self.save_traindata()
deftrain_svm(self):
#识别英文字母和数字
self.model=SVM(C=1,gamma=0.5)
#识别中文
self.modelchinese=SVM(C=1,gamma=0.5)
ifos.path.exists("
svm.dat"
):
self.model.load("
chars_train=[]
chars_label=[]
forroot,dirs,filesinos.walk("
train\\chars2"
iflen(os.path.basename(root))>
1:
continue
root_int=ord(os.path.basename(root))
forfilenameinfiles:
filepath=os.path.join(root,filename)
digit_img=cv2.imread(filepath)
digit_img=cv2.cvtColor(digit_img,cv2.COLOR_BGR2GRAY)
chars_train.append(digit_img)
#chars_label.append
(1)
chars_label.append(root_int)
chars_train=list(map(deskew,chars_train))
chars_train=preprocess_hog(chars_train)
#chars_train=chars_train.reshape(-1,20,20).astype(np.float32)
chars_label=np.array(chars_label)
print(chars_train.shape)
self.model.train(chars_train,chars_label)
svmchinese.dat"
self.modelchinese.load("
train\\charsChinese"
ifnotos.path.basename(root).startswith("
zh_"
pinyin=os.path.basename(root)
index=provinces.index(pinyin)+PROVINCE_START+1#1是拼音对应的汉字
chars_label.append(index)
#chars_train=chars_train.reshape(-1,20,20).astype(np.float32)
self.modelchinese.train(chars_train,chars_label)
defsave_traindata(self):
ifnotos.path.exists("
self.model.save("
ifnotos.path.exists("
self.modelchinese.save("
defaccurate_place(self,card_img_hsv,limit1,limit2,color):
row_num,col_num=card_img_hsv.shape[:
2]
xl=col_num
xr=0
yh=0
yl=row_num
#col_num_limit=self.cfg["
col_num_limit"
row_num_limit=self.cfg["
row_num_limit"
col_num_limit=col_num*0.8ifcolor!
="
green"
elsecol_num*0.5#绿色有渐变
foriinrange(row_num):
count=0
forjinrange(col_num):
H=card_img_hsv.item(i,j,0)
S=card_img_hsv.item(i,j,1)
V=card_img_hsv.item(i,j,2)
iflimit1<
H<
=limit2and34<
Sand46<
V:
count+=1
ifcount>
col_num_limit:
ifyl>
i:
yl=i
ifyh<
yh=i
row_num-row_num_limit:
ifxl>
j:
xl=j
ifxr<
xr=j
returnxl,xr,yh,yl
defpredict(self,car_pic):
iftype(car_pic)==type("
"
img=imreadex(car_pic)
img=car_pic
pic_hight,pic_width=img.shape[:
ifpic_width>
MAX_WIDTH:
resize_rate=MAX_WIDTH/pic_width
img=cv2.resize(img,(MAX_WIDTH,int(pic_hight*resize_rate)),interpolation=cv2.INTER_AREA)
blur=self.cfg["
blur"
#高斯去噪
ifblur>
img=cv2.GaussianBlur(img,(blur,blur),0)#图片分辨率调整
oldimg=img
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#equ=cv2.equalizeHist(img)
#img=np.hstack((img,equ))
#去掉图像中不会是车牌的区域
kernel=np.ones((20,20),np.uint8)
img_opening=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
img_opening=cv2.addWeighted(img,1,img_opening,-1,0);
#找到图像边缘
ret,img_thresh=cv2.threshold(img_opening,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
img_edge=cv2.Canny(img_thresh,100,200)
#使用开运算和闭运算让图像边缘成为一个整体
kernel=np.ones((self.cfg["
morphologyr"
],self.cfg["
morphologyc"
]),np.uint8)
img_edge1=cv2.morphologyEx(img_edge,cv2.MORPH_CLOSE,kernel)
img_edge2=cv2.morphologyEx(img_edge1,cv2.MORPH_OPEN,kernel)
#查找图像边缘整体形成的矩形区域,可能有很多,车牌就在其中一个矩形区域中
image,contours,hierarchy=cv2.findContours(img_edge2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours=[cntforcntincontoursifcv2.contourArea(cnt)>
Min_Area]
print('
len(contours)'
len(contours))
#一一排除不是车牌的矩形区域
car_contours=[]
forcntincontours:
rect=cv2.minAreaRect(cnt)
area_width,area_height=rect[1]
ifarea_width<
area_height:
area_width,area_height=area_height,area_width
wh_ratio=area_width/area_height
#print(wh_ratio)
#要求矩形区域长宽比在2到5.5之间,2到5.5是车牌的长宽比,其余的矩形排除
ifwh_ratio>
2andwh_ratio<
5.5:
car_contours.append(rect)
box=cv2.boxPoints(rect)
box=np.int0(box)
#oldimg=cv2.drawContours(oldimg,[box],0,(0,0,255),2)
#cv2.imshow("
edge4"
oldimg)
#print(rect)
print(len(car_contours))
print("
精确定位"
card_imgs=[]
#矩形区域可能是倾斜的矩形,需要矫正,以便使用颜色定位
forrectincar_contours:
ifrect[2]>
-1andrect[2]<
#创造角度,使得左、高、右、低拿到正确的值
angle=1
angle=rect[2]
rect=(rect[0],(rect[1][0]+5,rect[1][1]+5),angle)#扩大范围,避免车牌边缘被排除
heigth_point=right_point=[0,0]
left_point=low_point=[pic_width,pic_hight]
forpointinbox:
ifleft_point[0]>
point[0]:
left_point=point
iflow_point[1]>
point[1]:
low_point=point
ifheigth_point[1]<
heigth_point=point
ifright_point[0]<
right_point=point
ifleft_point[1]<
=right_point[1]:
#正角度
new_right_point=[right_point[0],heigth_point[1]]
pts2=np.float32([left_point,heigth_point,new_right_point])#字符只是高度需要改变
pts1=np.float32([left_point,heigth_point,right_point])
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(oldimg,M,(pic_width,pic_hight))
point_limit(new_right_point)
point_limit(heigth_point)
point_limit(left_point)
card_img=dst[int(left_point[1]):
int(heigth_point[1]),int(left_point[0]):
int(new_right_point[0])]
card_imgs.append(card_img)