Tensorflow车牌识别完整项目(含完整源代码及训练集)

article/2025/9/11 18:39:11

基于TensorFlow的车牌识别系统设计与实现,运用tensorflow和OpenCV的相关技术,实现车牌的定位、车牌的二值化、车牌去噪增强、图片的分割,模型的训练和车牌的识别等

项目问题,毕设,大创可私聊博主

目录

环境准备

思路流程

功能描述

细节阐述

项目总体框架

过程展示

技术简介

一、Tensorflow

二、OpenCV

系统设计

项目实现

最后


环境准备

    Anaconda 4.10.3
    Tensorflow 2.6.0
    python3.7.8
    coding: utf-8
    pycharm解释器:D:\Anaconda\envs\tensorflow\python.exe
    以及各种第三方库

思路流程

1、将图片通过opencv切割识别定位车牌,切割保存

2、识别省份简称、识别城市代号、识别车牌编号

功能描述

    car_num_main.py  :将图片转为灰度图像,灰度图像二极化,分割图像并分别保存为.jpg和.bmp文件
    train-license-province.py : 省份简称训练识别  
    train-license-letters.py :城市代号训练识别
    train-license-digits.py :车牌编号训练识别

细节阐述

    1、图片切割后分别保存在两个文件夹./img_cut   and    ./img_cut_not_3240
    2、识别车牌需进入终端,在命令行中进入脚本所在目录,
    输入执行如下命令:python train-license-province.py train 进行省份简称训练
    输入执行如下命令:python train-license-province.py predict 进行省份简称识别
    输入执行如下命令:python train-license-letters.py train 进行城市代号训练
    输入执行如下命令:python train-license-letters.py predict 进行城市代号识别
    输入执行如下命令:python train-license-digits.py train 进行车牌编号训练
    输入执行如下命令:python train-license-digits.py predict 进行车牌编号识别
    3、将要识别的图片调为.jpg格式,大小调为像素600*413最佳,可依据代码酌情调试
    4、具体可以准确识别的车牌号参见数据集中训练集

测试数据集

项目总体框架

capture_img :存放将要识别的车牌图片

img_cut:运行car_num_main.py后生成切割后的图片

img_cut_not_3240 :运行  car_num_main.py  后生成切割后的图片(对比度加强)

test_images:存放测试图片

train_images:  存放训练图片

train-saver: 训练模型

过程展示

PS D:\pycharm\pycharm_work> cd .\chepai\
PS D:\pycharm\pycharm_work\chepai> python train-license-province.py train

PS D:\pycharm\pycharm_work\chepai> python train-license-province.py predict

PS D:\pycharm\pycharm_work\chepai> python train-license-digits.py predict

技术简介

一、Tensorflow

        TensorFlow是一个开放源代码软件库,用于进行高性能数值计算。借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、GPU、TPU)和设备(桌面设备、服务器集群、移动设备、边缘设备等)。

        TensorFlow 是一个用于研究和生产的开放源代码机器学习库。TensorFlow 提供了各种 API,可供初学者和专家在桌面、移动、网络和云端环境下进行开发。

        TensorFlow是采用数据流图(data flow graphs)来计算,所以首先我们得创建一个数据流流图,然后再将我们的数据(数据以张量(tensor)的形式存在)放在数据流图中计算。节点(Nodes)在图中表示数学操作,图中的边(edges)则表示在节点间相互联系的多维数据数组, 即张量(tensor)。训练模型时tensor会不断的从数据流图中的一个节点flow到另一节点。

二、OpenCV

        OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

        OpenCV提供的视觉处理算法非常丰富,并且它部分以C语言编写,加上其开源的特性,处理得当,不需要添加新的外部支持也可以完整的编译链接生成执行程序,所以很多人用它来做算法的移植,OpenCV的代码经过适当改写可以正常的运行在DSP系统和ARM嵌入式系统中。其应用领域诸如:人机互动,物体识别,图像分割,人脸识别,动作识别,运动跟踪,机器人,运动分析,机器视觉,结构分析,汽车安全驾驶等领域。

系统设计

        车牌自动识别是以计算机视觉处理、数字图像处理、模式识别等技术为基础,对摄像机所拍摄的车辆图像或者视频图像进行处理分析,得到每辆车的车牌号码,从而完成识别的过程。在此基础上,可实现停车场出入口收费管理、盗抢车辆管理、高速公路超速自动化管理、闯红灯电子警察、公路收费管理等各种交通监管功能。

一、系统处理流程

        车牌自动识别系统的设计包含车辆图像获取、车牌区域定位、车牌特征轮廓提取和车牌内容识别环节。

二、车牌获取

         车牌图像获取是进行车牌识别的首要环节,车牌图像可以从摄像机拍摄的车辆图像或者视频图像中进行抽取,车牌图像的获取也可由用户手机拍摄后传入车牌识别系统。

三、灰度图像生成

        摄像机拍摄的含有车牌信息的车辆图像是彩色的,为了提高车牌识别的抗外界干扰的能力,先将彩色车辆图像生成二值的灰度图像,实现基于色调的车牌区域定位。由于国内的车牌往往是蓝底白字,因此,可以利用图像的色调或者色彩饱和度特征,生成二值灰度图像,从而实现更加准确地定位车牌位置。

四、车牌区域定位

        车牌区域的定位采用基于形状的方法。由于车辆图像背景比较复杂,所以应该根据车牌的特征进行初次筛选。车牌的特征可以选择中国车牌的大小、比例特征,因为车牌都是固定的矩形形状,通过首先寻找图像上拥有矩形特征的区域,然后再抽取这些区域,再结合车牌的长宽的比例特征可以筛选出相应的矩形区域,从而实现对车牌的准确定位。

五、特征轮廓提取

        OpenCV 与 Python 的接口中使用 cv2.fifindContours() 函数来查找检测物体的轮廓。

图3 和 图4 为特征轮廓提取前后的效果对比图 :

六、车牌内容识别

        车牌内容识别时,通过计算候选车牌区域蓝色数值(均值)的最大值,确定最终的车牌区域。对于选定的车牌轮廓,首先进行粗定位,即对车牌进行左右边界回归处理,去除车牌两边多余的部分,然后进行精定位,即将车牌送入 CRNN 网络进行字符识别,利用左右边界回归模型,预测出车牌的左右边框,进一步裁剪,进行精定位。基于文字特征的方法是根据文字轮廓特征进行识别,经过相应的算法解析,得到结果。

项目实现

核心代码展现

一、检测车牌

def find_car_num_brod():watch_cascade = cv2.CascadeClassifier('D:\pycharm\pycharm_work\chepai\cascade.xml')# 先读取图片image = cv2.imread("D:\pycharm\pycharm_work\chepai\capture_img\car1.jpg")resize_h = 1000height = image.shape[0]scale = image.shape[1] / float(image.shape[0])image = cv2.resize(image, (int(scale * resize_h), resize_h))image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)watches = watch_cascade.detectMultiScale(image_gray, 1.2, 2, minSize=(36, 9), maxSize=(36 * 40, 9 * 40))print("检测到车牌数", len(watches))for (x, y, w, h) in watches:cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 1)cut_img = image[y + 5:y - 5 + h, x + 8:x  + w]  # 裁剪坐标为[y0:y1, x0:x1]cut_gray = cv2.cvtColor(cut_img, cv2.COLOR_RGB2GRAY)cv2.imwrite("D:\pycharm\pycharm_work\chepai\\num_for_car.jpg", cut_gray)im = Image.open("D:\pycharm\pycharm_work\chepai\\num_for_car.jpg")size = 720, 180mmm = im.resize(size, Image.ANTIALIAS)mmm.save("D:\pycharm\pycharm_work\chepai\\num_for_car.jpg", "JPEG", quality=90)break

二、二值化图像

def cut_car_num_for_chart():# 1、读取图像,并把图像转换为灰度图像并显示img = cv2.imread("D:\pycharm\pycharm_work\chepai\\num_for_car.jpg")  # 读取图片img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换了灰度化cv2.imshow('gray', img_gray)  # 显示图片cv2.waitKey(0)# 2、将灰度图像二值化,设定阈值是100   转换后 白底黑字 ---》 目标黑底白字img_thre = img_gray# 灰点  白点 加错# cv2.threshold(img_gray, 130, 255, cv2.THRESH_BINARY_INV, img_thre)# 二值化处理 自适应阈值   效果不理想# th3 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)# 高斯除噪 二值化处理blur = cv2.GaussianBlur(img_gray, (5, 5), 0)ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)cv2.imshow('threshold', th3)cv2.imwrite('D:\pycharm\pycharm_work\chepai\wb_img.jpg', th3)cv2.waitKey(0)

        第一行imread(),由于flag设为1所以读的是彩图,采用cvtColor函数转化为灰度图。如果你读入就是灰度图可以省略第二行代码,然后转化为二值化函数,阈值180可以修改,后经过增强处理,效果如图所示:

 三、单字符切割

        单字符分割主要策略就是检测列像素的总和变化,因为没有字符的区域基本是黑色,像素值低;有字符的区域白色较多,列像素和就变大了!

        列像素变化的阈值是个问题,看到很多博客是固定的阈值进行检测,除非你处理后的二值化图像非常完美,不然有的图片混入了白色区域就会分割错误!

        考虑到车牌中只有7个字符,所以先判断得到宽度大小,如果小于总宽的七分之一视为干扰放弃;其实也可以加大到总宽的8分之一(因为车牌中间可能有连接符)。

    n = 1start = 1end = 2temp = 1while n < width - 2:n += 1if (white[n] if arg else black[n]) > (0.05 * white_max if arg else 0.05 * black_max):# 上面这些判断用来辨别是白底黑字还是黑底白字# 0.05这个参数请多调整,对应上面的0.95start = nend = find_end(start, white, black, arg, white_max, black_max, width)n = end# 车牌框检测分割 二值化处理后 可以看到明显的左右边框  毕竟用的是网络开放资源 所以车牌框定位角度真的不准,# 所以我在这里截取单个字符时做处理,就当亡羊补牢吧# 思路就是从左开始检测匹配字符,若宽度(end - start)小与20则认为是左侧白条 pass掉  继续向右识别,否则说明是# 省份简称,剪切,压缩 保存,还有一个当后五位有数字 1 时,他的宽度也是很窄的,所以就直接认为是数字 1 不需要再# 做预测了(不然很窄的 1 截切  压缩后宽度是被拉伸的),# shutil.copy()函数是当检测到这个所谓的 1 时,从样本库中拷贝一张 1 的图片给当前temp下标下的字符if end - start > 5:  # 车牌左边白条移除print(" end - start" + str(end - start))if temp == 1 and end - start < 20:passelif temp > 3 and end - start < 20:#  认为这个字符是数字1   copy 一个 32*40的 1 作为 temp.bmpshutil.copy(os.path.join("D:\pycharm\pycharm_work\chepai\fuzhi", "111.bmp"),  # 111.bmp 是一张 1 的样本图片os.path.join("D:\pycharm\pycharm_work\chepai\\img_cut\\", str(temp) + '.bmp'))passelse:cj = th3[1:height, start:end]cv2.imwrite("D:\pycharm\pycharm_work\chepai\img_cut_not_3240\\" + str(temp) + ".jpg", cj)im = Image.open("D:\pycharm\pycharm_work\chepai\img_cut_not_3240\\" + str(temp) + ".jpg")size = 32, 40mmm = im.resize(size, Image.ANTIALIAS)mmm.save("D:\pycharm\pycharm_work\chepai\img_cut\\" + str(temp) + ".bmp", quality=95)temp = temp + 1

车牌的切割效果如图所示:

 四、单字符识别

            max1 = 0max2 = 0max3 = 0max1_index = 0max2_index = 0max3_index = 0for j in range(NUM_CLASSES):if result[0][j] > max1:max1 = result[0][j]max1_index = jcontinueif (result[0][j] > max2) and (result[0][j] <= max1):max2 = result[0][j]max2_index = jcontinueif (result[0][j] > max3) and (result[0][j] <= max2):max3 = result[0][j]max3_index = jcontinuelicense_num = license_num + LETTERS_DIGITS[max1_index]print("概率:  [%s %0.2f%%]    [%s %0.2f%%]    [%s %0.2f%%]" % (LETTERS_DIGITS[max1_index], max1 * 100, LETTERS_DIGITS[max2_index], max2 * 100, LETTERS_DIGITS[max3_index],max3 * 100))print("车牌编号是: 【%s】" % license_num)

最终效果如图所示:

         注:此图为以下三个程序的运行结果图,我将图片拼接到一块了。。

train-license-province.py : 省份简称训练识别  
train-license-letters.py :城市代号训练识别
train-license-digits.py :车牌编号训练识别

最后

        车牌识别做不到100%识别成功,但通过训练已经基本可以达到98%以上的识别度,可以将capture_img文件中的图片(注意图片格式与大小会间接影响识别度,车牌名改为 car1.jpg)替换为自己的车牌照通过训练进行识别车牌照。

版本与实战文档尽量保持一致!可能会使用到此dll文件:cudart64__110 .zip

点此下载全部源码

车牌检测训练测试数据集

毕设项目专栏:https://blog.csdn.net/m0_54925305/category_11702151.html?spm=1001.2014.3001.5482



http://chatgpt.dhexx.cn/article/kfYlHuqV.shtml

相关文章

车牌识别:HyperLPR车牌识别代码解析

首先声明&#xff0c;这只是本人自己对HyperLPR代码的看法解析可能会有错还请多多谅解。 先贴上HyperLPR源码的链接HyperLPR 其中最有用的其实就是HyperLPRLite.py这个代码文件&#xff0c;原来Github上的使用教程可能有点老了不太适用&#xff0c;这边附上一个简单的demo使用&…

opencv + svm实现车牌识别(附完整代码)

一、实验目的 通过一张含有车牌的车的照片&#xff0c;分割出车牌并识别出图片上车的车牌号 二、具体内容 车牌定位车牌字符分割车牌字符识别 三、实验过程 1.车牌定位 具体过程&#xff1a; 1.灰度转换&#xff1a;将彩色图片转换为灰度图像&#xff0c;常见的RGB像素平均…

Java车辆牌照识别

Java车辆牌照识别 大家好&#xff0c;近期想做一个Java的车牌识别功能&#xff08;借助第三方百度云车牌识别API&#xff09;&#xff0c;大致搜索了一下相关的博客文档&#xff0c;没有看到有相对完整详细的文章&#xff0c;于是准备写一篇稍微详细一点的文章说明&#xff0c…

基于opencv的车牌识别解析与代码

Jeremy Lin HQU 车牌识别太出名了&#xff0c;我也就花几天来了解下这个系统&#xff0c;并结合opencv进行实现。下面是一些介绍&#xff1a; 车辆牌照识别&#xff08;License Plate Recognition&#xff0c;LPR&#xff09;技术作为交通管理自动化的重要手段和车辆检测系统的…

基于matlab的车牌识别

20221126 新增 首先说一下这个工程的思路&#xff0c;很多朋友妄想直接拿着工程用&#xff0c;那是不可能的&#xff0c;自己学去叭&#xff0c;我是先将车牌号预处理之后&#xff0c;整个图片干净一点之后&#xff0c;进行每个字符的切割&#xff0c;但是是很投机取巧的方法&a…

车牌识别步骤及部分代码

目录(?)[-] 车牌预处理字符分割归一化处理细化处理字符特征提取神经网络训练车牌图像识别结果测试 1.车牌预处理 车牌预处理过程的好坏直接影响到车牌图像进行后期处理过程&#xff0c;比如车牌字符分割等。车牌预处理也是尽可能的消除噪声&#xff0c;减少后期处理带来的不必…

车牌识别(毕业设计+代码)

简介与效果 用python3opencv3做的中国车牌识别&#xff0c;包括算法和客户端界面&#xff0c;只有2个文件&#xff0c;一个是界面代码&#xff0c;一个是算法代码&#xff0c;点击即可出结果&#xff0c;方便易用&#xff01; 大致的UI界面如下&#xff0c;点击输入图片&#…

真香!用Python检测和识别车牌(附代码)

车牌检测与识别技术用途广泛&#xff0c;可以用于道路系统、无票停车场、车辆门禁等。这项技术结合了计算机视觉和人工智能。 本文将使用Python创建一个车牌检测和识别程序。该程序对输入图像进行处理&#xff0c;检测和识别车牌&#xff0c;最后显示车牌字符&#xff0c;作为…

写好 API 接口文档,想清楚这几点

我在开始一个新的接口之前&#xff0c;需要进行以下判断&#xff1a; 请求协议是不是 HTTP、https? 请求体和响应格式是什么&#xff08;XML、JSON、FormData、Raw&#xff09;? API 是不是 RESTful 风格&#xff1f; 如果上面三个问题的答案都清楚了&#xff0c;就可以开…

API调用,API传参,面向对接开发,你真的会写接口文档吗?

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e2; &#x1f497; 你正在阅读 【梦想橡皮擦】 的博客 &#x1f44d; 阅读完毕&#xff0c;可以点点小手赞一下 &#x1f33b; 发现错误&#xff0c;直接评论区中指正吧 &#x1f4c6; 橡皮擦的第…

接口接口文档

一、接口简介 API&#xff08;Application Programming Interface&#xff09;即应用程序接口&#xff0c;可以任务是一个软件组件或一个Web服务与外界进行交互的接口&#xff0c;在这里接口可以和API划等号。 接口可以简单的理解为一个黑盒子&#xff0c;从一边输入参数&…

【编程规范】 后端API接口设计编写与文档编写参考

文章目录 0 统一规范0.1 理清业务流程0.2 定义前后端开发的接口规范0.3 定义接口文档 1 后端接口编写1.0 后端接口介绍1.0.1 接口交互1.0.2 返回格式1.0.3 CODE状态码1.0.4 Message&#xff08;Msg&#xff09;1.0.5 DATA 1.1 数据校验与异常处理1.1.1 参数校验设计1.1.2 全局异…

如何根据接口文档,写一个接口类(举例说明)

直接先贴图&#xff08;文中的url做了修改&#xff09;&#xff1a; 代码如下&#xff1a; FeignClient(name "Z_KPI_API",url "${Z.KPI.url:http://11.11.111.111:8080}",fallback ZApiClientFallback.class) public Interface ZApiClient{PostMappin…

Postman写接口文档

文章目录 参考首先了解什么是postman那么后端如何用postman编写接口文档&#xff0c;并且让前端或者其他开发人员也一起同步协作呢&#xff1f;1. 注册登录postman2. 创建项目工作区3. 编写接口文档4. 添加协作人&#xff08;这一步也可以在创建工作区之初就操作&#xff09;5.…

怎么写一份好的接口文档?

编写一份优秀的接口文档会让软件开发中变得更加轻松&#xff0c;更有效率。这可是关键任务&#xff0c;写得好不仅可以帮助开发人员更好地理解和使用 API 接口&#xff0c;还可以提高整个团队的协作效率。 大家可以在线感受一下优秀的接口文档是怎样的&#xff1a;https://pets…

接口文档的使用

请求参数&#xff08;(GET方法就是Query参数&#xff0c;POST方法就是 Body参数) 在 axios中通过headers选项设置Headers请求头参数 在 axios中通过data选项设置Body请求体参数 在 axios中通过params选项设置Query参数 如果有 Query 参数&#xff0c;axios 会在内部把这个对象…

接口文档包含哪些内容?怎么才能写好接口文档?十年测试老司机来告诉你

目录 接口文档结构 参数说明 示例 错误码说明 语言基调通俗易懂 及时更新与维护 总结 那么我们该如何写好一份优秀的接口文档呢&#xff1f; 接口文档结构 首先我们要知道文档结构是什么样子的。接口文档应该有清晰明确的结构&#xff0c;以便开发人员能快速定位自己需…

详解接口文档的编写

正规的团队合作或者是项目对接&#xff0c;接口文档是非常重要的&#xff0c;一般接口文档都是通过开发人员写的。一个工整的文档显得是非重要。下面我总结下自己看到的优秀接口文档。 一、背景介绍 接口&#xff1a;API API&#xff08;Application Programming Interface&…

如何写好API接口文档

日常项目开发的过程中&#xff0c;接口文档是必不可少的。后端工程师与前端工程师之间需要接口文档来定义数据传输协议、系统对外暴露接口需要文档来说明、系统之间相互调用需要文档来记录接口协议等等。对于一个完整的项目&#xff0c;接口文档是至关重要的。那我们如何写好一…

什么是接口文档

一、什么是接口文档&#xff1f; 在项目开发中&#xff0c;web项目的前后端分离开发&#xff0c;APP开发&#xff0c;需要由前后端工程师共同定义接口&#xff0c;编写接口文档&#xff0c;之后大家都根据这个接口文档进行开发&#xff0c;到项目结束前都要一直维护。 二、为…