前面4篇博客介绍了OpenCV图像处理的基础知识,本篇博客利用前4篇的知识完成一个小项目——车牌号码识别。该篇博客的代码可以满足小区门禁车牌号的识别。本篇博客是前4篇博客知识的一个综合运用。感觉学会了这个可以实现一系列的图像识别任务。。。毕竟好多技巧都是共通的
首先要感谢 大佬的博客 ,在它的基础上完成了自己的识别任务。

简洁易懂的车牌号识别Python实现“超详解”(含代码)

  • 1、整体思路
  • 2、代码详解
    • 2.1提取车牌位置
    • 2.2车牌字符的分割
    • 2.3模板匹配识别字符
  • 3、总结
  • 4、参考

1、整体思路

首先附上本次识别的图片:(图片是我在百度上找的)

基于OpenCV车牌号识别总体分为四个步骤
1)提取车牌位置,将车牌从图中分割出来;
2)车牌字符的分割;
3)通过模版匹配识别字符;
4)将结果绘制在图片上显示出来。
与深度学习相比,传统图像处理的识别有好处又有坏处
好处:不需要大量的数据集训练模型,通过形态学、边缘检测等操作提取特征
坏处:基于传统图像处理的图像识别代码的泛化性较低,当图像的角度,光照不同时,识别效果有时会不尽人意。

2、代码详解

为了方便观察每一步图片的变化,本次代码在Jupyter Notebook上编写,全部代码以上传(可直接运行)。
本次项目中会多次使用到图片显示和图片去噪灰度处理,所以首先定义了显示函数高斯滤波灰度处理函数,方便后面的调用:

# 导入所需模块
import cv2
from matplotlib import pyplot as plt
import os
import numpy as np
# plt显示彩色图片
def plt_show0(img):
#cv2与plt的图像通道不同:cv2为[b,g,r];plt为[r, g, b]b,g,r = cv2.split(img)img = cv2.merge([r, g, b])plt.imshow(img)plt.show()# plt显示灰度图片
def plt_show(img):plt.imshow(img,cmap='gray')plt.show()# 图像去噪灰度处理
def gray_guss(image):image = cv2.GaussianBlur(image, (3, 3), 0)gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)return gray_image

2.1提取车牌位置

对图片进行阈值化处理、边缘检测及形态学操作,根据得到的轮廓特征识别车牌的具体位置,将车牌分割出来。直接上代码及代码详解:

# 读取待检测图片
origin_image = cv2.imread('./image/car.jpg')
# 复制一张图片,在复制图上进行图像操作,保留原图
image = origin_image.copy()
# 图像去噪灰度处理
gray_image = gray_guss(image)
# x方向上的边缘检测(增强边缘信息)
Sobel_x = cv2.Sobel(gray_image, cv2.CV_16S, 1, 0)
absX = cv2.convertScaleAbs(Sobel_x)
image = absX# 图像阈值化操作——获得二值化图
ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU)
# 显示灰度图像
plt_show(image)
# 形态学(从图像中提取对表达和描绘区域形状有意义的图像分量)——闭操作
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX,iterations = 1)
# 显示灰度图像
plt_show(image)

二值化图以及闭操作(闭合细小的连接,抑制暗细节)的结果如图所示:

# 腐蚀(erode)和膨胀(dilate)
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))
#x方向进行闭操作(抑制暗细节)
image = cv2.dilate(image, kernelX)
image = cv2.erode(image, kernelX)
#y方向的开操作
image = cv2.erode(image, kernelY)
image = cv2.dilate(image, kernelY)
# 中值滤波(去噪)
image = cv2.medianBlur(image, 21)
# 显示灰度图像
plt_show(image)
# 获得轮廓
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for item in contours:rect = cv2.boundingRect(item)x = rect[0]y = rect[1]weight = rect[2]height = rect[3]# 根据轮廓的形状特点,确定车牌的轮廓位置并截取图像if (weight > (height * 3.5)) and (weight < (height * 4)):image = origin_image[y:y + height, x:x + weight]plt_show0(image)

2.2车牌字符的分割

#车牌字符分割
# 图像去噪灰度处理
gray_image = gray_guss(image)
# 图像阈值化操作——获得二值化图
ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)
plt_show(image)#膨胀操作,使“苏”字膨胀为一个近似的整体,为分割做准备
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
image = cv2.dilate(image, kernel)
plt_show(image)

# 查找轮廓
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
words = []
word_images = []
#对所有轮廓逐一操作
for item in contours:word = []rect = cv2.boundingRect(item)x = rect[0]y = rect[1]weight = rect[2]height = rect[3]word.append(x)word.append(y)word.append(weight)word.append(height)words.append(word)
# 排序,车牌号有顺序。words是一个嵌套列表
words = sorted(words,key=lambda s:s[0],reverse=False)
i = 0
#word中存放轮廓的起始点和宽高
for word in words:# 筛选字符的轮廓if (word[3] > (word[2] * 1.5)) and (word[3] < (word[2] * 3.5)) and (word[2] > 25):i = i+1splite_image = image[word[1]:word[1] + word[3], word[0]:word[0] + word[2]]word_images.append(splite_image)print(i)
print(words)for i,j in enumerate(word_images):  plt.subplot(1,7,i+1)plt.imshow(word_images[i],cmap='gray')
plt.show()

2.3模板匹配识别字符

模板匹配是一个机械性的流程,所以把机械性的操作设定为函数。

#模版匹配
# 准备模板(template[0-9]为数字模板;)
template = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','藏','川','鄂','甘','赣','贵','桂','黑','沪','吉','冀','津','晋','京','辽','鲁','蒙','闽','宁','青','琼','陕','苏','皖','湘','新','渝','豫','粤','云','浙']# 读取一个文件夹下的所有图片,输入参数是文件名,返回模板文件地址列表
def read_directory(directory_name):referImg_list = []for filename in os.listdir(directory_name):referImg_list.append(directory_name + "/" + filename)return referImg_list# 获得中文模板列表(只匹配车牌的第一个字符)
def get_chinese_words_list():chinese_words_list = []for i in range(34,64):#将模板存放在字典中c_word = read_directory('./refer1/'+ template[i])chinese_words_list.append(c_word)return chinese_words_list
chinese_words_list = get_chinese_words_list()# 获得英文模板列表(只匹配车牌的第二个字符)
def get_eng_words_list():eng_words_list = []for i in range(10,34):e_word = read_directory('./refer1/'+ template[i])eng_words_list.append(e_word)return eng_words_list
eng_words_list = get_eng_words_list()# 获得英文和数字模板列表(匹配车牌后面的字符)
def get_eng_num_words_list():eng_num_words_list = []for i in range(0,34):word = read_directory('./refer1/'+ template[i])eng_num_words_list.append(word)return eng_num_words_list
eng_num_words_list = get_eng_num_words_list()# 读取一个模板地址与图片进行匹配,返回得分
def template_score(template,image):#将模板进行格式转换template_img=cv2.imdecode(np.fromfile(template,dtype=np.uint8),1)template_img = cv2.cvtColor(template_img, cv2.COLOR_RGB2GRAY)#模板图像阈值化处理——获得黑白图ret, template_img = cv2.threshold(template_img, 0, 255, cv2.THRESH_OTSU)
#     height, width = template_img.shape
#     image_ = image.copy()
#     image_ = cv2.resize(image_, (width, height))image_ = image.copy()#获得待检测图片的尺寸height, width = image_.shape# 将模板resize至与图像一样大小template_img = cv2.resize(template_img, (width, height))# 模板匹配,返回匹配得分result = cv2.matchTemplate(image_, template_img, cv2.TM_CCOEFF)return result[0][0]# 对分割得到的字符逐一匹配
def template_matching(word_images):results = []for index,word_image in enumerate(word_images):if index==0:best_score = []for chinese_words in chinese_words_list:score = []for chinese_word in chinese_words:result = template_score(chinese_word,word_image)score.append(result)best_score.append(max(score))i = best_score.index(max(best_score))# print(template[34+i])r = template[34+i]results.append(r)continueif index==1:best_score = []for eng_word_list in eng_words_list:score = []for eng_word in eng_word_list:result = template_score(eng_word,word_image)score.append(result)best_score.append(max(score))i = best_score.index(max(best_score))# print(template[10+i])r = template[10+i]results.append(r)continueelse:best_score = []for eng_num_word_list in eng_num_words_list:score = []for eng_num_word in eng_num_word_list:result = template_score(eng_num_word,word_image)score.append(result)best_score.append(max(score))i = best_score.index(max(best_score))# print(template[i])r = template[i]results.append(r)continuereturn resultsword_images_ = word_images.copy()
# 调用函数获得结果
result = template_matching(word_images_)
print(result)
# "".join(result)函数将列表转换为拼接好的字符串,方便结果显示
print( "".join(result))
Output:
['苏', 'E', '0', '5', 'E', 'V', '8']
苏E05EV8

最后,利用PIL库将结果绘制在原图上,获得的最终输出图片如下:

from PIL import ImageFont, ImageDraw, Imageheight,weight = origin_image.shape[0:2]
print(height)
print(weight)image_1 = origin_image.copy()
cv2.rectangle(image_1, (int(0.2*weight), int(0.75*height)), (int(weight*0.9), int(height*0.95)), (0, 255, 0), 5)#设置需要显示的字体
fontpath = "font/simsun.ttc"
font = ImageFont.truetype(fontpath,64)
img_pil = Image.fromarray(image_1)
draw = ImageDraw.Draw(img_pil)
#绘制文字信息
draw.text((int(0.2*weight)+25, int(0.75*height)),  "".join(result), font = font, fill = (255, 255, 0))
bk_img = np.array(img_pil)
print(result)
print( "".join(result))
plt_show0(bk_img)


大功告成!!!!!

3、总结

(一) 、OpenCV的车牌号码识别一共分为四步走:
1–提取车牌位置,将车牌从图中分割出来;
2–车牌字符的分割;
3–通过模版匹配识别字符;
4–将结果绘制在图片上显示出来。
(二)、图像处理的识别泛化性较低,对图片的角度光照有要求,所以要理解图像处理每一步的作用,根据自己图像的特点调整参数,更改操作顺序等等,以达到最好的效果。
(三)、车牌号识别的模板连接如下,需要的可以下载,有了模板就可以识别自己的图片了
链接:https://pan.baidu.com/s/1QBjy7c0klv_PBUwJjA8ynA
提取码:v53d
(四)、完整代码已上传SCDN点击查看

4、参考

http://zengqiang.club/blog/34

【OpenCV实战】简洁易懂的车牌号识别Python+OpenCV实现“超详解”(含代码)相关推荐

  1. 用python写一个车牌号识别系统

    写车牌号识别系统需要用到计算机视觉技术,具体的实现方法如下: 图像预处理:对图像进行预处理,包括灰度化.二值化.边缘检测等,以得到图像中车牌的区域. 区域分割:对图像进行分割,得到车牌区域. 文字识别 ...

  2. Android扫车牌号识别技术SDK

    Android扫车牌号识别技术SDK Android扫车牌号识别技术SDK描述 Android扫车牌号识别技术SDK是我公司开发的基于移动平台的车牌识别软件开发包,支持android.iOS等多种主流 ...

  3. 【机器学习】 - 作业4: 基于K-近邻的车牌号识别

    课程链接: 清华大学驭风计划 代码仓库:Victor94-king/MachineLearning: MachineLearning basic introduction (github.com) 驭 ...

  4. python手写汉字识别_中文简历表格提取,手写汉字识别(Python+OpenCV)

    原标题:中文简历表格提取,手写汉字识别(Python+OpenCV) 所有代码获取: 简历 网上对表格框的提取的相关资料较少,尤其是Python+OpenCV的实现方面. 整体流程 如今OpenCV官 ...

  5. 数字图像处理二维码识别 python+opencv实现二维码实时识别

    数字图像处理二维码识别 python+opencv实现二维码实时识别 特点: (1)可以实现普通二维码,条形码: (2)解决了opencv输出中文乱码的问题 (3)增加网页自动跳转功能 (4)实现二维 ...

  6. Keras深度学习实战(4)——深度学习中常用激活函数和损失函数详解

    Keras深度学习实战(4)--深度学习中常用激活函数和损失函数详解 常用激活函数 Sigmoid 激活函数 Tanh 激活函数 ReLU 激活函数 线性激活函数 Softmax 激活函数 损失函数 ...

  7. Gavin老师Transformer直播课感悟 - Rasa项目实战之电商零售智能业务对话机器人ResponseSelector使用详解与Debugging演示(八十八)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之电商零售智能业务对话机器人系统如何使用Rasa框架提供的ResponseSelector组件处理常见问题和用户闲聊内容的过程,以及如何 ...

  8. python 自动化-Python API 自动化实战详解(纯代码)

    主要讲如何在公司利用Python 搞API自动化. 1.分层设计思路 dataPool :数据池层,里面有我们需要的各种数据,包括一些公共数据等 config :基础配置 tools : 工具层 co ...

  9. 手机摄影中多摄融合理论详解与代码实战

    转载AI Studio项目链接https://aistudio.baidu.com/aistudio/projectdetail/3465839 手机摄影中多摄融合理论详解与代码实战 前言   从20 ...

  10. 史上最易懂——ReactNative分组列表SectionList使用详情及示例详解

    React Native系列 <逻辑性最强的React Native环境搭建与调试> <ReactNative开发工具有这一篇足矣> <解决React Native un ...

最新文章

  1. Java图形化界面设计——容器(JFrame)
  2. Django1.6踩到的坑
  3. 初识Activiti
  4. P2237 [USACO14FEB]自动完成Auto-complete
  5. R语言第八讲续 评估模型之自助法分析案例
  6. cuisineroyale服务器所在位置,cuisine royale进不去怎么办?原因及解决办法分享
  7. html xsl xml文件,用XSL显示XML文件看起来像HTML
  8. 使用 ConnectionStringBuilder 对象创建精确连接字符串
  9. 1.2_配置Python基本环境
  10. Oracle之自定义函数
  11. ARP协议-路由交换原理5-【HCNA笔记】
  12. win7更新_WIN7操作系统无法更新IE11的解决办法
  13. 使用Directshow + LAVFilter做一个万能格式的多媒体播放器
  14. metasploit、msfvenom生成木马入侵电脑及手机
  15. mysql存储图片特征向量_图像特征提取之(一)HOG特征
  16. GitLab之不允许用户注册-yellowcong
  17. uc_pass.php,discuz 论坛UCenter无法登录,闪退的终极8种解决办法
  18. 编译原理|LL(1)语法分析实验
  19. yii2 之图片上传插件fileinput使用说明
  20. 年轻人,你的目标不该是成为斜杠青年

热门文章

  1. 在Ubuntu 16.04 64bit上安装谷歌地球Google Earth免费版
  2. 计算机应用基础2016,2016年最新统考计算机应用基础试题及答案
  3. Linux网络操作系统及应用教程( 项目式)项目一
  4. 在线图片托管服务imgur
  5. 无线通信设备安装工程概预算编制_祁东设备安装工程施工承包-设计安装_天霖工程...
  6. 苹果手机Apple ID 忘记密码 ,频繁跳出登录iCloud如何关闭
  7. Android 高德地图自定义InfoWindow
  8. 【Qt】绘制CIE色度图
  9. 南京大学计算机学院英才计划,2020年“英才计划”工作实施方案
  10. Android桌面壁纸