【机器学习实战高阶】基于深度学习车牌识别 自动识别车牌号码 Automatic License Number Plate Detection and Recognition

在这里插入图片描述

深度学习项目 - 自动车牌识别

本项目旨在识别车牌号码。为了检测车牌号码,我们将使用 OpenCV 识别车牌,并利用 Python 的 pytesseract 从车牌中提取字符和数字信息。
在这里插入图片描述

自动车牌识别

OpenCV 是一个开源的机器学习库,为计算机视觉提供了通用的基础设施。而 Pytesseract 是一个 Tesseract-OCR 引擎,用于读取图像类型并提取图像中的信息。

安装 OpenCV 和 Pytesseract pip3 Python 包:
pip3 install opencv-python  # 安装 OpenCV 库
pip3 install pytesseract  # 安装 Pytesseract 库

在本 Python 项目中,为了在输入图像中识别车牌,我们将使用 OpenCV 的以下功能:

  1. 高斯模糊(Gaussian Blur):我们使用高斯核来平滑图像。这一技术非常有效,能够去除高斯噪声。OpenCV 提供了 cv2.GaussianBlur() 函数来完成此任务。
  2. Sobel 梯度:我们计算图像的导数。这一功能在许多计算机视觉任务中非常重要。通过导数计算梯度,梯度的大幅变化表示图像中的主要变化。OpenCV 提供了 cv2.Sobel() 函数来计算 Sobel 操作符。
  3. 形态学变换(Morphological Transformation):这些操作基于图像形状,通常在二值图像上执行。基本的形态学操作包括腐蚀(Erosion)、膨胀(Dilation)、开运算(Opening)和闭运算(Closing)。OpenCV 提供了以下函数:
    • cv2.erode():腐蚀操作。
    • cv2.dilate():膨胀操作。
    • cv2.morphologyEx():执行开运算和闭运算等复杂形态学操作。
  4. 轮廓(Contours):轮廓是包含所有连续相同强度点的曲线。它们是对象识别中非常有用的工具。OpenCV 提供了 cv2.findContours() 函数来实现这一功能。
下载项目源代码

在继续之前,请下载源代码:
链接: 基于深度学习车牌识别 自动识别车牌号码

现在,让我们深入到车牌识别代码中。请按照以下步骤操作:

  1. 导入库

    该项目需要 numpy 和 pillow Python 库,以及 OpenCV 和 pytesseract。

    import numpy as np  # 导入 numpy 库
    import cv2  # 导入 OpenCV 库
    from PIL import Image  # 导入 PIL 库
    import pytesseract as tess  # 导入 pytesseract 库
    
  2. 定义辅助函数

    现在我们将定义三个函数,用于过滤掉 OpenCV 可能识别到但不太可能是车牌的轮廓。

2.1. 检查面积范围和宽高比

该函数用于检查轮廓的面积范围和宽高比。如果面积或宽高比不符合要求,则返回 False。

def ratioCheck(area, width, height):  # 定义检查面积和宽高比的函数
    ratio = float(width) / float(height)  # 计算宽高比
    if ratio < 1:
        ratio = 1 / ratio  # 如果宽小于高,则取倒数
    if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):  # 检查面积和宽高比
        return False  # 如果不符合要求,返回 False
    return True  # 如果符合要求,返回 True

2.2. 检查图像矩阵的平均值

该函数用于检查车牌图像的平均像素值。如果平均值大于等于 115,则认为图像足够亮,返回 True;否则返回 False。

def isMaxWhite(plate):  # 定义检查图像矩阵平均值的函数
    avg = np.mean(plate)  # 计算图像的平均像素值
    if(avg>=115):  # 如果平均值大于等于 115
        return True  # 返回 True
    else:
        return False  # 否则返回 False

2.3. 检查轮廓的旋转角度

该函数用于检查轮廓的旋转角度。如果旋转角度大于 15 度或宽高为 0,则返回 False。否则,检查轮廓的面积和宽高比,如果符合要求则返回 True。

def ratio_and_rotation(rect):  # 定义检查轮廓旋转角度的函数
    (x, y), (width, height), rect_angle = rect  # 获取轮廓的中心点、宽高和旋转角度
    if(width>height):  # 如果宽度大于高度
        angle = -rect_angle  # 旋转角度取反
    else:
        angle = 90 + rect_angle  # 否则旋转角度加 90 度
    if angle>15:  # 如果旋转角度大于 15 度
        return False  # 返回 False
    if height == 0 or width == 0:  # 如果高度或宽度为 0
        return False  # 返回 False
    area = height * width  # 计算轮廓面积
    if not ratioCheck(area, width, height):  # 检查面积和宽高比
        return False  # 如果不符合要求,返回 False
    else:
        return True  # 如果符合要求,返回 True
  1. 清洗识别到的车牌图像

    该函数用于清洗识别到的车牌图像,以便在使用 pytesseract 之前进行预处理。首先将图像转换为灰度图像,然后进行二值化处理,找到轮廓并返回清理后的图像和轮廓信息。

    def clean2_plate(plate):  # 定义清洗车牌图像的函数
        gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)  # 将图像转换为灰度图像
        _, thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)  # 进行二值化处理
        if cv2.waitKey(0) & 0xff == ord('q'):  # 按下 'q' 键退出
            pass
        num_contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)  # 找到轮廓
        if num_contours:
            contour_area = [cv2.contourArea(c) for c in num_contours]  # 计算每个轮廓的面积
            max_cntr_index = np.argmax(contour_area)  # 找到面积最大的轮廓
            max_cnt = num_contours[max_cntr_index]  # 获取面积最大的轮廓
            max_cntArea = contour_area[max_cntr_index]  # 获取最大轮廓的面积
            x, y, w, h = cv2.boundingRect(max_cnt)  # 获取最大轮廓的边界矩形
            if not ratioCheck(max_cntArea, w, h):  # 检查边界矩形的面积和宽高比
                return plate, None  # 如果不符合要求,返回原图像和 None
            final_img = thresh[y:y+h, x:x+w]  # 提取边界矩形中的图像
            return final_img, [x, y, w, h]  # 返回清洗后的图像和轮廓信息
        else:
            return plate, None  # 如果没有找到轮廓,返回原图像和 None
    
  2. 主处理步骤

    在这一步中,我们将读取输入图像,进行高斯模糊、Sobel 梯度和形态学操作。然后在图像中找到轮廓,并遍历每个轮廓来识别车牌。最后,清洗图像轮廓并将其输入到 pytesseract 中以识别数字和字符。

    img = cv2.imread("testData/sample15.jpg")  # 读取输入图像
    print("Number  input image...")  # 打印输入图像信息
    cv2.imshow("input", img)  # 显示输入图像
    if cv2.waitKey(0) & 0xff == ord('q'):  # 按下 'q' 键退出
        pass
    img2 = cv2.GaussianBlur(img, (3, 3), 0)  # 应用高斯模糊
    img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)  # 转换为灰度图像
    img2 = cv2.Sobel(img2, cv2.CV_8U, 1, 0, ksize=3)  # 计算 Sobel 梯度
    _, img2 = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # 进行二值化处理
    element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3))  # 获取结构元素
    morph_img_threshold = img2.copy()  # 复制二值图像
    cv2.morphologyEx(src=img2, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold)  # 进行闭运算
    num_contours, hierarchy = cv2.findContours(morph_img_threshold, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)  # 找到轮廓
    cv2.drawContours(img2, num_contours, -1, (0, 255, 0), 1)  # 绘制轮廓
    for i, cnt in enumerate(num_contours):  # 遍历每个轮廓
        min_rect = cv2.minAreaRect(cnt)  # 获取最小外接矩形
        if ratio_and_rotation(min_rect):  # 检查轮廓的宽高比和旋转角度
            x, y, w, h = cv2.boundingRect(cnt)  # 获取轮廓的边界矩形
            plate_img = img[y:y+h, x:x+w]  # 提取车牌图像
            print("Number  identified number plate...")  # 打印识别到的车牌信息
            cv2.imshow("num plate image", plate_img)  # 显示车牌图像
            if cv2.waitKey(0) & 0xff == ord('q'):  # 按下 'q' 键退出
                pass
            if(isMaxWhite(plate_img)):  # 检查车牌图像的平均像素值
                clean_plate, rect = clean2_plate(plate_img)  # 清洗车牌图像
                if rect:
                    fg = 0
                    x1, y1, w1, h1 = rect  # 获取清洗后的轮廓信息
                    x, y, w, h = x + x1, y + y1, w1, h1  # 更新边界矩形
                    # cv2.imwrite("clena.png", clean_plate)  # 保存清洗后的图像
                    plate_im = Image.fromarray(clean_plate)  # 将清洗后的图像转换为 PIL 图像
                    text = tess.image_to_string(plate_im, lang='eng')  # 使用 pytesseract 识别图像中的文本
                    print("Number  Detected Plate Text : ", text)  # 打印识别到的车牌文本
    

项目 GUI 代码

创建一个新文件 gui.py 并粘贴以下代码:

import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
from tkinter import PhotoImage
import numpy as np
import cv2
import pytesseract as tess

代码总结:
这部分代码导入了项目所需的库。tkinter 用于创建 GUI 界面,filedialog 用于文件选择对话框,PIL 用于图像处理,numpy 用于数值计算,cv2 用于图像处理和计算机视觉任务,pytesseract 用于 OCR 识别。

def clean2_plate(plate):
    gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)  # 将输入图像转换为灰度图像
    _, thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)  # 对灰度图像进行二值化处理
    num_contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)  # 检测图像中的轮廓
    if num_contours:
        contour_area = [cv2.contourArea(c) for c in num_contours]  # 计算每个轮廓的面积
        max_cntr_index = np.argmax(contour_area)  # 找到面积最大的轮廓索引
        max_cnt = num_contours[max_cntr_index]  # 获取面积最大的轮廓
        max_cntArea = contour_area[max_cntr_index]  # 获取面积最大的轮廓的面积
        x, y, w, h = cv2.boundingRect(max_cnt)  # 计算最大轮廓的边界矩形
        if not ratioCheck(max_cntArea, w, h):  # 检查边界矩形的宽高比是否符合要求
            return plate, None  # 如果不符合要求,返回原图像和 None
        final_img = thresh[y:y+h, x:x+w]  # 裁剪出最大轮廓的区域
        return final_img, [x, y, w, h]  # 返回处理后的图像和边界矩形
    else:
        return plate, None  # 如果没有检测到轮廓,返回原图像和 None

代码总结:
clean2_plate 函数用于清理和提取车牌图像。它首先将输入图像转换为灰度图像,然后进行二值化处理。接下来,检测图像中的轮廓,并找到面积最大的轮廓。计算该轮廓的边界矩形,并检查其宽高比是否符合要求。如果符合要求,返回裁剪后的图像和边界矩形;否则返回原图像和 None。

def ratioCheck(area, width, height):
    ratio = float(width) / float(height)  # 计算宽高比
    if ratio < 1:
        ratio = 1 / ratio  # 如果宽高比小于 1,取其倒数
    if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):  # 检查面积和宽高比是否在合理范围内
        return False  # 如果不在合理范围内,返回 False
    return True  # 如果在合理范围内,返回 True

代码总结:
ratioCheck 函数用于检查给定区域的面积和宽高比是否符合车牌的合理范围。它首先计算宽高比,如果宽高比小于 1,取其倒数。然后检查面积是否在 1063.62 和 73862.5 之间,宽高比是否在 3 和 6 之间。如果符合要求,返回 True;否则返回 False。

def isMaxWhite(plate):
    avg = np.mean(plate)  # 计算图像的平均像素值
    if(avg >= 115):
        return True  # 如果平均像素值大于等于 115,返回 True
    else:
        return False  # 否则返回 False

代码总结:
isMaxWhite 函数用于检查车牌图像是否主要为白色。它计算图像的平均像素值,如果平均像素值大于等于 115,认为图像主要为白色,返回 True;否则返回 False。

def ratio_and_rotation(rect):
    (x, y), (width, height), rect_angle = rect  # 解析矩形的中心点、宽度、高度和旋转角度
    if width > height:
        angle = -rect_angle  # 如果宽度大于高度,旋转角度为负
    else:
        angle = 90 + rect_angle  # 否则,旋转角度为 90 度加上矩形的旋转角度
    if angle > 15:
        return False  # 如果旋转角度大于 15 度,返回 False
    if height == 0 or width == 0:
        return False  # 如果高度或宽度为 0,返回 False
    area = height * width  # 计算矩形的面积
    if not ratioCheck(area, width, height):  # 检查矩形的宽高比是否符合要求
        return False  # 如果不符合要求,返回 False
    else:
        return True  # 如果符合要求,返回 True

代码总结:
ratio_and_rotation 函数用于检查矩形的宽高比和旋转角度是否符合要求。它首先解析矩形的中心点、宽度、高度和旋转角度,根据宽度和高度的关系调整旋转角度。然后检查旋转角度是否大于 15 度,高度或宽度是否为 0。最后,调用 ratioCheck 函数检查矩形的宽高比是否在合理范围内。如果所有条件都满足,返回 True;否则返回 False。

top = tk.Tk()
top.geometry('900x700')  # 设置窗口大小
top.title('Number Plate Recognition')  # 设置窗口标题
top.iconphoto(True, PhotoImage(file="/home/shivam/Dataflair/Keras Projects_CIFAR/GUI/logo.png"))  # 设置窗口图标
img = ImageTk.PhotoImage(Image.open("logo.png"))  # 打开并加载图标图像
top.configure(background='#CDCDCD')  # 设置窗口背景颜色
label = Label(top, background='#CDCDCD', font=('arial', 35, 'bold'))  # 创建一个标签,用于显示识别结果
sign_image = Label(top, bd=10)  # 创建一个标签,用于显示上传的图像
plate_image = Label(top, bd=10)  # 创建一个标签,用于显示识别出的车牌图像

代码总结:
这部分代码用于初始化主窗口并设置其属性。创建了一个 Tk 窗口,设置了窗口的大小、标题、图标、背景颜色等。同时还创建了三个标签,分别用于显示识别结果、上传的图像和识别出的车牌图像。

def classify(file_path):
    res_text = [0]  # 初始化识别结果文本
    res_img = [0]  # 初始化识别结果图像
    img = cv2.imread(file_path)  # 读取图像文件
    img2 = cv2.GaussianBlur(img, (3, 3), 0)  # 对图像进行高斯模糊处理
    img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)  # 将图像转换为灰度图像
    img2 = cv2.Sobel(img2, cv2.CV_8U, 1, 0, ksize=3)  # 使用 Sobel 算子进行边缘检测
    _, img2 = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # 对图像进行二值化处理
    element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3))  # 获取一个矩形结构元素
    morph_img_threshold = img2.copy()  # 复制二值化图像
    cv2.morphologyEx(src=img2, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold)  # 进行形态学闭运算
    num_contours, hierarchy = cv2.findContours(morph_img_threshold, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)  # 检测图像中的轮廓
    cv2.drawContours(img2, num_contours, -1, (0, 255, 0), 1)  # 在图像上绘制轮廓
    for i, cnt in enumerate(num_contours):
        min_rect = cv2.minAreaRect(cnt)  # 获取最小面积矩形
        if ratio_and_rotation(min_rect):  # 检查矩形的宽高比和旋转角度是否符合要求
            x, y, w, h = cv2.boundingRect(cnt)  # 计算轮廓的边界矩形
            plate_img = img[y:y+h, x:x+w]  # 裁剪出边界矩形区域
            print("Number identified number plate...")  # 打印提示信息
            res_img[0] = plate_img  # 保存裁剪后的图像
            cv2.imwrite("result.png", plate_img)  # 将裁剪后的图像保存到文件
            if isMaxWhite(plate_img):  # 检查图像是否主要为白色
                clean_plate, rect = clean2_plate(plate_img)  # 清理车牌图像
                if rect:
                    fg = 0
                    x1, y1, w1, h1 = rect  # 解析边界矩形
                    x, y, w, h = x + x1, y + y1, w1, h1  # 调整边界矩形的位置
                    plate_im = Image.fromarray(clean_plate)  # 将清理后的图像转换为 PIL 图像
                    text = tess.image_to_string(plate_im, lang='eng')  # 使用 pytesseract 进行 OCR 识别
                    res_text[0] = text  # 保存识别结果
                    if text:
                        break  # 如果识别到文本,退出循环
    label.configure(foreground='#011638', text=res_text[0])  # 更新标签显示识别结果
    uploaded = Image.open("result.png")  # 打开保存的车牌图像
    im = ImageTk.PhotoImage(uploaded)  # 将图像转换为 PhotoImage
    plate_image.configure(image=im)  # 更新标签显示车牌图像
    plate_image.image = im  # 保留对图像的引用,避免被垃圾回收
    plate_image.pack()
    plate_image.place(x=560, y=320)  # 将标签放置在窗口中的指定位置

代码总结:
classify 函数用于处理上传的图像并识别车牌。首先读取图像文件,然后进行高斯模糊、灰度转换、Sobel 边缘检测和二值化处理。接下来获取一个矩形结构元素,并对二值化图像进行形态学闭运算。检测图像中的轮廓,并在图像上绘制这些轮廓。对于每个轮廓,获取最小面积矩形并检查其宽高比和旋转角度是否符合要求。如果符合要求,裁剪出轮廓区域并保存为 result.png。然后检查图像是否主要为白色,如果主要为白色,调用 clean2_plate 函数进行清理,并使用 pytesseract 进行 OCR 识别。最后,更新标签显示识别结果和车牌图像。

def show_classify_button(file_path):
    classify_b = Button(top, text="Classify Image", command=lambda: classify(file_path), padx=10, pady=5)  # 创建一个“识别图像”按钮
    classify_b.configure(background='#364156', foreground='white', font=('arial', 15, 'bold'))  # 设置按钮样式
    classify_b.place(x=490, y=550)  # 将按钮放置在窗口中的指定位置

代码总结:
show_classify_button 函数用于在窗口中显示“识别图像”按钮。该按钮的点击事件会调用 classify 函数处理传入的图像文件路径。

def upload_image():
    try:
        file_path = filedialog.askopenfilename()  # 打开文件选择对话框,获取用户选择的文件路径
        uploaded = Image.open(file_path)  # 打开用户选择的图像文件
        uploaded.thumbnail(((top.winfo_width()/2.25), (top.winfo_height()/2.25)))  # 将图像缩放到窗口大小的 1/2.25
        im = ImageTk.PhotoImage(uploaded)  # 将图像转换为 PhotoImage
        sign_image.configure(image=im)  # 更新标签显示上传的图像
        sign_image.image = im  # 保留对图像的引用,避免被垃圾回收
        label.configure(text='')  # 清空识别结果标签
        show_classify_button(file_path)  # 显示“识别图像”按钮
    except:
        pass  # 如果发生异常,捕获并忽略

代码总结:
upload_image 函数用于处理用户上传的图像。打开文件选择对话框,获取用户选择的图像文件路径,然后打开并缩放图像。将缩放后的图像转换为 PhotoImage 并更新 sign_image 标签显示该图像。同时清空识别结果标签,并显示“识别图像”按钮。

upload = Button(top, text="Upload an image", command=upload_image, padx=10, pady=5)  # 创建一个“上传图像”按钮
upload.configure(background='#364156', foreground='white', font=('arial', 15, 'bold'))  # 设置按钮样式
upload.pack()  # 将按钮添加到窗口布局
upload.place(x=210, y=550)  # 将按钮放置在窗口中的指定位置

sign_image.pack()  # 将上传图像标签添加到窗口布局
sign_image.place(x=70, y=200)  # 将上传图像标签放置在窗口中的指定位置

label.pack()  # 将识别结果标签添加到窗口布局
label.place(x=500, y=220)  # 将识别结果标签放置在窗口中的指定位置

heading = Label(top, image=img)  # 创建一个标题标签,显示项目图标
heading.configure(background='#CDCDCD', foreground='#364156')  # 设置标题标签样式
heading.pack()  # 将标题标签添加到窗口布局

top.mainloop()  # 进入主事件循环,保持窗口运行

代码总结:
这部分代码用于创建和配置主窗口中的按钮和标签。创建了一个“上传图像”按钮,并设置其点击事件为 upload_image 函数。将上传图像标签、识别结果标签和标题标签添加到窗口布局,并设置它们的位置。最后,进入主事件循环,保持窗口运行。

参考资料

参考资料名称链接
Tkinter 官方文档https://docs.python.org/3/library/tkinter.html
OpenCV 官方文档https://docs.opencv.org/master/
PIL 官方文档https://pillow.readthedocs.io/en/stable/
NumPy 官方文档https://numpy.org/doc/stable/
PyTesseract 官方文档https://pypi.org/project/pytesseract/
License Plate Recognition 研究综述https://www.researchgate.net/publication/332855701_A_Survey_on_License_Plate_Recognition_Systems
OpenCV 形态学操作教程https://opencv-python-tutroials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html
OpenCV 轮廓检测教程https://opencv-python-tutroials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html
Sobel 边缘检测原理https://homepages.inf.ed.ac.uk/rbf/HIPR2/sobel.htm
Gaussian Blur 高斯模糊原理https://towardsdatascience.com/image-processing-with-python-and-opencv-part-2-gaussian-blurring-and-sharpening-bf4cb49228e6
OCR 技术综述https://www.sciencedirect.com/science/article/pii/S1877050915006783
Tesseract OCR 使用教程https://www.geeksforgeeks.org/python-ocr-on-pdf-using-pytesseract/
OpenCV 二值化处理教程https://learnopencv.com/otsu-thresholding-explained/
Tkinter GUI 设计教程[https://realpython.com/python-gui-tkinter/](https://realpython.com/python-g
OpenCV 官方文档https://docs.opencv.org/4.x/
Tesseract-OCR 官方文档https://tesseract-ocr.github.io/tessdoc/
Python 中的图像处理https://www.geeksforgeeks.org/python-digit-and-character-recognition-for-captchas-using-opencv-tesseract-and-pytesseract/
车牌识别教程https://www.jb51.net/article/192353.htm
OpenCV 形态学操作https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html
Sobel 梯度算子https://www.tutorialspoint.com/opencv/opencv_sobel_operator.htm
计算机视觉入门https://cv-tricks.com/
高斯模糊详解https://blog.csdn.net/xiaoxiao20180204/article/details/79643369
车牌识别研究综述https://arxiv.org/abs/1903.02727
Pytesseract 使用教程https://github.com/madmaze/pytesseract-tutorial
OpenCV 检测车牌的另一种方法https://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/
形态学变换的原理https://www.mathworks.com/help/images/morphology-fundamentals-dilation-and-erosion.html
车牌检测与识别https://www.sciencedirect.com/science/article/pii/S1877050920326946
计算机视觉中的轮廓检测https://www.tutorialspoint.com/contour-detection-in-computer-vision-using-python
车牌字符识别方法https://ieeexplore.ieee.org/document/8923706
数字和字符识别https://www.analyticsvidhya.com/blog/2019/06/comprehensive-guide-digital-character-recognition-ocr-python/
车牌识别在实际应用中的挑战https://www.researchgate.net/publication/335230929_Challenges_and_Solutions_for_License_Plate_Recognition_in_Real-World_Applications
posted @   爱上编程技术  阅读(32)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示