数字图像处理--车牌识别

这篇具有很好参考价值的文章主要介绍了数字图像处理--车牌识别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数字图像处理–车牌识别

主要内容

实现车牌识别

算法流程

本文中,车牌识别具体流程设计以及算法使用主要分为以下几步。
1、读取源车牌图像。
2、对原始车牌图像进行预处理:灰度化,运用基于几何运算的滤波器(开运算)消除毛刺噪声。
3、二值化操作。
4、利用canny边缘检测算法消除小的区域保留大的区域。
5、通过颜色识别判断定位车牌位置。
6、利用掩膜处理对定位车牌后的图像进行分割,直接分割出车牌。
7、再次对车牌进行二值化处理。
8、分割字符。
9、对分割字符进行神经网络模型匹配,输出车牌字符串。
针对上述实验设计步骤,做出实验流程图,如下图所示。
基于数字图像处理的车牌识别技术,数字图像处理,python,计算机视觉,opencv,图像处理

源代码

上代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager
import ddddocr


#读取字体文件
font = font_manager.FontProperties(fname=r".\OPPOSans-Heavy.ttf")


class Get_license():

    #图像拉伸函数
    def stretch(self, img):

        maxi = float(img.max())
        mini = float(img.min())

        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                img[i, j] = (255 / (maxi - mini) * img[i, j] - (255 * mini) / (maxi - mini))

        return img

    #二值化处理函数
    def dobinaryzation(self, img):

        maxi = float(img.max())
        mini = float(img.min())

        x = maxi - ((maxi - mini) / 2)
        #二值化,返回阈值ret和二值化操作后的图像thresh
        ret, thresh = cv2.threshold(img, x, 255, cv2.THRESH_BINARY)
        #返回二值化后的黑白图像
        return thresh

    #寻找矩形的轮廓
    def find_rectangle(self, contour):

        y, x = [],[]

        for p in contour:
            y.append(p[0][0])
            x.append(p[0][1])

        return [min(y), min(x), max(y), max(x)]

    #定位车牌号
    def locate_license(self, img, afterimg):

        contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        #找出最大的三个区域
        block = []
        for c in contours:
            #找出轮廓的左上点和右下点
            #由此计算它的面积和长度比
            r = self.find_rectangle(c)
            a = (r[2] - r[0]) * (r[3] - r[1])  #面积
            s = (r[2] - r[0]) * (r[3] - r[1])  #长度比

            block.append([r, a, s])

        #选出面积最大的3个区域
        block = sorted(block, key=lambda b: b[1])[-3:]

        #使用颜色识别判断找出最像车牌的区域
        maxweight, maxindex = 0, -1
        for i in range(len(block)):
            b = afterimg[block[i][0][1]:block[i][0][3], block[i][0][0]:block[i][0][2]]
            #BGR转HSV
            hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)
            #蓝色车牌的范围
            lower = np.array([100, 50, 50])
            upper = np.array([140, 255, 255])
            #根据阈值构建掩膜
            mask = cv2.inRange(hsv, lower, upper)
            #统计权值
            w1 = 0
            for m in mask:
                w1 += m / 255

            w2 = 0
            for n in w1:
                w2 += n

            #选出最大权值的区域
            if w2 > maxweight:
                maxindex = i
                maxweight = w2

        return block[maxindex][0]

    #预处理函数
    def find_license(self, img):

        m = 400 * img.shape[0] / img.shape[1]

        #压缩图像
        img = cv2.resize(img, (400, int(m)), interpolation=cv2.INTER_CUBIC)

        #BGR转换为灰度图像
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        #灰度拉伸
        stretchedimg = self.stretch(gray_img)

        '''进行开运算,用来去除噪声'''
        r = 16
        h = w = r * 2 + 1
        kernel = np.zeros((h, w), np.uint8)
        cv2.circle(kernel, (r, r), r, 1, -1)
        #开运算
        openingimg = cv2.morphologyEx(stretchedimg, cv2.MORPH_OPEN, kernel)
        #获取差分图,两幅图像做差  cv2.absdiff('图像1','图像2')
        strtimg = cv2.absdiff(stretchedimg, openingimg)

        #图像二值化
        binaryimg = self.dobinaryzation(strtimg)

        #canny边缘检测
        canny = cv2.Canny(binaryimg, binaryimg.shape[0], binaryimg.shape[1])

        '''消除小的区域,保留大块的区域,从而定位车牌'''
        #进行闭运算
        kernel = np.ones((5, 19), np.uint8)
        closingimg = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)

        #进行开运算
        openingimg = cv2.morphologyEx(closingimg, cv2.MORPH_OPEN, kernel)

        #再次进行开运算
        kernel = np.ones((11, 5), np.uint8)
        openingimg = cv2.morphologyEx(openingimg, cv2.MORPH_OPEN, kernel)

        #消除小区域,定位车牌位置
        rect = self.locate_license(openingimg, img)

        return rect, img

    #图像分割函数
    def cut_license(self, afterimg, rect):

        #转换为宽度和高度
        rect[2] = rect[2] - rect[0]
        rect[3] = rect[3] - rect[1]
        rect_copy = tuple(rect.copy())
        #创建掩膜
        mask = np.zeros(afterimg.shape[:2], np.uint8)
        #创建背景模型  大小只能为13*5,行数只能为1,单通道浮点型
        bgdModel = np.zeros((1, 65), np.float64)
        #创建前景模型
        fgdModel = np.zeros((1, 65), np.float64)
        #分割图像
        cv2.grabCut(afterimg, mask, rect_copy, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
        mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
        img_show = afterimg * mask2[:, :, np.newaxis]
        #cv2.imshow('111',img_show)
        return img_show


class Segmentation():
    def __init__(self, cutimg):

        #1、读取图像,并把图像转换为灰度图像并显示
        # cutimg = cv2.imread("3.jpg")  #读取图片
        img_gray = cv2.cvtColor(cutimg, cv2.COLOR_BGR2GRAY)  #转换了灰度化
        #cv2.imshow('gray', img_gray)   #显示图片
        #cv2.waitKey(0)

        #2、将灰度图像二值化,设定阈值是100
        self.img_thre = img_gray
        cv2.threshold(img_gray, 100, 255, cv2.THRESH_BINARY_INV, self.img_thre)

        #cv2.waitKey(0)

        #3、保存黑白图片
        cv2.imwrite('thre_res.png', self.img_thre)

        #4、分割字符
        self.white = []               #记录每一列的白色像素总和
        self.black = []               #黑色
        self.height = self.img_thre.shape[0]
        self.width = self.img_thre.shape[1]
        self.white_max = 0
        self.black_max = 0
        #计算每一列的黑白色像素总和
        for i in range(self.width):
            s = 0                     #这一列白色总数
            t = 0                     #这一列黑色总数
            for j in range(self.height):
                if self.img_thre[j][i] == 255:
                    s += 1
                if self.img_thre[j][i] == 0:
                    t += 1
            self.white_max = max(self.white_max, s)
            self.black_max = max(self.black_max, t)
            self.white.append(s)
            self.black.append(t)

        self.arg = False                #False表示白底黑字;True表示黑底白字
        if self.black_max > self.white_max:
            self.arg = True

    def heibai(self):
        return self.img_thre


    def find_end(self, start_):
        end_ = start_ + 1
        for m in range(start_ + 1, self.width - 1):
            if (self.black[m] if self.arg else self.white[m]) > (
            0.85 * self.black_max if self.arg else 0.85 * self.white_max):
                end_ = m
                break
        return end_

    def display(self):
        #img_list = []
        n = 1
        plt.figure()
        img_num = 0
        while n < self.width - 2:
            n += 1
            if (self.white[n] if self.arg else self.black[n]) > (
            0.15 * self.white_max if self.arg else 0.15 * self.black_max):
                #上面这些判断用来辨别是白底黑字还是黑底白字

                start = n
                end = self.find_end(start)
                n = end

                if end - start > 5:
                    cj = self.img_thre[1:self.height, start:end]
                    img_num += 1
                    cj = cv2.cvtColor(cj, cv2.COLOR_RGB2BGR)

                    plt.figure(2)
                    plt.subplot(2, 4, img_num)
                    plt.title('{}'.format(img_num))
                    plt.imshow(cj)
        plt.show()
        return self.img_thre


if __name__ == '__main__':

    #读取源图像
    img = cv2.imread('8.png')
    img1 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)

    #绘图
    plt.figure(1)
    plt.suptitle('车牌识别',fontproperties=font)
    plt.subplot(2, 3, 1)
    plt.title('原始图像', fontproperties=font)
    plt.imshow(img1)

    #预处理图像
    license = Get_license()
    rect, afterimg = license.find_license(img)
    afterimg = cv2.cvtColor(afterimg, cv2.COLOR_RGB2BGR)

    plt.subplot(2, 3, 2)
    plt.title('预处理后图像', fontproperties=font)
    plt.imshow(afterimg)

    #车牌号打框
    cv2.rectangle(afterimg, (rect[0], rect[1]), (rect[2], rect[3]), (0, 255, 0), 1)
    x1, y1, x2, y2 = int(rect[0]), int(rect[1]), int(rect[2]), int(rect[3])
    print('车牌框出:',x1, x2, y1, y2)
    plt.subplot(2, 3, 3)
    plt.title('车牌框出', fontproperties=font)
    plt.imshow(afterimg)

    #背景去除
    cutimg = license.cut_license(afterimg, rect)
    plt.subplot(2, 3, 4)
    plt.title('车牌背景去除', fontproperties=font)
    plt.imshow(cutimg)
    # print(int(_rect[0]), int(_rect[3]), int(_rect[2]), int(_rect[1]))
    print('车牌背景去除',x1, y1, x2, y2)

    #开始分割车牌
    # cutimg = cutimg[140:165, 151:240]
    cutimg = cutimg[y1 + 3:y2 - 3, x1 - 1:x2 - 3]
    # cutimg = cutimg[int(_rect[0]):int(_rect[3]),int(_rect[2]):int(_rect[1])]
    print('cutimg:',cutimg)
    height, width = cutimg.shape[:2]
    cutimg1 = cv2.resize(cutimg, (2 * width, 2 * height), interpolation=cv2.INTER_CUBIC)
    plt.subplot(2, 3, 5)
    plt.title('分割车牌与背景', fontproperties=font)
    plt.imshow(cutimg)

    #字符切割
    seg = Segmentation(cutimg)
    plt.subplot(2, 3, 6)
    img_hei = seg.heibai()
    img_hei = cv2.cvtColor(img_hei, cv2.COLOR_RGB2BGR)
    plt.title('车牌二值化处理', fontproperties=font)
    plt.imshow(img_hei)
    seg.display()
    plt.show()

    #打印车牌
    ocr = ddddocr.DdddOcr()
    with open('thre_res.png', 'rb') as f:
        image = f.read()
    res = ocr.classification(image)
    print(res)



实现结果

选取车牌照片,成功完成了对车牌号码的识别。如下图所示,即是原始图像到最后分割车牌与背景后的图片显示。

基于数字图像处理的车牌识别技术,数字图像处理,python,计算机视觉,opencv,图像处理
接着,对二值化处理过后的图片进行字符分割,所得结果如下图所示。
基于数字图像处理的车牌识别技术,数字图像处理,python,计算机视觉,opencv,图像处理
最后,通过利用ddddocr图片识别库对每个字符进行匹配。从而,实现字符图片到文本转换,成功打印输出车牌号码。
基于数字图像处理的车牌识别技术,数字图像处理,python,计算机视觉,opencv,图像处理
注意:选取其他照片后,可能需要微调代码里面 (车牌号打框)的参数值。就是图片局限性有点大。希望后续有小伙伴提出更泛化的代码实现!!!文章来源地址https://www.toymoban.com/news/detail-779225.html

到了这里,关于数字图像处理--车牌识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数字图像处理之matlab大作业:车牌识别

    1、基于模板的车牌识别,带GUI GitHub - joeyos/LicensePlateRecognition: License plate recognition 2、基于模板的车牌识别,注释详细 https://github.com/hangxyz/License-Plate-Recognition-by-MATLAB 3、其他优秀作品 1)董同学:带语音播报的车牌识别 车牌识别-基于模板匹配_勇敢歪歪的博客-CSDN博客_车牌识

    2024年02月08日
    浏览(45)
  • 【图像处理】基于MATLAB的RGB车牌识别

    目录 基于MATLAB的RGB车牌识别 基于MATLAB的RGB车牌识别通常可以分为以下步骤: 读入待处理图像,将RGB图像转换为HSV图像; 提取HSV图像中的Hue和Saturation通道; 利用颜色索引表的方式对提取出的Hue和Saturation进行阈值分割,得到二值化图像; 对二值化图像进行形态学操作,实现

    2023年04月22日
    浏览(48)
  • 人工智能|深度学习——基于数字图像处理和深度学习的车牌定位

    车牌识别Vehicle License Plate Recognition VLPR) 是从一张或一系列数字图片中自动定位车牌区域并提取车牌信息的图像识别技术。车牌识别 以数字图像处理、模式识别、计算机视觉等技术为基础,是现代智能交通系统的重要组成部分,广泛应用于日常生活中,如 停车场收 费管理,车

    2024年02月21日
    浏览(46)
  • 基于FPGA的车牌识别,其中包括常规FPGA图像处理算法

    基于FPGA的车牌识别,其中包括常规FPGA图像处理算法:         rgb转yuv,        sobel边缘检测,        腐蚀膨胀,        特征值提取与卷积模板匹配。 有bit流可以直接烧录实验。 保证无错误,完好,2018.3vivado版本,正点达芬奇Pro100t,板卡也可以自己更改移植一下。 所

    2024年04月14日
    浏览(52)
  • 33、基于STM32单片机车牌识别系统摄像头图像处理系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、程序源码 七、资料包括 随着汽车工业的迅猛发展,我国汽车拥有量急剧增加。停车场作为交通设施的组成部分,随着交通运输的繁忙和不断发展,

    2024年02月15日
    浏览(44)
  • (数字图像处理MATLAB+Python)第五章图像增强-第四、五节:基于模糊技术和基于伪彩色处理的图像增强

    图像的模糊特征平面 :假设原始图像为 I ( x , y ) I(x,y) I ( x , y ) ,其中 x x x 和 y y y 分别表示图像的水平和垂直方向的坐标。模糊特征平面可以表示为 B ( x , y , θ ) B(x,y,theta) B ( x , y , θ ) ,其中 θ theta θ 是一个旋转角度参数,表示模糊核函数的旋转角度。 B ( x , y , θ ) B(x,

    2023年04月20日
    浏览(104)
  • 【数字图像处理】基于Simulink的PCB孔位检测识别实验报告和代码

    需要一种图像处理系统来检测印刷电路板(PCB)中的小孔,并将它们的位置与预定义的规格进行比较。本实验的主要目的是处理图像,以便可以显示检测到的孔位置的覆盖(例如使用红色标记)以及预定义位置的覆盖(例如使用绿色标记)。图1中显示了一个样本图像(部分)。如果有任

    2024年02月07日
    浏览(65)
  • 76、基于STM32单片机车牌识别摄像头图像处理扫描设计(程序+原理图+PCB源文件+相关资料+参考PPT+元器件清单等)

    单片机主芯片选择方案 方案一:AT89C51是美国ATMEL公司生产的低电压,高性能CMOS型8位单片机,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大。其片内的4K程序存储器是FLASH工艺的,这种单

    2024年02月12日
    浏览(55)
  • 三种目标检测方法(基于传统数字图像处理的识别方法、基于传统机器学习的识别方法和基于深度学习的识别方法)的区别

    问题描述:图像检测分为了基于传统数字图像处理的识别方法、基于传统机器学习的识别方法和基于深度学习的识别方法,但是有时迷惑三者的区别是什么呢? 问题解答: 第一,基于传统数字图像处理的识别方法和其他两者的区分在于基于传统图像处理方法没有损失函数,

    2024年02月12日
    浏览(41)
  • 霍夫变换车道线识别-车牌字符识别代码(matlab仿真与图像处理系列第5期)

    当使用霍夫变换进行车道线识别时,可以按照以下步骤来编写 MATLAB 代码: 读入图像:使用 imread 函数读取包含车道线的图像。 图像预处理:为了减少噪音和突出车道线,可以对图像进行预处理。通常,可以采用以下步骤: 将图像转换为灰度图像:使用 rgb2gray 函数将彩色图

    2024年02月11日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包