基于-OpenCV-和-Python-车牌识别系统的设计与实现代码大全.pdf
- 文档编号:18633096
- 上传时间:2023-08-23
- 格式:PDF
- 页数:14
- 大小:527.46KB
基于-OpenCV-和-Python-车牌识别系统的设计与实现代码大全.pdf
《基于-OpenCV-和-Python-车牌识别系统的设计与实现代码大全.pdf》由会员分享,可在线阅读,更多相关《基于-OpenCV-和-Python-车牌识别系统的设计与实现代码大全.pdf(14页珍藏版)》请在冰点文库上搜索。
题目题目基于基于OpenCV和和Python车牌车牌识别系统的设计与实现识别系统的设计与实现11题目的主要研究内容题目的主要研究内容
(1)工作的主要描述利用python中自带的opencv库中的模式识别算法制作一个简易的模式识别系统,使用自己搜集到的数据集对模型进行训练,最终完成特征提取、分类等工作,并且在最后的推理过程中,实现了车牌识别的工作。
(2)系统流程图导入所需模块准备训练数据集车牌识别器推理12题目研究的工作基础或实验条题目研究的工作基础或实验条件件项目的编程环境为python,编译器使用pycharm2021.3x64,设计一个车牌识别系统,有GUI界面。
选择一张有车牌的图片后,完成车牌定位、倾斜校正、字符分割,最后通过k-NN算法对车牌的字母和数字进行识别,将识别结果在GUI界面中显示出来13数据集描述数据集描述车牌定位就是在图片中识别出哪个位置有车牌,是字符分割和字母数字识别的前提,是车牌识别系统的关键和难点。
:
例如,训练数据的目录结构树如下所示:
14特征特征提取提取过程描述过程描述1.对原始图像进行高斯模糊,减少噪点。
2.提取图像边缘。
首先将彩色图像转为灰度图gray,利用大核对灰度图进行开操作得到图像open,相当于对灰度图进行涂抹操作,将灰度图gray和开操作后的图像open按1:
-1的比例融合得到图像add,以上操作可以将大面积灰度值相似的地方置黑,可以减少车灯、背景、地面、挡风玻璃等细节。
接着使用canny算法对融合图像add提取边缘,得到图像canny。
3.使用横向长条作为核对边缘图像进行一次闭操作,得到图像close,相当于对边缘横向涂抹,因为一般视角车牌是宽大于高的矩形。
再对图像close进行一次开操作,得到图像open2,消除较细的线条和不大的竖向线条,从而将车牌位置的连通区域独立出来。
4.查找连通区域,通过最小外接矩形的宽高比25.5筛选合适的连通区域。
5.将最小外接矩形图像旋转矫正,上下左右向外扩展一点范围,避免连通区域没能覆盖车牌造成影响。
6.将连通区域原图转为HSV图像,确定图像的主要颜色,若不为蓝、黄、绿,则排除。
按照3种颜色对车牌进行精细定位,缩小范围。
7.再次通过图像宽高比2.25.3筛选合适的位置,至此车牌定位结束15K-NN分类分类算法算法在模式识别领域中,k-NN算法是一种用于分类和回归的非参数统计方法。
在k-NN分类算法中,输入包含k个最接近的特征空间的训练样本,输出是一个分类族群。
一个对象的分类是由其邻近样本占多数的类别确定的,k为正整数,通常为奇数。
k个最邻近样本中最多的分类类别决定了赋予该对象的类别,若k=1k=1k=1,则该对象的类别直接由最近的一个节点赋予。
k-NN算法是所有的机器学习算法中最简单的之一。
k个最邻近样本都是已经正确分类的对象,虽然没要求明确的训练步骤,但这也可以当作是此算法的一个训练样本集。
训练样本是多维特征空间向量,其中每个训练样本带有一个类别标签。
算法的训练阶段只包含存储的特征向量和训练样本的标签。
k-NN算法的缺点是对数据的局部结构非常敏感。
在分类阶段,k是一个常数,项目中选取k=7k=7k=7。
一般情况下,可以用欧氏距离作为距离度量。
在欧几里得空间中,k-NN算法分类会在类别分布不均时出现缺陷,也就是说,出现频率较多的样本将会影响测试样本的预测结果。
因为样本更多的类别更可能出现在测试点的K邻域,而测试点的属性又是通过k邻域内的样本计算出来的。
解决这个缺点的方法之一是在进行分类时将样本到k个近邻点的距离考虑进去。
k近邻点中每一个的分类都乘以与测试点之间距离的成反比的权重。
16主要程序代码主要程序代码fromtkinterimport*importcv2fromtkinter.filedialogimport*fromcv2import*fromnumpyimport*fromPILimportImageTk,Imageimportoperatorclassrecognition:
#oriImagedefopen(self):
img_path=askopenfilename(initialdir=./testImage,title=选择待识别图片选择待识别图片,filetypes=(jpg,*.jpg),(png,*.png)ifimg_path:
img=cv2.imdecode(fromfile(img_path,dtype=uint8),cv2.IMREAD_COLOR)self.show(img,400,oriImg)colors,lisencePlates=self.getROI(img)forminrange(len(lisencePlates):
self.show(lisencePlatesm,40,ROIImg)letters=self.getLetters(lisencePlatesm,colorsm)results=forletterinletters:
feature=self.getFeature(letter)result=self.sort(feature,trainingMat,labels,5)results.append(result)#print(result)recogResult=,.join(results)resultShow.configure(text=recogResult)defshow(self,img,newheight,label):
globaloriTk,ROITkimg=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)img=Image.fromarray(img)height=img.heightwidth=img.widthscaleRatio=newheight/heightnewwidth=int(width*scaleRatio)img=img.resize(newwidth,newheight),Image.ANTIALIAS)iflabel=oriImg:
self.oriTk=ImageTk.PhotoImage(image=img)label.configure(image=self.oriTk)eliflabel=ROIImg:
self.ROITk=ImageTk.PhotoImage(image=img)label.configure(image=self.ROITk)defgetROI(self,img):
#oriImg=Image.fromarray(img)#imgHeight=oriImg.height#imgWidth=oriImg.width#尺寸太大则缩小尺寸太大则缩小imgHeight,imgWidth=img.shape:
2ifimgHeight1000:
scaleRatio=1000/imgHeightimgHeight=1000imgWidth=int(imgWidth*scaleRatio)img=cv2.resize(img,(imgWidth,imgHeight),interpolation=cv2.INTER_AREA)oriImg=img#保存原图副本保存原图副本img=cv2.GaussianBlur(img,(3,3),0)#高斯模糊高斯模糊#print(img)gaussianImg=img#保存副本保存副本img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转灰度图转灰度图#imshow(gray,img)kernel=ones(20,20),uint8)imgOpen=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)#开操作,突出黑开操作,突出黑#imshow(open,imgOpen)img=cv2.addWeighted(img,1,imgOpen,-1,0)#图像融合图像融合#imshow(add,img)ret,img=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)#二值化二值化img=cv2.Canny(img,100,200)#canny算法查找边缘算法查找边缘#imshow(canny,img)kernel=ones(4,19),uint8)img=cv2.morphologyEx(img,MORPH_CLOSE,kernel)#闭操作,横向涂抹闭操作,横向涂抹#imshow(close,img)#kernel=ones(4,25),uint8)img=cv2.morphologyEx(img,MORPH_OPEN,kernel)#开操作,去除细线开操作,去除细线#imshow(open2,img)#查找连通区域查找连通区域try:
contours,hierarchy=cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)exceptValueError:
image,contours,hierarchy=cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)contours=cntforcntincontoursifcv2.contourArea(cnt)2000#排除面积太小的连通区域排除面积太小的连通区域print(numberofbigcontours:
len(contours)#通过长宽比排除比例不适的连通区域通过长宽比排除比例不适的连通区域rightRatioRects=forcntincontours:
rect=cv2.minAreaRect(cnt)#最小内接矩形最小内接矩形(x_center,y_center),(w,h),thetaw,h=rect1ifwh:
width,height=h,welse:
width,height=w,hratio=width/heightif2ratioh:
#宽大于高,顺时针旋转宽大于高,顺时针旋转width,height=w,hmatRotate=cv2.getRotationMatrix2D(box00,box01),rect2,1)img=cv2.warpAffine(oriImg,matRotate,(imgWidth+100,imgHeight+100)#扩大范围扩大范围ifint(box00)-extraXimgWidth+99:
maxX=imgWidth+99else:
maxX=int(box00)+int(width)+extraXifint(box01)-int(height)-extraYimgHeight+99:
maxY=imgHeight+99else:
maxY=int(box01)+extraYelse:
#宽小于高,逆时针旋转宽小于高,逆时针旋转width,height=h,wmatRotate=cv2.getRotationMatrix2D(box00,box01),-90+rect2,1)img=cv2.warpAffine(oriImg,matRotate,(imgWidth+100,imgHeight+100)#imshow(rotate,img)#扩大范围扩大范围ifint(box00)-extraXimgWidth+99:
maxX=imgWidth+99else:
maxX=int(box00)+int(width)+extraXifint(box01)-extraYimgHeight+99:
maxY=imgHeight+99else:
maxY=int(box01)+int(height)+extraYimg=imgminY:
maxY,minX:
maxX#imshow(str(rect),img)rotatedRects.append(img)#利用颜色排除不是车牌的区域,并进行较精细定位利用颜色排除不是车牌的区域,并进行较精细定位colors=lisencePlates=forimginrotatedRects:
green=yellow=blue=0hsvImg=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)row,col=hsvImg.shape:
2pixelCount=row*col#print(pixelcount:
pixelCount)foriinrange(row):
forjinrange(col):
H=hsvImg.item(i,j,0)S=hsvImg.item(i,j,1)V=hsvImg.item(1,j,2)if15=H=60andV=45:
yellow+=1elif65=H=15andV=65:
green+=1elif100=H=55andV=40:
blue+=1ifyellowgreenandyellowblueandyellowpixelCount*0.45:
xl,xr,yh,yl=self.fineMap(yellow,hsvImg)img=imgyh:
yl,xl:
xrh,w=img.shape:
2if2.2w/hyellowandbluegreenandbluepixelCount*0.45:
xl,xr,yh,yl=self.fineMap(blue,hsvImg)img=imgyh:
yl,xl:
xrh,w=img.shape:
2if2.2w/hyellowandgreenblueandgreenpixelCount*0.35:
xl,xr,yh,yl=self.fineMap(green,hsvImg)img=imgyl-int(yl-yh)*4/3):
yl,xl:
xrh,w=img.shape:
2if2.2w/h5.3:
lisencePlates.append(img)colors.append(green)#imshow(str(img),img)print(numoflisenceplate:
+str(len(lisencePlates)returncolors,lisencePlates#精细定位精细定位deffineMap(self,color,hsvImg):
ifcolor=yellow:
limit1=15limit2=30limitS=60limitV=45elifcolor=green:
limit1=65limit2=90limitS=15limitV=65elifcolor=blue:
limit1=100limit2=120limitS=55limitV=40row_num,col_num=hsvImg.shape:
2xl=col_num-1xr=0yh=row_num-1yl=0#col_num_limit=self.cfgcol_num_limitrow_num_limit=row_num*0.5ifcolor!
=greenelserow_num*0.3#绿色有渐变绿色有渐变col_num_limit=col_num*0.3#按行按行foriinrange(row_num):
count=0forjinrange(col_num):
H=hsvImg.item(i,j,0)S=hsvImg.item(i,j,1)V=hsvImg.item(i,j,2)iflimit1=H=limitSandV=limitV:
count+=1ifcountcol_num_limit:
ifyhi:
yh=iifyli:
yl=i#按列按列forjinrange(col_num):
count=0foriinrange(row_num):
H=hsvImg.item(i,j,0)S=hsvImg.item(i,j,1)V=hsvImg.item(i,j,2)iflimit1=H=limitSandV=limitV:
count+=1ifcountrow_num_limit:
ifxlj:
xl=jifxrj:
xr=jreturnxl,xr,yh,yl#二值化,去铆钉,字符分割二值化,去铆钉,字符分割defgetLetters(self,img,color):
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转灰度图转灰度图#二值化二值化ifcolor=blue:
ret,img=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)elifcolor=yelloworcolor=green:
ret,img=cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)#去铆钉去铆钉rowNum,colNum=img.shape:
2foriinrange(rowNum):
previousPixel=-1jump=0forjinrange(colNum):
ifpreviousPixel=-1:
previousPixel=imgijelse:
ifpreviousPixel!
=imgij:
jump+=1previousPixel=imgijifjump8:
forjinrange(colNum):
imgij=0#字符分割字符分割accumulation=img.sum(axis=0)max,min=accumulation.max(axis=0),accumulation.min(axis=0)accumulation=(accumulation-min)/(max-min)#print(accumulation)successive=intervalPre=isPreviousLess=0forminrange(len(accumulation):
ifisPreviousLess:
ifaccumulationm=0.2:
successive.append(m)else:
isPreviousLess=0intervalPre.append(successive)successive=else:
ifaccumulationmintervalLen:
intervalLen=len(intervalPren)bigInterval=intervalPrenbigIntervalIndex=n#找到最大间隔的前一个间隔,即省简称和字母之间的间隔找到最大间隔的前一个间隔,即省简称和字母之间的间隔ifbigIntervalIndex=1:
minIndex=self.findInterval(accumulation,intervalPrebigIntervalIndex-1)img=img:
minIndex:
#截取字母区域截取字母区域contours,heirachy=cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#获取连通区域获取连通区域#通过面积找到字母连通区域通过面积找到字母连通区域ifcolor=green:
cntNum=7else:
cntNum=6list=forminrange(len(contours):
tuple=(m,cv2.contourArea(contoursm)list.append(tuple)list.sort(key=lambdax:
x1,reverse=True)bigCnts=#字母连通区域字母连通区域forninrange(cntNum):
bigCnts.append(contourslistn0)#通过通过x坐标排序坐标排序list=forninrange(cntNum):
#外接矩形外接矩形x,y,width,height=cv2.boundingRect(bigCntsn)tuple=(n,x)list.append(tuple)list.sort(key=lambdax:
x1)cnts=#从左到右,字母连通区域从左到右,字母连通区域forninrange(cntNum):
cnts.append(bigCntslistn0)#裁剪裁剪letters=forcntincnts:
x,y,width,height=cv2.boundingRect(cnt)letter=imgy:
y+height,x:
x+widthletter=cv2.resize(letter,(32,64),interpolation=cv2.INTER_CUBIC)letters.append(letter)#imshow(str(cnt),letter)returnletters#print(intervalPre)#print(minIndex)#imshow(img,gaussianImg)#imshow(img,img)deffindInterval(self,accumulation,intervalPre):
min=1#最小值最小值forminrange(len(intervalPre):
ifaccumulationintervalPremmin:
min=accumulationintervalPremminIndex=intervalPremreturnminIndexdefgetFeature(self,img):
feature=foriinrange(64):
forjinrange(32):
ifimgi,j=0:
pixel=0else:
pixel=1feature.append(pixel)returnfeature#构建训练集构建训练集defcreateTrainSet(self):
labels=fileList=os.listdir(train)m=len(fileList)trainingMat=zeros(m,2048)foriinrange(m):
fileName=fileListilabels.append(self.getNumLabel(fileName)ori=cv2.imread(train/%s%fileName)#读取训练样本读取训练样本img_gray=cv2.cvtColor(ori,cv2.COLOR_BGR2GRAY)ret,img_bin=cv2.threshold(img_gray,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)#二值化二值化#img=skewCorrection(img_bin)#倾斜校正倾斜校正img=self.crop(img_bin)trainingMati,:
=self.getFeature(img)returnlabels,trainingMat#由图像名称得到数字类别由图像名称得到数字类别defgetNumLabel(self,file_name):
fileStr=file_name.split(.)0#根据文件名中的字符根据文件名中的字符.进行切片进行切片numLabel=fileStr.split(_)0#根据文件切片结果中的根据文件切片结果中
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 OpenCV Python 车牌 识别 系统 设计 实现 代码 大全