前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >yolov8学习,车辆车牌识别代码解读

yolov8学习,车辆车牌识别代码解读

原创
作者头像
繁依Fanyi
修改2024-10-27 21:09:02
修改2024-10-27 21:09:02
23300
代码可运行
举报
运行总次数:0
代码可运行

最近对人工智能、计算机视觉等一类的东西很感兴趣,突发奇想想做一个停车场管理系统,从其中就需要车牌识别,于是尝试学习并尝试做一下这个yolo车牌检测识别的项目。

在构建停车场管理系统的过程中,车牌识别是核心功能之一。为了实现这一目标,选择了YOLO(You Only Look Once)作为车牌检测与识别的工具。以下将详细解读项目中的各个模块,包括 main.pyvisualize.pyadd\_missing\_data.pyutil.py,并逐步讲解它们的处理过程和背后的知识点。

1. main.py:项目的核心入口

main.py 作为整个项目的主入口,负责整体流程的控制。该模块的核心功能包括加载YOLO模型、读取输入视频、进行图像处理以及输出检测结果。

加载模型

在项目开始时,首先导入必要的库和模块,如 OpenCV、YOLO 和自定义的工具模块。接着,使用 YOLO 模型加载函数载入预训练的模型文件。这一步骤至关重要,因为它为后续的车辆和车牌检测提供了必要的网络结构和参数。

代码语言:python
代码运行次数:0
复制
from ultralytics import YOLO

import cv2

import util

from sort.sort import \*

from util import get\_car, read\_license\_plate, write\_csv



# 初始化检测结果字典和 SORT 追踪器

results = {}

mot\_tracker = Sort()



# 加载 YOLO 模型

coco\_model = YOLO('yolov8n.pt')

license\_plate\_detector = YOLO('./models/license\_plate\_detector.pt')
读取视频

接下来,使用 OpenCV 读取输入视频并逐帧进行处理。每帧的处理包括检测车辆和车牌的过程。

代码语言:python
代码运行次数:0
复制
# 加载视频

cap = cv2.VideoCapture('./sample.mp4')



# 初始化帧计数器

frame\_nmr = -1

ret = True

while ret:

    frame\_nmr += 1

    ret, frame = cap.read()

    if ret:

        results[frame\_nmr] = {}

        ...
检测车辆

对于每帧图像,首先使用 YOLO 模型检测车辆。检测结果包含每个车辆的边界框信息及其置信度分数。通过过滤车辆类别,只保留主要关心的车辆(如轿车、SUV等)。

代码语言:python
代码运行次数:0
复制
# 检测车辆

detections = coco\_model(frame)[0]

detections\_ = []

for detection in detections.boxes.data.tolist():

    x1, y1, x2, y2, score, class\_id = detection

    if int(class\_id) in vehicles:

        detections\_.append([x1, y1, x2, y2, score])
追踪车辆

使用 SORT 算法对检测到的车辆进行追踪。每个车辆在视频中分配一个唯一的 ID,以便后续识别和关联车牌信息。

代码语言:python
代码运行次数:0
复制
# 追踪车辆

track\_ids = mot\_tracker.update(np.asarray(detections\_))
检测车牌

对于每帧图像,使用车牌检测模型来识别车牌。检测到的每个车牌都被分配到相应的车辆 ID,以确保每个车牌和其对应的车辆保持一致。

代码语言:python
代码运行次数:0
复制
# 检测车牌

license\_plates = license\_plate\_detector(frame)[0]

for license\_plate in license\_plates.boxes.data.tolist():

    x1, y1, x2, y2, score, class\_id = license\_plate



    # 将车牌分配给车辆

    xcar1, ycar1, xcar2, ycar2, car\_id = get\_car(license\_plate, track\_ids)
裁剪和处理车牌

成功分配车牌后,裁剪出车牌区域,并对其进行灰度转换和二值化处理,以便于后续的字符识别。

代码语言:python
代码运行次数:0
复制
if car\_id != -1:

    # 裁剪车牌图像

    license\_plate\_crop = frame[int(y1):int(y2), int(x1): int(x2), :]



    # 处理车牌图像

    license\_plate\_crop\_gray = cv2.cvtColor(license\_plate\_crop, cv2.COLOR\_BGR2GRAY)

    \_, license\_plate\_crop\_thresh = cv2.threshold(license\_plate\_crop\_gray, 64, 255, cv2.THRESH\_BINARY\_INV)



    # 读取车牌号码

    license\_plate\_text, license\_plate\_text\_score = read\_license\_plate(license\_plate\_crop\_thresh)



    if license\_plate\_text is not None:

        results[frame\_nmr][car\_id] = {'car': {'bbox': [xcar1, ycar1, xcar2, ycar2]},

                                      'license\_plate': {'bbox': [x1, y1, x2, y2],

                                                        'text': license\_plate\_text,

                                                        'bbox\_score': score,

                                                        'text\_score': license\_plate\_text\_score}}
写入结果

最后,将处理后的检测结果写入 CSV 文件,以便后续的数据分析和处理。

代码语言:python
代码运行次数:0
复制
# 写入结果

write\_csv(results, './test.csv')

main.py 模块主要实现了视频中的车辆和车牌检测功能,并将结果存储为结构化数据。

好的,下面是更加详细和自然的描述,包含对 visualize.py 功能的讲解及其重要性。

2. visualize.py:结果可视化模块

visualize.py 模块的主要功能是将车牌识别的结果以可视化的形式展示在视频中。这不仅可以帮助开发者直观地理解识别系统的表现,还能用于展示最终的产品效果,增强用户体验。

导入所需库

首先需要导入一些必要的库:

  • cv2:用于图像和视频处理。
  • numpy:用于数值计算和数组操作。
  • pandas:用于数据处理和分析。
代码语言:python
代码运行次数:0
复制
import ast

import cv2

import numpy as np

import pandas as pd
绘制边框的函数

draw\_border 函数负责在图像上绘制车辆和车牌的边框。通过这种可视化,可以清晰地看到识别的区域,帮助分析模型的准确性。

代码语言:python
代码运行次数:0
复制
def draw\_border(img, top\_left, bottom\_right, color=(0, 255, 0), thickness=10, line\_length\_x=200, line\_length\_y=200):

    x1, y1 = top\_left

    x2, y2 = bottom\_right



    # 绘制左上角边框

    cv2.line(img, (x1, y1), (x1, y1 + line\_length\_y), color, thickness)  # 左侧

    cv2.line(img, (x1, y1), (x1 + line\_length\_x, y1), color, thickness)  # 上侧



    # 绘制左下角边框

    cv2.line(img, (x1, y2), (x1, y2 - line\_length\_y), color, thickness)  # 左侧

    cv2.line(img, (x1, y2), (x1 + line\_length\_x, y2), color, thickness)  # 下侧



    # 绘制右上角边框

    cv2.line(img, (x2, y1), (x2 - line\_length\_x, y1), color, thickness)  # 上侧

    cv2.line(img, (x2, y1), (x2, y1 + line\_length\_y), color, thickness)  # 右侧



    # 绘制右下角边框

    cv2.line(img, (x2, y2), (x2, y2 - line\_length\_y), color, thickness)  # 右侧

    cv2.line(img, (x2, y2), (x2 - line\_length\_x, y2), color, thickness)  # 下侧



    return img
读取识别结果数据

通过 Pandas 读取 CSV 文件中的识别结果,这些结果是模型处理视频后生成的,包括每个车牌的置信度和位置信息。

代码语言:python
代码运行次数:0
复制
results = pd.read\_csv('./test\_interpolated.csv')  # 读取包含识别结果的 CSV 文件
加载视频

使用 OpenCV 加载视频文件。同时设置了输出视频的编码格式和帧率,以确保生成的视频与原视频质量一致。

代码语言:python
代码运行次数:0
复制
# 加载视频

video\_path = 'sample.mp4'

cap = cv2.VideoCapture(video\_path)  # 创建视频捕获对象



# 指定视频编码和帧率

fourcc = cv2.VideoWriter\_fourcc(\*'mp4v')

fps = cap.get(cv2.CAP\_PROP\_FPS)  # 获取原视频的帧率

width = int(cap.get(cv2.CAP\_PROP\_FRAME\_WIDTH))  # 获取视频宽度

height = int(cap.get(cv2.CAP\_PROP\_FRAME\_HEIGHT))  # 获取视频高度

out = cv2.VideoWriter('./out.mp4', fourcc, fps, (width, height))  # 创建输出视频文件
初始化车牌信息字典

为每个车辆提取最大置信度的车牌信息,并存储对应的车牌图像。这样做的目的是在后续绘制过程中,能够快速访问每辆车的识别结果。

代码语言:python
代码运行次数:0
复制
license\_plate = {}

for car\_id in np.unique(results['car\_id']):  # 遍历所有唯一的车ID

    max\_ = np.amax(results[results['car\_id'] == car\_id]['license\_number\_score'])  # 找到最大置信度

    license\_plate[car\_id] = {

        'license\_crop': None,  # 初始化车牌裁剪图像

        'license\_plate\_number': results[(results['car\_id'] == car\_id) &

                                         (results['license\_number\_score'] == max\_)]['license\_number'].iloc[0]  # 存储车牌号

    }

    

    # 设置视频帧的位置

    cap.set(cv2.CAP\_PROP\_POS\_FRAMES, results[(results['car\_id'] == car\_id) &

                                             (results['license\_number\_score'] == max\_)]['frame\_nmr'].iloc[0])

    ret, frame = cap.read()  # 读取该帧



    # 获取车牌的边界框坐标

    x1, y1, x2, y2 = ast.literal\_eval(results[(results['car\_id'] == car\_id) &

                                              (results['license\_number\_score'] == max\_)]['license\_plate\_bbox'].iloc[0].replace('[ ', '[').replace('   ', ' ').replace('  ', ' ').replace(' ', ','))



    # 裁剪车牌图像并调整大小

    license\_crop = frame[int(y1):int(y2), int(x1):int(x2), :]

    license\_crop = cv2.resize(license\_crop, (int((x2 - x1) \* 400 / (y2 - y1)), 400))  # 调整裁剪图像的大小



    license\_plate[car\_id]['license\_crop'] = license\_crop  # 保存裁剪的车牌图像
逐帧读取视频并绘制识别结果

在这一部分,逐帧读取视频,并根据识别结果在每帧上绘制车辆和车牌的边界框。通过这种方式,用户可以直观地看到模型的识别效果,并评估其准确性和可靠性。

代码语言:python
代码运行次数:0
复制
frame\_nmr = -1  # 帧计数器

cap.set(cv2.CAP\_PROP\_POS\_FRAMES, 0)  # 重置视频到开头



# 读取帧

ret = True

while ret:

    ret, frame = cap.read()  # 读取一帧

    frame\_nmr += 1  # 增加帧计数

    if ret:

        df\_ = results[results['frame\_nmr'] == frame\_nmr]  # 获取当前帧的结果

        for row\_indx in range(len(df\_)):

            # 绘制车辆边界框

            car\_x1, car\_y1, car\_x2, car\_y2 = ast.literal\_eval(df\_.iloc[row\_indx]['car\_bbox'].replace('[ ', '[').replace('   ', ' ').replace('  ', ' ').replace(' ', ','))

            draw\_border(frame, (int(car\_x1), int(car\_y1)), (int(car\_x2), int(car\_y2)), (0, 255, 0), 25,

                        line\_length\_x=200, line\_length\_y=200)



            # 绘制车牌边界框

            x1, y1, x2, y2 = ast.literal\_eval(df\_.iloc[row\_indx]['license\_plate\_bbox'].replace('[ ', '[').replace('   ', ' ').replace('  ', ' ').replace(' ', ','))

            cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 0, 255), 12)  # 绘制车牌的矩形框



            # 获取并显示车牌裁剪图像

            license\_crop = license\_plate[df\_.iloc[row\_indx]['car\_id']]['license\_crop']  # 获取车牌裁剪图像

            H, W, \_ = license\_crop.shape  # 获取车牌裁剪图像的高度和宽度



            try:

                # 在车辆上方插入车牌图像

                frame[int(car\_y1) - H - 100:int(car\_y1) - 100,

                      int((car\_x2 + car\_x1 - W) / 2):int((car\_x2 + car\_x1 + W) / 2), :] = license\_crop



                # 在车牌上方添加白色背景

                frame[int(car\_y1) - H - 400:int(car\_y1) - H - 100,

                      int((car\_x2 + car\_x1 - W) / 2):int((car\_x2 + car\_x1 + W) / 2), :] = (255, 255, 255)



                # 获取文本的尺寸

                (text\_width, text\_height), \_ = cv2.getTextSize(

                    license\_plate[df\_.iloc[row\_indx]['car\_id']]['license\_plate\_number'],

                    cv2.FONT\_HERSHEY\_SIMPLEX,

                    4.3,

                    17)



                # 在帧中绘制车牌号码

                cv2.putText(frame,

                            license\_plate[df\_.iloc[row\_indx]['car\_id']]['license\_plate\_number'],





                            (int((car\_x2 + car\_x1 - text\_width) / 2), int(car\_y1 - H - 250 + (text\_height / 2))),

                            cv2.FONT\_HERSHEY\_SIMPLEX,

                            4.3,

                            (0, 0, 0),

                            17)



            except:

                pass  # 忽略可能出现的错误



        out.write(frame)  # 将处理后的帧写入输出视频

        frame = cv2.resize(frame, (1280, 720))  # 调整输出帧的尺寸



out.release()  # 释放视频写入对象

cap.release()  # 释放视频捕获对象

好的,我会将 util.py 的内容进行详细描述,并在代码中加入中文注释,便于理解。以下是修改后的内容:

3. add\_missing\_data.py:处理缺失数据

在构建车牌识别系统时,确保数据的完整性和质量至关重要。add\_missing\_data.py 模块专注于处理数据中的缺失部分,以保证数据集的连贯性和准确性。为此,采用插值填补的方法,以填补在数据收集中可能遗漏的车牌检测结果。

在实际应用中,数据常常不完整,尤其是在视频监控场景中,某些帧可能缺失了车牌的检测结果。为了保证后续分析和处理的准确性,要对这些缺失数据进行补充。插值填补的方法通过已有数据推测缺失值,维持数据的连续性。

具体实现中,首先从输入的CSV文件中读取车牌检测的数据,提取帧编号、车辆ID及其对应的边界框。利用 numpy 数组,来快速处理和过滤这些数据。针对每个车辆ID,筛选出该车辆在不同帧中的检测结果,检查连续帧之间是否存在缺失。当发现某一帧与上一帧之间存在间隔时,利用插值方法填补缺失的边界框。

导入所需库
代码语言:python
代码运行次数:0
复制
import csv

import numpy as np

from scipy.interpolate import interp1d
**提取必要列**

首先提取输入数据中的帧编号、车辆ID和边界框。

代码语言:python
代码运行次数:0
复制
def interpolate\_bounding\_boxes(data):

    frame\_numbers = np.array([int(row['frame\_nmr']) for row in data])

    car\_ids = np.array([int(float(row['car\_id'])) for row in data])

    car\_bboxes = np.array([list(map(float, row['car\_bbox'][1:-1].split())) for row in data])

    license\_plate\_bboxes = np.array([list(map(float, row['license\_plate\_bbox'][1:-1].split())) for row in data])
**处理每个车辆ID**

接着,对每个唯一的车辆ID进行处理,筛选该车辆在不同帧中的检测结果,并检测是否存在缺失。

代码语言:python
代码运行次数:0
复制
    interpolated\_data = []

    unique\_car\_ids = np.unique(car\_ids)



    for car\_id in unique\_car\_ids:

        frame\_numbers\_ = [p['frame\_nmr'] for p in data if int(float(p['car\_id'])) == int(float(car\_id))]

        car\_mask = car\_ids == car\_id

        car\_frame\_numbers = frame\_numbers[car\_mask]

        car\_bboxes\_interpolated = []

        license\_plate\_bboxes\_interpolated = []
**插值填补**

当检测到某一帧与上一帧之间存在间隔时,使用插值方法填补缺失的边界框。

代码语言:python
代码运行次数:0
复制
        for i in range(len(car\_bboxes[car\_mask])):

            frame\_number = car\_frame\_numbers[i]

            car\_bbox = car\_bboxes[car\_mask][i]

            license\_plate\_bbox = license\_plate\_bboxes[car\_mask][i]



            if i > 0:

                prev\_frame\_number = car\_frame\_numbers[i - 1]

                prev\_car\_bbox = car\_bboxes\_interpolated[-1]

                prev\_license\_plate\_bbox = license\_plate\_bboxes\_interpolated[-1]



                if frame\_number - prev\_frame\_number > 1:

                    frames\_gap = frame\_number - prev\_frame\_number

                    x = np.array([prev\_frame\_number, frame\_number])

                    x\_new = np.linspace(prev\_frame\_number, frame\_number, num=frames\_gap, endpoint=False)



                    interp\_func = interp1d(x, np.vstack((prev\_car\_bbox, car\_bbox)), axis=0, kind='linear')

                    interpolated\_car\_bboxes = interp\_func(x\_new)

                    interp\_func = interp1d(x, np.vstack((prev\_license\_plate\_bbox, license\_plate\_bbox)), axis=0, kind='linear')

                    interpolated\_license\_plate\_bboxes = interp\_func(x\_new)



                    car\_bboxes\_interpolated.extend(interpolated\_car\_bboxes[1:])

                    license\_plate\_bboxes\_interpolated.extend(interpolated\_license\_plate\_bboxes[1:])
**构建输出数据**

最后,将插值后的数据构建成新的记录,并准备写入CSV文件。

代码语言:python
代码运行次数:0
复制
            car\_bboxes\_interpolated.append(car\_bbox)

            license\_plate\_bboxes\_interpolated.append(license\_plate\_bbox)



        for i in range(len(car\_bboxes\_interpolated)):

            frame\_number = first\_frame\_number + i

            row = {

                'frame\_nmr': str(frame\_number),

                'car\_id': str(car\_id),

                'car\_bbox': ' '.join(map(str, car\_bboxes\_interpolated[i])),

                'license\_plate\_bbox': ' '.join(map(str, license\_plate\_bboxes\_interpolated[i])),

                'license\_plate\_bbox\_score': '0',

                'license\_number': '0',

                'license\_number\_score': '0'

            }



            if str(frame\_number) in frame\_numbers\_:

                original\_row = [p for p in data if int(p['frame\_nmr']) == frame\_number and int(float(p['car\_id'])) == int(float(car\_id))][0]

                row['license\_plate\_bbox\_score'] = original\_row.get('license\_plate\_bbox\_score', '0')

                row['license\_number'] = original\_row.get('license\_number', '0')

                row['license\_number\_score'] = original\_row.get('license\_number\_score', '0')



            interpolated\_data.append(row)



    return interpolated\_data
**从CSV文件加载数据并写入更新后的数据**:
代码语言:python
代码运行次数:0
复制
with open('test.csv', 'r') as file:

    reader = csv.DictReader(file)

    data = list(reader)



interpolated\_data = interpolate\_bounding\_boxes(data)



header = ['frame\_nmr', 'car\_id', 'car\_bbox', 'license\_plate\_bbox', 'license\_plate\_bbox\_score', 'license\_number', 'license\_number\_score']

with open('test\_interpolated.csv', 'w', newline='') as file:

    writer = csv.DictWriter(file, fieldnames=header)

    writer.writeheader()

    writer.writerows(interpolated\_data)

这种处理方式确保即使在没有检测到车牌的帧中,也能提供合理的边界框数据,从而提升数据集的完整性和准确性。填补完成后,将补充的数据输出到一个新的CSV文件中,确保数据集的完整性。这样做的意义在于,系统能够在处理过程中自动适应和修复数据的缺失,减少人为干预,提升了自动化处理的效率。

4. util.py:实用工具函数模块

util.py 模块包含了一些辅助函数,这些函数为整个车牌识别系统的其他模块提供支持,包括模型的加载、车牌的读取和格式化等功能。

OCR读取器初始化

首先,使用 easyocr 库初始化了一个OCR读取器,它支持英文字符的识别。以下是代码:

代码语言:python
代码运行次数:0
复制
import string

import easyocr



# 初始化OCR读取器,指定语言为英语,未启用GPU

reader = easyocr.Reader(['en'], gpu=False)
字符映射字典

这里定义了两个字典,用于在车牌识别过程中进行字符与数字之间的转换。

代码语言:python
代码运行次数:0
复制
# 字符到数字的映射

dict\_char\_to\_int = {

    'O': '0',

    'I': '1',

    'J': '3',

    'A': '4',

    'G': '6',

    'S': '5'

}



# 数字到字符的映射

dict\_int\_to\_char = {

    '0': 'O',

    '1': 'I',

    '3': 'J',

    '4': 'A',

    '6': 'G',

    '5': 'S'

}
写入CSV文件的函数

write\_csv 函数用于将识别结果写入CSV文件。它接受两个参数:结果字典和输出文件路径。

代码语言:python
代码运行次数:0
复制
def write\_csv(results, output\_path):

    """

    将结果写入CSV文件。



    参数:

        results (dict): 包含结果的字典。

        output\_path (str): 输出CSV文件的路径。

    """

    with open(output\_path, 'w') as f:

        # 写入CSV文件的表头

        f.write('{},{},{},{},{},{},{}\n'.format(

            'frame\_nmr', 'car\_id', 'car\_bbox',

            'license\_plate\_bbox', 'license\_plate\_bbox\_score', 'license\_number',

            'license\_number\_score'

        ))



        # 遍历结果字典并写入每一行

        for frame\_nmr in results.keys():

            for car\_id in results[frame\_nmr].keys():

                print(results[frame\_nmr][car\_id])  # 打印当前车辆的信息

                if 'car' in results[frame\_nmr][car\_id].keys() and \

                   'license\_plate' in results[frame\_nmr][car\_id].keys() and \

                   'text' in results[frame\_nmr][car\_id]['license\_plate'].keys():

                    # 写入车牌识别结果到CSV文件

                    f.write('{},{},{},{},{},{},{}\n'.format(

                        frame\_nmr,

                        car\_id,

                        '[{} {} {} {}]'.format(

                            results[frame\_nmr][car\_id]['car']['bbox'][0],

                            results[frame\_nmr][car\_id]['car']['bbox'][1],

                            results[frame\_nmr][car\_id]['car']['bbox'][2],

                            results[frame\_nmr][car\_id]['car']['bbox'][3]

                        ),

                        '[{} {} {} {}]'.format(

                            results[frame\_nmr][car\_id]['license\_plate']['bbox'][0],

                            results[frame\_nmr][car\_id]['license\_plate']['bbox'][1],

                            results[frame\_nmr][car\_id]['license\_plate']['bbox'][2],

                            results[frame\_nmr][car\_id]['license\_plate']['bbox'][3]

                        ),

                        results[frame\_nmr][car\_id]['license\_plate']['bbox\_score'],

                        results[frame\_nmr][car\_id]['license\_plate']['text'],

                        results[frame\_nmr][car\_id]['license\_plate']['text\_score']

                    ))

        f.close()  # 关闭文件
检查车牌格式的函数

license\_complies\_format 函数用于检查车牌文本是否符合规定的格式。该格式要求车牌文本长度为7个字符,并且每个字符的位置都有特定的要求。

代码语言:python
代码运行次数:0
复制
def license\_complies\_format(text):

    """

    检查车牌文本是否符合规定格式。



    参数:

        text (str): 车牌文本。



    返回:

        bool: 如果符合格式返回True,否则返回False。

    """

    if len(text) != 7:

        return False



    # 检查每个字符是否符合要求

    if (text[0] in string.ascii\_uppercase or text[0] in dict\_int\_to\_char.keys()) and \

       (text[1] in string.ascii\_uppercase or text[1] in dict\_int\_to\_char.keys()) and \

       (text[2] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] or text[2] in dict\_char\_to\_int.keys()) and \

       (text[3] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] or text[3] in dict\_char\_to\_int.keys()) and \

       (text[4] in string.ascii\_uppercase or text[4] in dict\_int\_to\_char.keys()) and \

       (text[5] in string.ascii\_uppercase or text[5] in dict\_int\_to\_char.keys()) and \

       (text[6] in string.ascii\_uppercase or text[6] in dict\_int\_to\_char.keys()):

        return True

    else:

        return False
格式化车牌的函数

format\_license 函数用于将车牌文本格式化,使用预定义的映射字典转换字符。

代码语言:python
代码运行次数:0
复制
def format\_license(text):

    """

    通过使用映射字典格式化车牌文本。



    参数:

        text (str): 车牌文本。



    返回:

        str: 格式化后的车牌文本。

    """

    license\_plate\_ = ''

    mapping = {

        0: dict\_int\_to\_char,

        1: dict\_int\_to\_char,

        4: dict\_int\_to\_char,

        5: dict\_int\_to\_char,

        6: dict\_int\_to\_char,

        2: dict\_char\_to\_int,

        3: dict\_char\_to\_int

    }

    for j in [0, 1, 2, 3, 4, 5, 6]:

        if text[j] in mapping[j].keys():

            license\_plate\_ += mapping[j][text[j]]  # 根据映射字典转换字符

        else:

            license\_plate\_ += text[j]  # 如果字符不在字典中,直接添加



    return license\_plate\_
读取车牌文本的函数

read\_license\_plate 函数从给定的裁剪图像中读取车牌文本,并返回格式化后的文本及其置信度分数。

代码语言:python
代码运行次数:0
复制
def read\_license\_plate(license\_plate\_crop):

    """

    从给定的裁剪图像中读取车牌文本。



    参数:

        license\_plate\_crop (PIL.Image.Image): 裁剪后的车牌图像。



    返回:

        tuple: 包含格式化车牌文本和置信度分数的元组。

    """

    detections = reader.readtext(license\_plate\_crop)  # 使用OCR读取文本



    for detection in detections:

        bbox, text, score = detection  # 解包检测结果



        text = text.upper().replace(' ', '')  # 将文本转换为大写并去除空格



        if license\_complies\_format(text):  # 检查格式是否符合

            return format\_license(text), score  # 返回格式化后的文本和分数



    return None, None  # 如果没有符合的文本,返回None
获取车辆坐标的函数

get\_car 函数根据车牌坐标和车辆的追踪ID,返回车辆的坐标和ID。

代码语言:python
代码运行次数:0
复制
def get\_car(license\_plate, vehicle\_track\_ids):

    """

    根据车牌坐标和车辆追踪ID获取车辆坐标和ID。



    参数:

        license\_plate (tuple): 包含车牌坐标 (x1, y1, x2, y2, score, class\_id) 的元组。

        vehicle\_track\_ids (list): 车辆追踪ID及其对应坐标的列表。



    返回:

        tuple: 包含车辆坐标 (x1, y1, x2, y2) 和ID的元组。

    """

    x1, y1, x2, y2, score, class\_id = license\_plate



    foundIt = False

    for j in range(len(vehicle\_track\_ids)):

        xcar1, ycar1, xcar2, ycar2, car\_id = vehicle\_track\_ids[j]



        # 检查车牌坐标是否在车辆坐标内

        if x1 > xcar1 and y1 > ycar1 and x2 < xcar2 and y2 < ycar2:

            car\_indx = j

            foundIt = True

            break



    if foundIt:

        return vehicle\_track\_ids[car\_indx]  # 返回找到的车辆坐标和ID



    return -1, -1, -1, -1, -1  # 如果没有找到,返回负值

这部分实现了车牌的读取、格式化及输出,确保车牌识别的准确性和结果的有效管理。

至此,代码结束,理解并实现车辆车牌识别代码对我这样的小白还是有些困难,还需多实践,多学习 yolov8 的相关项目及知识,加油加油!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. main.py:项目的核心入口
    • 加载模型
    • 读取视频
    • 检测车辆
    • 追踪车辆
    • 检测车牌
    • 裁剪和处理车牌
    • 写入结果
  • 2. visualize.py:结果可视化模块
    • 导入所需库
    • 绘制边框的函数
    • 读取识别结果数据
    • 加载视频
    • 初始化车牌信息字典
    • 逐帧读取视频并绘制识别结果
  • 3. add\_missing\_data.py:处理缺失数据
    • 导入所需库
    • **提取必要列**
    • **处理每个车辆ID**
    • **插值填补**
    • **构建输出数据**
    • **从CSV文件加载数据并写入更新后的数据**:
  • 4. util.py:实用工具函数模块
    • OCR读取器初始化
    • 字符映射字典
    • 写入CSV文件的函数
    • 检查车牌格式的函数
    • 格式化车牌的函数
    • 读取车牌文本的函数
    • 获取车辆坐标的函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档