Skip to content

Latest commit

 

History

History
346 lines (241 loc) · 8.64 KB

实验5车牌字符.md

File metadata and controls

346 lines (241 loc) · 8.64 KB

实验五、简单车牌字符切割

一、 题目描述

对下面的图片进行切割操作,请详细地记录每一步操作的步骤。

车牌识别系统(Vehicle License Plate Recognition,VLPR) 是计算机视频图像识别技术在车辆牌照识别中的一种应用。

车牌号检测需要大致分为四个部分:

  • 1.车辆图像获取
  • 2.车牌定位、
  • 3.车牌字符分割
  • 4.车牌字符识别

二、 实现过程

1.图片读取

import numpy as np
import cv2 

img=cv2.imread("1.png",0)

2.图片反转

#实现图片反色功能
def PointInvert(img):
    height, width = img.shape        #获取图片尺寸
    for i in range(height):
        for j in range(width):
            pi = img[i, j]
            img[i, j] = 255 - pi
    return img
img=PointInvert(img)
#显示图片
cv2.imshow('original', img)
key = cv2.waitKey(0)
if key==27: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()

3.阈值操作

ret,img1=cv2.threshold(img,100,255,cv2.THRESH_BINARY)

#显示图片
cv2.imshow('original', img1)
key = cv2.waitKey(0)
if key==27: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()

4.图像投影

#返回图像的高和宽
(h,w)=img1.shape

#初始化一个跟图像高一样长度的数组,用于记录每一行的黑点个数
h_h =[0]*h

for i in range(0,h):          #遍历每一行
    for j in range(0,w):      #遍历每一列
        if img1[i,j]==0:      #判断该点是否为黑点,0代表黑点
            h_h [i]+=1           #该行的计数器加一
            img1[i,j]=255     #将其改为白点,即等于255
for i in range(0,h):          #遍历每一行
    for j in range(0,h_h [i]):   #从该行应该变黑的最左边的点开始向最右边的点设置黑点
        img1[i,j]=0           #设置黑点
cv2.imshow("img",img1) 
cv2.waitKey(0) 
cv2.destroyAllWindows()

ret,img1=cv2.threshold(img,100,255,cv2.THRESH_BINARY)

#初始化一个跟图像宽一样长度的数组,用于记录每一列的黑点个数
w_w  =[0]*w

for i in range(0,w):           #遍历每一列  
    for j in range(0,h):       #遍历每一行
        if img1[j,i]==0:       #判断该点是否为黑点,0代表是黑点
            w_w [i]+=1            #该列的计数器加1
            img1[j,i]=255      #记录完后将其变为白色,即等于255
for i in range(0,w):           #遍历每一列
    for j in range(h-w_w [i],h):  #从该列应该变黑的最顶部的开始向最底部设为黑点
        img1[j,i]=0            #设为黑点
cv2.imshow("img",img1) 
cv2.waitKey(0) 
cv2.destroyAllWindows()

5.获取上下宽度

for i in range(0,len(h_h)-1):
    if(h_h[i]==0 and h_h[i+1]!=0):
        t1=i

for i in range(0,len(h_h)-1):
    if(h_h[i]!=0 and h_h[i+1]==0):
        t2=i

6.获取每个字符的左右宽度

a=[]
for i in range(0,len(w_w)-1):
    if(w_w[i]==0 and w_w[i+1]!=0):
        a.append(i)
b=[]
for i in range(0,len(w_w)-1):
    if(w_w[i]!=0 and w_w[i+1]==0):
        b.append(i)
        
ar=[]        
for x in range(0,len(a)):
    ar.append(b[x]-a[x])
avg=sum(ar)/len(a)                      #得到宽度平均值
for i in ar:
    if(i<avg):
        del a[ar.index(i)]              #删除小于平均值的宽度
        del b[ar.index(i)]

7.切割字符

imgo=cv2.imread("1.png",1)
for i in range(0,len(a)):
    cv2.rectangle(imgo,(a[i],t1),(b[i],t2),(0,33,255),1)

cv2.imshow('original', imgo)
key = cv2.waitKey(0)
if key==27: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()

三、 运行结果(效果)

​ ### 1.原图

image-20200514122519843

2.二值化

image-20200514122542410

3.水平投影

image-20200514122610183

4.垂直投影

image-20200514122626143

5.最终结果

image-20200514123238460

image-20200514122650597

中级

1.读取图片,将图片四周设为255

#水平投影
import numpy as np
import cv2 

#实现图片反色功能
def PointInvert(img):
    height, width = img.shape        #获取图片尺寸
    for i in range(height):
        for j in range(width):
            pi = img[i, j]
            img[i, j] = 255 - pi
    return img


img=cv2.imread("2.png",0)

img=PointInvert(img)
img[0:23]=255
img[123:141]=255
img[:,0:10]=255
img[:,490:499]=255

#显示图片
cv2.imshow('original', img)

2.开运算 清楚多余的部分

key = cv2.waitKey(0)
if key==27: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()

ret,img1=cv2.threshold(img,100,255,cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 定义结构元素


opening = cv2.morphologyEx(img1, cv2.MORPH_OPEN, kernel)  # 开运算



#显示图片
cv2.imshow('original', opening)
key = cv2.waitKey(0)
if key==27: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()

#返回图像的高和宽
(h,w)=img1.shape

#初始化一个跟图像高一样长度的数组,用于记录每一行的黑点个数
h_h =[0]*h

for i in range(0,h):          #遍历每一行
    for j in range(0,w):      #遍历每一列
        if img1[i,j]==0:      #判断该点是否为黑点,0代表黑点
            h_h [i]+=1           #该行的计数器加一
            img1[i,j]=255     #将其改为白点,即等于255
for i in range(0,h):          #遍历每一行
    for j in range(0,h_h [i]):   #从该行应该变黑的最左边的点开始向最右边的点设置黑点
        img1[i,j]=0           #设置黑点
cv2.imshow("img",img1) 
cv2.waitKey(0) 
cv2.destroyAllWindows()

ret,img1=cv2.threshold(img,100,255,cv2.THRESH_BINARY)

#初始化一个跟图像宽一样长度的数组,用于记录每一列的黑点个数
w_w  =[0]*w

for i in range(0,w):           #遍历每一列  
    for j in range(0,h):       #遍历每一行
        if img1[j,i]==0:       #判断该点是否为黑点,0代表是黑点
            w_w [i]+=1            #该列的计数器加1
            img1[j,i]=255      #记录完后将其变为白色,即等于255
for i in range(0,w):           #遍历每一列
    for j in range(h-w_w [i],h):  #从该列应该变黑的最顶部的开始向最底部设为黑点
        img1[j,i]=0            #设为黑点
        
cv2.imshow("img",img1) 
cv2.waitKey(0) 
cv2.destroyAllWindows()
print(img1.shape)

3.获取每个字符的左右和上下宽度

for i in range(0,len(h_h)-1):
    if(h_h[i]==0 and h_h[i+1]!=0):
        t1=i

for i in range(0,len(h_h)-1):
    if(h_h[i]!=0 and h_h[i+1]==0):
        t2=i
    

a=[]
for i in range(0,len(w_w)-1):
    if(w_w[i]==0 and w_w[i+1]!=0):
        a.append(i)
b=[]
for i in range(0,len(w_w)-1):
    if(w_w[i]!=0 and w_w[i+1]==0):
        b.append(i)
        
ar=[]        
for x in range(0,len(a)):
    ar.append(b[x]-a[x])
avg=sum(ar)/len(a)                      #得到宽度平均值
for i in ar:
    if(i<avg):
        del a[ar.index(i)]              #删除小于平均值的宽度
        del b[ar.index(i)]
        

4.切割图片

img=cv2.imread("2.png",0)
img=PointInvert(img)

ret,img1=cv2.threshold(img,100,255,cv2.THRESH_BINARY)
for i in range(0,len(a)):
    cv2.rectangle(img,(a[i],t1),(b[i],t2),(0,33,255),1)

cv2.imshow('original', img)
key = cv2.waitKey(0)
if key==27: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()        

image-20200514174324141

image-20200514174346206

image-20200514174407464

四、 问题及解决方法

车牌中间的圆点也被算进去了,解决方法:将小圆点的宽度与其他方框的宽度进行比较,剔除小圆点。

五、 实验总结

在实际开发与应用中,我们会遇到很多无法预测的问题,我们需要将理论与实践相结合。