基于HyperLPR的车牌识别(十二)

2021SC@SDUSC

源代码下载地址:HyperLPR: HyperLRP是一个开源的、基于深度学习高性能中文车牌识别库,由北京智云视图科技有限公司开发,支持PHP、C/C++、Python语言,Windows/Mac/Linux/Android/IOS 平台。

源码配置的详情见第一篇分析

SimpleRecognizePlateByE2E源码如下:

def SimpleRecognizePlateByE2E(image):
    t0 = time.time()
    images = detect.detectPlateRough(image,image.shape[0],top_bottom_padding_rate=0.1)
    res_set = []
    for j,plate in enumerate(images):
        plate, rect, origin_plate  =plate
        plate  =cv2.resize(plate,(136,36*2))
        res,confidence = e2e.recognizeOne(origin_plate)
        print "res",res
 
        t1 = time.time()
        ptype = td.SimplePredict(plate)
        if ptype>0 and ptype<5:
            plate = cv2.bitwise_not(plate)
        image_rgb = fm.findContoursAndDrawBoundingBox(plate)
        image_rgb = fv.finemappingVertical(image_rgb)
        image_rgb = fv.finemappingVertical(image_rgb)
        cache.verticalMappingToFolder(image_rgb)
        res,confidence = e2e.recognizeOne(image_rgb)
        print res,confidence
        res_set.append([[],res,confidence])
 
        if confidence>0.7:
            image = drawRectBox(image, rect, res+" "+str(round(confidence,3)))
    return image,res_set

detectPlateRough(...)函数作用

image.shape[]数组含义如下:

image.shape[0], 图片垂直尺寸

image.shape[1], 图片水平尺寸

image.shape[2], 图片通道数

该函数用于粗略地初始化图片,并传给images对象,其中上下填充率默认为0.1

首先是打印出来一个传入image的shape值也就是图片的大小,针对上下填充率进行判断,高于0.2时报错。再将图片的高度,内边距,宽高比进行赋值。

再用resize对图片进行裁剪操作。用cvtColor来把图片转变为一个黑白的图片。最后使用了级联分类器进行模式识别,用于提取图片车牌特征。detectMultiScale是cv2中进行模式识别的函数,它能够对输入的图片进行识别,识别出所有待识别模式(在这里是车牌)的位置坐标和大小,将其用矩vector表示并返回,存储在watches。初步识别出车牌后,对车牌进行裁剪,方便下一步操作。

recognizeOne(…)函数

先对图片进行resize处理,随后将该图片执行转置操作。随后导入ocr部分的网络模型(keras模型) 其中Keras是一个高层神经网络API,为支持快速实验而生。该模型用于进行车牌具体识别,使用了卷积神经网络对图像进行识别。其中Conv2D是卷积神经网络相关函数,它的作用大概是建立一个卷积核,并且规定好卷积核的大小和步长,利用卷积核对图片做处理。Activation是卷积神经网络中的激活函数。MaxPool2D是池化层函数。

SimplePredict()函数

   该函数先对图片进行裁剪操作,再用astype进行强制类型转换防止溢出。针对这些图片进行预测,然后返回图像的维度的最大值。

bitwise_not(...)函数

bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1=0,~0=1

findContoursAndDrawBoundingBox(...)函数

该函数是一种有使用条件的方法,前提是车牌的6个字符不能有完全的粘连。首先是确定上下边界,把extend好的检测到的车牌区域提取出来。接着使用多个参数对这个区域进行多次自适应二值化。我们对opencv中adaptiveThreshold函数的k的参数从选择从-50变化到0。做15次二值化。接着对每次二值化的图像进行连通域分析寻找满足字符长宽比的轮廓。

接着我们要对下面的点做直线拟合,在做直线拟合之前特别的,我们要特别的介绍一下随机抽样一致(RANSAC)算法。在实际应用中获取到的数据,常常会包含有噪声数据,这些噪声数据会使对模型的构建造成干扰,我们称这样的噪声数据点为outliers,那些对于模型构建起积极作用的我们称它们为inliers,RANSAC做的一件事就是先随机的选取一些点,用这些点去获得一个模型(这个讲得有点玄,如果是在做直线拟合的话,这个所谓的模型其实就是斜率),然后用此模型去测试剩余的点,如果测试的数据点在误差允许的范围内,则将该数据点判为inlier,否则判为outlier。inliers的数目如果达到了某个设定的阈值,则说明此次选取的这些数据点集达到了可以接受的程度,否则继续前面的随机选取点集后所有的步骤,不断重复此过程,直到找到选取的这些数据点集达到了可以接受的程度为止,此时得到的模型便可认为是对数据点的最优模型构建。

由于在做连通域分析的时候,我们仅仅使用满足字符长宽比例的boundingbox作为判断条件,所以会带来一定的噪声。如下图又下角就存在着满足条件的错误点。所以RANSAC算法能帮助我们剔除这些噪声点。

我们使用RANSAC算法对上图中的点进行拟合。      

这样就找到了上边界和下边界,下面我们只需要把这个区域crop出来就行了。

finemappingVertical(...)函数

作者对图片执行了两次finemappingVertical操作。

该函数先使用resize函数将已裁剪的图片再进行裁剪操作。再使用astype函数来将原来灰度图颜色通道[0, 255]转化为float类型[0,1]。后self.modelFineMapping.predict函数输入66*16(float),输入进模型进行测试。该模型也是一个卷积神经网络模型,通过模型处理后,再次进行裁剪输出。keras网络模型:对车牌的左右边界进行回归。通过modelFineMapping.loadweights()函数加载模型文件。通过modelFineMapping.predict输出网络结果

verticalMappingToFolder(...)函数

hashlib.md5()函数获取image.data的md5加密对象,进行utf-8的加密。hexdigest()函数直接获取加密后的十六进制数据字符串值。故该函数先将图片中的数据进行加密,再将其作为保存图片的名称保存在finemapping文件夹下。后续再将经过粗定位,裁剪,精定位的图片再次通过recognizeOne()进行识别,得出车牌字符。最后插入res_set的尾部。

drawRectBox()函数

该函数用于打上boundingbox和标签(为之前verticalMappingToFolder(...)函数生成的字符串)。当处理好的文件可信度大于0.7时,将对一开始输入进行识别的图片中,框出识别出的车牌并显示车牌号码。

你可能感兴趣的:(python)