基于YOLO V8的车牌识别

news2024/11/20 0:41:59

赵春江

2023年6月

1、前言

十年前就想实现车牌识别这项任务,虽然当时这项技术就已较成熟(与现在的实现方法不同),但那时的我还具备这个能力。弹指一瞬间,没想到十年间人工智能技术已经发展到一个新的高度,图像识别早已不成问题,以ChapGPT为代表的生成式技术大行其道。写作、作曲、绘画等内容创作,甚至编程都可由计算机自动完成,这在以前只会出现在电影里。

回到主题,正如上文提到的那样,图像识别经过十几年的发展,已经不再触不可及。基于各类预训练模型,通过简单的微调和迁移学习,就可以实现我们想要的各类图像分类、图像识别和图像分割。在这里,我们利用YOLO V8,以车牌识别为研究对象,抛砖引玉地讲解一下图像识别的实现方法(并没有涉及具体的技术细节),以完成我十年前的愿望。

2、实现

我们识别的车牌为正面水平放置的蓝底白字车牌,如下图所示的位置及车牌。对于其他位置和类型的车牌,本人并不能保证能够正确识别。

 2.1、数据准备

数据收集整理和预处理一直都是深度学习最关键的一步。在这里我们使用的图像都来源于网上搜索和本人亲自拍摄。我把车牌识别分为两个步骤:第一步是提取出车牌,第二步是由车牌图像识别出车牌字符。因此需要有两个数据集,一个是含有车牌的图像,另一个是只含有车牌的图像。对于第一个数据集,我们需要标注出车牌的位置;对于第二个数据集,我们不仅需要标注出字符的位置,还需要标注出是哪个字符。这是一项很繁琐的工作,数据集不能太少,标注信息更要准确。

好在我们可以借助https://roboflow.com/这网站,减轻一些标注工作的劳动强度。具体如何标注,在这里就不再赘述。总之我已经标注好了,大家只需下载即可,网址分别为:

含车牌的数据集:

https://universe.roboflow.com/zhao-chunjiang-jztse/chinese-plate-license

只含车牌的数据集:

https://universe.roboflow.com/zhao-chunjiang-jztse/chinese-plate-license-character/dataset/2

这里需要说明的是,由于本人没有能力收集到足够数量的各个省市区的车牌图像,所以识别出的字符并不包括代表省市区的汉字

2.2、车牌识别

有了数据集,下面就可以开始训练了。我们在google colab内编写程序,这对于那些没有GPU的人来说,再合适不过的了。

首先,利用含有车牌的数据集训练能够识别车牌的模型:

加载谷歌云盘

from google.colab import drive
drive.mount('/content/drive')

下载并安装ultralytics

!pip install ultralytics

训练模型

from ultralytics import YOLO

model = YOLO("yolov8m.pt")
#train the model
results = model.train(data="/content/drive/MyDrive/Chinese plate license/data.yaml",
                    epochs=120,
                    imgsz=640)

把训练得到的最好模型best.pt保存在谷歌云盘内,供以后使用

import shutil
shutil.copy("/content/runs/detect/train/weights/best.pt","/content/drive/MyDrive/plate.pt")

简单的测试一下训练效果,把测试图像上传至colab内,然后调用模型,最后显示结果图像

model = YOLO("/content/drive/MyDrive/plate.pt")
results = model.predict(source="/content/cars.jpg", save=True)

from PIL import Image
import matplotlib.pyplot as plt
image = Image.open("/content/runs/detect/predict/cars.jpg")
plt.imshow(image)

最终结果为:

以上的代码可以在google colab中看到并运行:

https://colab.research.google.com/gist/ZhaoChunjiang/0d8cc1789eb01af28d6176095eb0b024/plate.ipynb

2.3、字符识别

然后,利用只含车牌的数据集训练能够识别字符的模型:

加载谷歌云盘

from google.colab import drive
drive.mount('/content/drive')

下载并安装ultralytics

!pip install ultralytics

训练模型

from ultralytics import YOLO
model = YOLO("yolov8m.pt")

# train the model
results = model.train(data="/content/drive/MyDrive/Chinese plate license character/data.yaml",
                    epochs=120,
                    imgsz=[448,140])

把训练得到的最好模型best.pt保存在谷歌云盘内,供以后使用

import shutil
shutil.copy("/content/runs/detect/train/weights/best.pt","/content/drive/MyDrive/char.pt")

简单的测试一下训练效果,把测试图像上传至colab内,然后调用模型,最后显示结果图像

model = YOLO("/content/drive/MyDrive/char.pt")
results = model.predict(source="/content/plate.jpg", save=True)

from PIL import Image
import matplotlib.pyplot as plt
image = Image.open("/content/runs/detect/predict/plate.jpg")
plt.imshow(image)

最终结果为:

以上的代码可以在google colab中看到并运行:

https://colab.research.google.com/gist/ZhaoChunjiang/8b6ece0dce6fc959dac8b52604997f02/char.ipynb

通过前面两段代码,我们分别得到了识别车牌和字符的网络模型plate.pt和char.pt。为便于大家使用和验证,我把这两个已训练好的网络模型上传至百度云盘,大家也就不用再运行2.2和2.3部分的程序,只要利用这两个pt文件,执行2.4部分的代码,就可以实现车牌识别。

链接:https://pan.baidu.com/s/1cZdg_2pZ5JTTq09l_kN_vQ

提取码:wasd

2.4、车牌字符识别

下面我们就给出车牌识别的完整代码:

加载谷歌云盘

from google.colab import drive
drive.mount('/content/drive')

下载并安装ultralytics

!pip install ultralytics

加载已训练好的检测车牌和字符的模型plate.pt和char.pt,这两个模型都已事先上传至谷歌云盘内

from ultralytics import YOLO
modelPlate = YOLO("/content/drive/MyDrive/plate.pt")
modelChar = YOLO("/content/drive/MyDrive/char.pt")

定义待识别的图像(事先已上传至colab内)和字符数组

car = "/content/drive/MyDrive/555.jpg"

charclass = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '8', '5', '4', '9', '1', '7', '6', '3', '2', '0']

定义用于在图像中显示字符的函数,它的作用主要是根据图像的大小调整显示字符的大小

import cv2

def box_label(image, box, label='', color=(19, 222, 24), txt_color=(255, 255, 255)):
   #根据图像的大小,选择画笔的粗细
   lw = max(round(sum(image.shape) / 2 * 0.003), 2)
   #得到该矩形的左上角和右下角坐标
   p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3]))
   #绘制矩形框
   cv2.rectangle(image, p1, p2, color, thickness=lw, lineType=cv2.LINE_AA)
   #绘制标签
   if label:
      tf = max(lw - 1, 1)  # font thickness
      w, h = cv2.getTextSize(label, 0, fontScale=lw / 3, thickness=tf)[0]  # text width, height
      outside = p1[1] - h >= 3
      p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3
      cv2.rectangle(image, p1, p2, color, -1, cv2.LINE_AA)  # filled
      cv2.putText(image, label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2),
                0,
                lw / 3,
                txt_color,  #白色
                thickness=tf,
                lineType=cv2.LINE_AA)

检测车牌

results1 = modelPlate.predict(source=car)
boxes = results1[0].boxes.data.cpu().numpy()[:,:4]
#print(boxes)

识别并显示车牌字符

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from google.colab.patches import cv2_imshow

imge = Image.open(car)
img = np.asarray(imge)

for i in range(len(boxes)):
   plate = imge.crop(boxes[i])
   results2 = modelChar.predict(plate)
   chars = results2[0].boxes.data.cpu().numpy()
   inde = np.argsort(chars[:,0])
   char = chars[:,5]
   res = ""
   for j in range(len(chars)):
      res += charclass[int(char[inde[j]])]
      if j==0:
         res += " "

   box_label(img, boxes[i], res)

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2_imshow(img) #在Colab中使用,否则用cv2.imshow

最终的结果为:

我们再看看另一个测试结果:

以上的代码可以在google colab中看到并运行:

https://colab.research.google.com/gist/ZhaoChunjiang/993f9c5936debc79013ea24e19dc8b1e/plate_dection.ipynb

3、小结

经过多次测试可以看出,只要车牌的分辨率足够大,该系统是能够准确识别车牌字符的。唯一的遗憾就是还不能实现对汉字的识别(因数据不够多)。希望大家也用自己的图像测试一下。

4、谢谢

如果您觉得这篇文章对您有一些帮助,可以获得一些灵感,请您微信打赏,十分感谢!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/691498.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【每日编程Day29】有假币

目录 一、选择题 二、编程题 1、有假币 一、选择题 重点复习选择题4,8,10。 问题4: 类方法:又称为静态方法。而实例方法不能加static,又叫非静态方法。 类方法和实例方法的区别_类方法和实例方法区别_及可不遥的博客-CSDN博客 &#xff0…

效果!R微型变压器节省空间秘密揭晓!

通常,我们可能会遇到一些特殊的设备。由于其设计空间有限,R型变压器的体积应足够小,以便很好地应用。针对市场上的这个问题,作为R型变压器生产厂家,我们怎么能不注意呢?因此,我们的设计研发团队…

明确了!国家发布程序员和搬砖民工一样,都是农民工!

目录 前言 怎么解释新生代农民工? 2019年确定程序员属于密集型劳动者 新生代民工确实非常形象: 总结: 前言 前几天我们发现,人社局官网发布了一则报告,显示软件开发和信息技术服务业都属于新生农工,不…

前端获取地区的天气状况

翻阅了大量的帖子,在赛选了很多废的帖子之后找到了两个总体来说还不错的 一:配置高德地图 高德地图的查看天气的话,是每天免费100次 先访问高德官网:高德控制台,注册后申请应用,获取key值。 这个key值可…

三步轻松搞定,Word图片打印清晰度提升10倍

Word文档中插入图片是非常常见的操作,然而,在打印时有时会遇到图片清晰度不够的问题。这种情况下,即使图片在电脑上看起来很清晰,但是在打印时却变得模糊不清。这可能会影响工作效率,甚至影响到呈现效果。那么&#xf…

Java 面试必刷的1100 道Java大厂面试真题(含答案解析)

2023秋招即将来临,很多同学会问 Java 面试八股文有必要背吗? 我的回答是:很有必要。你可以讨厌这种模式,但你一定要去背,因为不背你就进不了大厂。 国内的互联网面试,恐怕是现存的、最接近科举考试的制度…

yolov8训练自有跌倒数据集

参考: https://www.bilibili.com/video/BV1xL411B7ax https://www.dgrt.cn/a/2364195.html?actiononClick https://blog.roboflow.com/how-to-train-yolov8-on-a-custom-dataset/ 1、数据集制作(一般是coco格式): lableme&a…

如何用手机快速获得真人手办所需的人像模型

伴随网络生活覆盖面的增大,越来越多的领域需要三维模型 ,比如最近爆火的真人手办就必须用到人像模型 。 真人手办的制作过程其实非常简单,在专门搭建的摄影棚内进行全身3D扫描,获得3D人体模型,然后进行修模&#xff0c…

WordCount是什么?WordCount编程实现思路

WordCount算是大数据计算领域经典的入门案例,相当于Hello World。 虽然WordCount业务极其简单,但是希望能够通过案例感受背后MapReduce的执行流程和默认的行为机制,这才是关键。 WordCount编程实现思路 map阶段的核心:把输入的数…

C#.NETWPF开发工业MES MCS系统软件源代码两套

产品介绍: C#.NETWPF开发工业MES MCS系统软件源代码两套 A,WPF MES 上位机产线执行系统。 1, 完整纯源代码; 2, AGV自动调度; 3, SQLSERVER数据库。带附加文件。 4, WPF各种技术…

慕了!17年阿里Java开发大佬把Spring Boot的精髓都总结出来了

目前ssm框架还是比较常用的,其中的ss指的无非就是Spring 和 SpringMVC,我们可以简单地认为 "Spring Boot ≥ Spring SpringMVC" ,没错,用了Spring Boot中涵盖了Spring和SpringMVC等大量常用开发配置,而且S…

想知道识别文字的软件有哪些?分享文字识别软件有哪些

嗨~小伙伴们,你们是否有过手写笔记或者拍照存档时不小心照模糊、字迹潦草的经历呢?别担心,现在有很多文字识别软件可以帮助我们迅速将纸质笔记、图片等转化成电子版,方便管理和编辑。今天我们就一起来看看文字识别软件有哪些吧&am…

javaDoc中进行页面跳转

在写java代码时,我们可以写一些用于代码跳转或者网页跳转的注释,这样一来,我们在开发软件(比如Idea)中就可以通过ctrl鼠标直接跳转。 常用的是{link}和see,两种用法基本一样,区别见下方。 {link…

vant组件改为 uview-plus 组件的时分秒组件

项目中本来使用过了vant 的组件,但是uniapp 和vant并不兼容,除了几个普通的组件能用之外,想使用弹窗的话vant就完成不了了,还好uniapp官方支持的 uview-plus 支持vue3,就给项目更换了。之前使用vant封装的组件这时候也…

品达通用权限系统-Day02

文章目录 2.3 自定义starter2.3.1 案例一2.3.1.1 开发starter2.3.1.2 使用starter 2.3.2 案例二2.3.2.1 开发starter2.3.2.2 使用starter 2.3 自定义starter 本小节我们通过自定义两个starter来加强starter的理解和应用。 2.3.1 案例一 2.3.1.1 开发starter 开发工具&#…

软件测试入门(了解软件)

一、什么是软件 软件:通过大代码逻辑开发出来的程序,称为软件。 二、软件的种类 web端:电脑、手机的浏览器可以打开的网页,就是web的软件。比如:公司官网、淘宝网等等 客户端:电脑客户端:需要…

聊聊glibc中malloc函数的unlink

unlink的意思其实就是删除。在介绍这个函数之前,我们得介绍一点概念。在程序中,如果我们使用malloc申请的内存在不用或者不需要的时候,是需要程序员手动去释放,也就是free操作。我们知道malloc操作free操作都是涉及到内存管理的。…

USB Monitor只抓数据时的设置

一,简介 在抓HID数据时,只关注数据的收发,不太关注其他的数据例如SOF等信息,所以要对上位机软件的过滤设置进行勾选。 二,过滤设置 原则:带data的都要,不带data的可以不要。 点击“设置”-&…

挽输出和开漏输出

GPIO口配置为输出时会有两种模式,一种叫推挽输出,一种叫开漏模式。 三种输出状态 如下图所示为将GPIO配置为输出时的内部示意图: 由上图可以看出,GPIO的输出状态完全取决于两个MOS管Q1和Q2的导通状态: Q1导通、Q2关断…

js 数组中和为 0 的三个数

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例 …