车牌定位(二)

写在前面的话: python中有很多腐蚀膨胀的集成库,cv2还是最常用的。这篇文章仅是从底层原理去理解这么做的意义,供学习理解使用。
简单介绍一下本节,主要是用python继续对图片进行预处理,主要是 腐蚀膨胀 还有这节就把车牌直接 提取 出来啦!!!

图片预处理

常用库就…

path = './huiimg.png'
im = Image.open(path).convert('L')
plt.imshow(im)
# 转换为数组
im_array = np.array(im)
width, height = im_array.shape

腐蚀

粗略的说,腐蚀可以使目标区域范围“变小”,其实质造成图像的边界收缩,可以用来消除小且无意义的目标物。式子表达为:
在这里插入图片描述
式子表示用结构B腐蚀A,需要注意的是B中需要定义一个原点,【而B的移动的过程与卷积核移动的过程一致,同卷积核与图像有重叠之后再计算一样】当B的原点平移到图像A的像元(x,y)时,如果B在(x,y)处,完全被包含在图像A重叠的区域,(也就是B中为1的元素位置上对应的A图像值全部也为1)则将输出图像对应的像元(x,y)赋值为1,否则赋值为0。

def erosion(ima,w,h):
    imb = np.copy(ima)
    for rept in range(5):
        for i in range(1,w-1):
            for j in range(1,h-1):
                if(ima[i,j] == 255):
                    flag = 0
                    for m in range(-1,2):
                        for n in range(-1,2):
                            if(ima[i+m,j+n] == 0):
                                flag += 1
                    if(flag > 3):
                        imb[i,j] = 0
    return imb
  • 图形点在其 3x3 邻域要有flag+1个点不是图形点则该点设为背景点(0)。
  • flag 参数可调节,根据之后的实验再进行变化去选取,所以可以把它变成形参,便于以后调节。

膨胀

粗略地说,膨胀会使目标区域范围 “变大”,将于目标区域接触的背景点合并到该目标物中,使目标边界向外部扩张。作用就是可以用来填补目标区域中某些空洞以及消除包含在目标区域中的小颗粒噪声。
在这里插入图片描述
结构B膨胀A,将结构元素B的原点平移到图像像元(x,y)位置。如果B在图像像元(x,y)处与A的交集不为空(也就是B中为1的元素位置上对应A的图像值至少有一个为1),则输出图像对应的像元(x,y)赋值为1,否则赋值为0。

def dilation(ima,w,h):
    imb = np.copy(ima)
    for rept in range(5):
        for i in range(1,w-1):
            for j in range(1,h-1):
                if(ima[i,j] == 0):
                    flag = 0
                    for m in range(-1,2):
                        for n in range(-1,2):
                            if(ima[i+m,j+n] == 255):
                                flag += 1
                                break
                    # 词出表明只要周围有1个白色那么原点就变为白色
                    if(flag > 0):
                        imb[i,j] = 255
    return imb
  • 背景点在其 3x3 邻域只要有一个点为图形点则该点设为图形点

开运算 & 闭运算

i. 开运算

开运算 = 先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)

  • 开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便。
  • 开运算是一个基于几何运算的滤波器。
  • 结构元素大小的不同将导致滤波效果的不同。
  • 不同的结构元素的选择导致了不同的分割,即提取出不同的特征。

ii. 闭运算

闭运算 = 先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)

  • 闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
  • 闭运算是通过填充图像的凹角来滤波图像的。
  • 结构元素大小的不同将导致滤波效果的不同。
  • 不同结构元素的选择导致了不同的分割。

车牌提取

此部分直接将车牌给截出来,先介绍第一种方法

i. 我们先统计出像素值为0的最大行以及最大列的像素个数。我们设置比较值为1/3最大值。即大于找到第一行及最后一行大于这个值得行数,以及第一列和最后一列大于这个值得列数。我们再设置一个阈值thred,则得出了行及列的标号。

'''
定位, y为行,x为列
'''
def get_location(w, h, thred):
    temp = np.zeros((400,1))
    flag = 0
    # 找出一行的最大值
    for i in range(w):
        temp[i] = 0
        for j in range(h):
            if imb_array[i,j] == 255:
                temp[i] += 1
    maxnum = (temp.max()) / 3
    for i in range(w):
        if flag == 0:
            if temp[i] > maxnum:
                y1 = i - thred
                flag = 1
        if flag == 1:
            if temp[i] == 0:
                y2 = i + thred
                flag = 0
                break
    # 找出一列
    for i in range(h):
        temp[i] = 0
        for j in range(w):
            if imb_array[j,i] == 255:
                temp[i] += 1
    maxnum = (temp.max()) / 3
    for i in range(h):
        if flag == 0:
            if temp[i] > maxnum:
                x1 = i - thred
                flag = 1
        if flag == 1:
            if temp[i] == 0:
                x2 = i + thred
                flag = 0
                break
    return x1,x2,y1,y2

得出结果:

VL, VH, HL, HH = get_location(new_w, new_h,0)
print(VL, VH, HL, HH)
c_w = VH - VL
c_h = HH - HL
print(c_w, c_h)

180 270 195 220
90 25

大家注意一下,我这张图传参0,并不代表这个值是合适的,最好取大一些,因为会有倾斜等等特殊状况

将它截出来,一起来看效果图吧!很nice!

box=( VL,HL,VH,HH )
region = imb.crop(box)
region2 = imb2.crop(box)
plt.imshow(region)
就是我们要的图啦,放张对比图吧
new_region = img.crop(box)
# plt.figure(figsize=(16.8))
plt.subplot(131)
plt.imshow(new_region)
plt.subplot(132)
plt.imshow(region)
plt.subplot(133)
plt.imshow(region2)

在这里插入图片描述
接下来就是分割字符串啦,且听下回分解~

ii. 这里介绍第二种方法

车牌由七个字符组成,在对候选区域对应的灰度化图像进行边缘检测二值化之后,正常情况下,在车牌水平投影区域内会出现较大的波峰,该波峰认为是车牌的上下边界.

一般取15较合适,从上下左右四个方向分别遍历,分别取出相应符合条件的行和列即可

P.S. 由于最近忙考试,这部分没有去改,放上一部分c的代码,其基本原理与上相差不多,效果的话也需要去用实践去检验,毕竟实践是检验真理的唯一标准嘛!

if(outimg[i*width+j-15]==0 && outimg[i*width+j-14]==255 && outimg[i*width+j]==255)
{
	y1=i-3;
	nflag = 1;
	j = width;
}

下一节直接分割字符串~

猜你喜欢

转载自blog.csdn.net/q18421896/article/details/85556762