机器视觉——车牌分割

利用openCV或其他工具编写程序实现对图片中的字符进行切割的操作。

实现过程

1、编写程序

   

    目标图片如下

 

根据展示的程序功能编写对应的程序:

第一步,读取显示图像的功能openCV已经提供了函数imread()和imshow(),代码如下

import cv2

import numpy as np

origineImage = cv2.imread('123456.jpg')

cv2.imshow('origin', origineImage)

cv2.waitKey(0)

第二步,将图像转换为灰度图,并进行阈值分割二值化图片去除图像深度数据:

grayimg=cv2.cvtColor(origineImage,cv2.COLOR_BGR2GRAY)

img1,thres=cv2.threshold(grayimg,130,255,cv2.THRESH_BINARY)

er=pointInvert(thres)

cv2.imshow('gray',grayimg)

cv2.imshow('thres',thres)

cv2.imshow('point',er)

cv2.waitKey(0)

第三步,编写水平投影和垂直投影的函数,上一个实验已经实现的图片的水平投影和垂直投影,我们直接将代码拿过来用就可以了:

水平投影:

def getHProjection(image):

    hProjection = image.copy()

    #图像高与宽

    (h,w)=image.shape

    #长度与图像高度一致的数组

    h_ = [0]*h

    #循环统计每一行白色像素的个数

    for y in range(0,h):

        for x in range(0,w):

            if image[y,x] == 0:

                h_[y]+=1

                hProjection[y,x]=255

    #绘制水平投影图像

    for y in range(0,h):

        for x in range(0,h_[y]):

            hProjection[y,x] = 0

    cv2.imshow('hProjection2',hProjection)

    cv2.waitKey(0)

    return h_

垂直投影:

def getVProjection(image):

    vProjection = image.copy()

    #图像高与宽

    (h,w) = image.shape

    #长度与图像宽度一致的数组

    w_ = [0]*w

    #循环统计每一列白色像素的个数

    for x in range(w):

        for y in range(h):

            if image[y,x] == 0:

                w_[x]+=1

                vProjection[y,x]=255

    #绘制垂直平投影图像

    for x in range(0,w):

        for y in range(h-w_[x],h):

            vProjection[y,x] = 0

    cv2.imshow('vProjection',vProjection)

    cv2.waitKey(0)

    return w_

编写测试代码测试结果:

H = getHProjection(er)

W = getVProjection(er)

第四步,得到每个字符的长宽存入数组中并根据数组在图像上画矩形框实现字符的切割:

for i in range(len(H)):

    if H[i] > 0 and start ==0:

        H_Start.append(i)

        start = 1

    if H[i] <= 0 and start == 1:

        H_End.append(i)

        start = 0

for i in range(len(H_Start)):

        #获取行图像

        cropImg = img[H_Start[i]:H_End[i], 0:w]

        #cv2.imshow('cropImg',cropImg)

        #对行图像进行垂直投影

        W = getVProjection(cropImg)

        Wstart = 0

        Wend = 0

        W_Start = 0

        W_End = 0

        for j in range(len(W)):

            if W[j] > 10 and Wstart ==0:

                W_Start =j

                Wstart = 1

                Wend=0

            if W[j] < 10 and Wstart == 1:

                W_End =j

                Wstart = 0

                Wend=1

            if Wend == 1:

                Position.append([W_Start,H_Start[i],W_End,H_End[i]])

                Wend =0

for m in range(len(Position)):

    cv2.rectangle(origineImage, (Position[m][0],Position[m][1]), (Position[m][2],Position[m][3]), (0 ,229 ,238), 1)

cv2.imshow('image',origineImage)

cv2.waitKey(0)

运行结果

 

 

 

 

 

问题及解决方法

1、矩形框的绘制及无用字符的去除

    解决方法:查资料找到openCV自带的矩形框绘制函数,理解函数中每个值对应的数据,正确输入数据就可以完成矩形框的绘制;无用字符也就是中间的点的去除花了不少时间去判断并实验,存储长宽数据的数组数量大,只能一个一个对着看,最后在w_数组中找到了合适的范围将中间的点去除掉。

实验总结

    这一次的实验在上一次实验的基础上只需要添加一个画矩形框的函数,而这个函数openCV中是已经给出了,我们要做的仅仅是找到矩形框的顶点并输入这个数据让程序在原图像上画出矩形框。

原文地址:https://www.cnblogs.com/zhangmingfeng/p/12895544.html