该项目基于Python和OpenCV实现车牌识别,含图像预处理、定位、分割及模板匹配等步骤。先通过灰度转换、噪声过滤等预处理图像,再经形态学操作定位车牌,分割字符后按位置排序,最后用模板匹配识别字符,可输出车牌号码,在智能交通等领域实用。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜


一键运行
该项目旨在通过Python编程语言结合OpenCV库,实现一个完整的车牌识别系统。项目将演示从图像预处理到车牌定位、分割,以及最终通过模板匹配技术实现车牌号码的自动识别。这一技术在智能交通、车辆管理和监控等领域具有显著的实际应用价值,能够显著提升交通管理的效率和准确性。

OpenCV应用:本项目采用OpenCV这一强大的图像处理和计算机视觉库,实现高效的图像分析和处理功能。OpenCV的集成使得车牌识别过程更加精确和快速。
Python编程:选择Python作为开发语言,得益于其简洁的语法和丰富的库支持,使得开发过程更加高效。Python的易学性和广泛的社区资源为项目提供了强大的后盾。
立即学习“Python免费学习笔记(深入)”;
高级图像处理:项目中运用了多种高级图像处理技术,包括但不限于灰度转换以增强图像对比度、噪声过滤以净化图像质量、边缘检测以识别图像轮廓、形态学操作以改善图像结构,以及透视变换以校正图像视角。
创新算法集成:通过结合多种图像处理技术,项目开发了一套创新的算法流程,有效提升了车牌识别的准确性和鲁棒性,特别是在复杂环境下的表现。
实用性与灵活性:项目不仅注重技术实现,还强调算法的实用性和灵活性,确保能够适应不同的应用场景和需求,如智能交通监控、车辆自动登记等。

OpenCV(Open Source Computer Vision Library)是一个功能强大的开源计算机视觉库,广泛应用于图像处理和计算机视觉任务。它提供了丰富的算法和功能,包括但不限于图像处理、视频分析、物体识别、机器学习等 。
技术原理方面,OpenCV主要基于以下几个方面:

在实际应用中,OpenCV可以用于人脸检测、物体识别、图像拼接、视频分析等多种场景。例如,使用Haar Cascade算法可以检测图像中的人脸位置,物体识别可以通过深度学习算法实现,图像拼接可以通过Stitcher类将多个图像拼接成一个大视场图像 。

import cv2from matplotlib import pyplot as pltimport osimport numpy as npfrom PIL import ImageFont, ImageDraw, Image
cv2.GaussianBlur参数说明:
def plt_show0(img):
b,g,r = cv2.split(img)
img = cv2.merge([r, g, b])
plt.imshow(img)
plt.show()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运行下面的cell,显示处理的原始图片
from IPython.display import Image# 显示图片Image(filename='work/1.jpeg')
<IPython.core.display.Image object>
origin_image = cv2.imread('work/1.jpeg')# 高斯去噪image = origin_image.copy()
gray_image = gray_guss(image)
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)<Figure size 640x480 with 1 Axes>
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10)) image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX,iterations = 1)# 显示灰度图像plt_show(image)
<Figure size 640x480 with 1 Axes>
# 腐蚀(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)
<Figure size 640x480 with 1 Axes>
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)) and (weight < (height * 4.5)):
image = origin_image[y:y + height, x:x + weight]
plt_show(image)<Figure size 640x480 with 1 Axes>
运行下面的cell,对车牌字符分割
# 图像去噪灰度处理gray_image = gray_guss(image) ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU) # 阈值化plt_show(image)
<Figure size 640x480 with 1 Axes>
#膨胀操作kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4)) image = cv2.dilate(image, kernel) plt_show(image)
<Figure size 640x480 with 1 Axes>
运行下面的cell,对车牌号排序
# 查找轮廓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 = 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] * 5.5)) and (word[2] > 10):
i = i+1
if word[2] < 15:
splite_image = image[word[1]:word[1] + word[3], word[0]-word[2]:word[0] + word[2]*2] else:
splite_image = image[word[1]:word[1] + word[3], word[0]:word[0] + word[2]]
word_images.append(splite_image)for i,j in enumerate(word_images):
plt.subplot(1,7,i+1)
plt.imshow(word_images[i],cmap='gray')
plt.show()<Figure size 640x480 with 7 Axes>
解压模版文件,文件路径在/home/aistudio/work/Template.zip,运行完之后可以注释下面的cell
%%capture !unzip /home/aistudio/work/Template.zip -d /home/aistudio/work
# 准备模板(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('/home/aistudio/work/Template/'+ 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('/home/aistudio/work/Template/'+ 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('/home/aistudio/work/Template/'+ template[i])
eng_num_words_list.append(word) return eng_num_words_list
eng_num_words_list = get_eng_num_words_list()# 获得英文和数字模板列表(匹配车牌后面的字符)def get_eng_num_words_list():
eng_num_words_list = [] for i in range(0,34):
word = read_directory('/home/aistudio/work/Template/'+ 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) continue
if 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) continue
else:
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) continue
return results
word_images_ = word_images.copy()# 调用函数获得结果result = template_matching(word_images_)print(result)print( "".join(result))['渝', 'B', 'F', 'U', '8', '7', '1'] 渝BFU871
import cv2from matplotlib import pyplot as pltimport osimport numpy as npfrom PIL import ImageFont, ImageDraw, Image height,weight = origin_image.shape[0:2] 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 = "/home/aistudio/work/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)
['渝', 'B', 'F', 'U', '8', '7', '1'] 渝BFU871
<Figure size 640x480 with 1 Axes>
以上就是基于Opencv的Python车牌识别实战【一键运行】的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号