Python教程-使用Python进行车牌识别
在以下教程中,我们将了解如何使用Python编程语言识别车牌号码。我们将利用OpenCV来识别车牌,并使用Python的pytesseract库来从车牌中提取字符和数字。通过本教程,我们将构建一个Python程序,自动识别车牌号码。
理解自动车牌识别系统
自动车牌识别系统有各种各样的形状和大小:
- 在受控光照条件下执行的车牌识别系统可以使用基本的图像处理技术来识别车牌。
- 更高级的车牌识别系统使用专门的目标检测器,如HOG + Linear SVM、SSD、YOLO和Faster R-CNN来定位图像中的车牌。
- 最先进的车牌识别软件使用循环神经网络(RNN)和长短时记忆网络(LSTM)来帮助更好地进行车牌上的光学字符识别(OCR)。
- 更高级的车牌识别系统使用专门的神经网络架构来对图像进行预处理和清理,然后进行OCR,从而提高车牌识别的准确性。
使自动车牌识别更加复杂的因素可能需要实时操作。
例如,让我们考虑一个安装在收费公路上的车牌识别系统。它必须能够检测每辆经过的车辆的车牌,对车牌上的字符进行OCR,并将这些数据存储在数据库中,以便向车主发送收费账单。
一些复杂因素使车牌识别非常具有挑战性,包括寻找可用于训练自定义车牌识别模型的数据集。用于训练最先进模型的大型、健壮的车牌识别数据集通常受到保护,几乎不会公开发布:
- 这些数据集包含与车辆、驾驶员和位置相关的敏感身份信息。
- 车牌数据集的筛选工作耗时且需要大量员工时间进行解释。
- 与地方和联邦政府签订的车牌识别合同通常非常具有竞争力。通常情况下,有价值的不是已训练的模型,而是某个公司已经筛选出来的数据集。
- 出于相同原因,我们会看到车牌识别行业被收购,不是因为其车牌识别系统,而是因为数据集本身。
项目的先决条件
我们将使用Python的OpenCV库。它是一个用于机器学习的开源库,并提供了计算机视觉的通用基础设施。我们还将使用Pytesseract来完成这个项目。Pytesseract是一个Tesseract-OCR引擎,用于读取图像中的文本和提取可用的详细信息。
安装
我们可以使用pip安装OpenCV库,如下所示:
命令:
$ pip install opencv-python
同样的步骤也将用于安装Pytesseract引擎。其命令如下所示:
命令:
$ pip install pytesseract
OpenCV的特点
在以下Python项目中,我们将使用OpenCV的以下特点来识别输入图像中的车牌:
- 高斯模糊: 在这里,我们将使用高斯核来对图像进行平滑处理。这种技术对于去除高斯噪声非常有效。OpenCV提供了一个名为GaussianBlur()的函数来执行这项任务。
形态变换:这些操作是基于图像形状的操作,通常在二进制图像上执行。基本的形态操作包括开运算、闭运算、腐蚀、膨胀等。OpenCV提供了以下函数:
- cv2.erode()
- cv2.dilate()
- cv2.morphologyEx()
- Sobel: 在这里,我们将计算图像的导数。这对于计算机视觉任务非常重要。借助这些导数,我们可以计算梯度,梯度的高变化意味着图像中有显著的变化。OpenCV提供了Sobel()函数来计算Sobel算子。
- 轮廓: 轮廓是由相同强度的连续点组成的曲线。这些曲线对于对象识别非常有用。OpenCV提供了findContours()函数来执行此功能。
理解Python代码
既然我们已经涵盖了项目的理论部分,让我们进入编码部分。为了更好地理解和清晰,我们已将项目的整个源代码分为不同的步骤。
步骤1:导入所需模块
首先,我们需要导入OpenCV和pytesseract,以及matplotlib、glob和OS。
文件: anpr.py
# importing the required modules
import pytesseract
import matplotlib.pyplot as plt
import cv2
import glob
import os
注意: 文件的名称必须与车牌图像中的确切编号相同。例如,如果车牌号是"FTY348U",那么图像文件的名称将是"FTY348U.jpg"。
步骤2:使用Tesseract引擎对车牌执行OCR
在以下步骤中,我们需要使用Tesseract引擎对车牌执行光学字符识别(OCR)。下面是代码片段。
文件: anpr.py
# specifying the path to the number plate images folder as shown below
file_path = os.getcwd() + "/license_plates/**/*.jpg"
NP_list = []
predicted_NP = []
for file_path in glob.glob(file_path, recursive = True):
NP_file = file_path.split("/")[-1]
number_plate, _ = os.path.splitext(NP_file)
'''
Here we will append the actual number plate to a list
'''
NP_list.append(number_plate)
'''
Reading each number plate image file using openCV
'''
NP_img = cv2.imread(file_path)
'''
We will then pass each number plate image file
to the Tesseract OCR engine utilizing the Python library
wrapper for it. We get back predicted_res for
number plate. We append the predicted_res in a
list and compare it with the original number plate
'''
predicted_res = pytesseract.image_to_string(NP_img, lang ='eng',
config ='--oem 3 --psm 6 -c tessedit_char_whitelist = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
filter_predicted_res = "".join(predicted_res.split()).replace(":", "").replace("-", "")
predicted_NP.append(filter_predicted_res)
解释:
在上面的代码片段中,我们使用OS模块指定了车牌图像文件的路径。我们还定义了两个空列表NP_list和predicted_NP。然后,我们使用append()函数将实际车牌添加到列表中。接下来,我们使用OpenCV模块读取每个车牌图像文件并将其存储在NP_img变量中。然后,我们使用Python库包装器将每个车牌图像文件传递给Tesseract OCR引擎。我们得到车牌的predicted_res,并将其追加到列表中,然后与原始车牌进行比较。
现在,由于我们已经预测了车牌,但我们不知道预测的结果。因此,为了查看数据和预测,我们将进行一些可视化,如下所示。我们还将估计没有使用任何核心函数的预测准确性。
文件: anpr.py
print("Original Number Plate", "\t", "Predicted Number Plate", "\t", "Accuracy")
print("--------------------", "\t", "-----------------------", "\t", "--------")
def estimate_predicted_accuracy(ori_list, pre_list):
for ori_plate, pre_plate in zip(ori_list, pre_list):
acc = "0 %"
number_matches = 0
if ori_plate == pre_plate:
acc = "100 %"
else:
if len(ori_plate) == len(pre_plate):
for o, p in zip(ori_plate, pre_plate):
if o == p:
number_matches += 1
acc = str(round((number_matches / len(ori_plate)), 2) * 100)
acc += "%"
print(ori_plate, "\t", pre_plate, "\t", acc)
estimate_predicted_accuracy(NP_list, predicted_NP)
输出:
Original Number Plate Predicted Number Plate Accuracy
-------------------- ----------------------- --------
DL3CAM0857 DL3CAM0857 100 %
MD06NYW MDOGNNS 40 %
TN21TC706 TN21TC706 100 %
TN63DB5481 TN63DB5481 100 %
UP14DR4070 UP14DR4070 100 %
W5KHN WSKHN 80 %
解释:
在上面的代码片段中,我们定义了一个函数来计算预测准确性。在函数内部,我们使用for循环来遍历原始车牌列表和预测的车牌列表,然后检查它们是否匹配。我们还根据数字的长度来检查准确性,以获得更好和适当的结果。
我们可以看到,Tesseract OCR引擎通常以100%的准确性预测所有车牌。对于预测不正确的车牌,Tesseract OCR引擎的准确性较低,我们将对这些车牌文件应用图像处理技术,然后再次将它们传递给Tesseract OCR。通过应用图像处理技术,我们可以提高Tesseract引擎对不正确预测的车牌的准确性。
步骤3:图像处理技术
让我们考虑以下代码片段,以了解图像处理技术。
文件: anpr.py
import matplotlib.image as mpimg
for img in os.listdir("D://Python//License_Plate"):
test_NP = mpimg.imread("W5KHN.jpg")
plt.imshow(test_NP)
plt.axis('off')
plt.title('W5KHN license plate')
plt.show()
输出:
解释:
在上面的代码片段中,我们从指定文件夹中导入image模块并使用for循环提取图像。然后,我们使用imread()函数读取提取的图像。接下来,我们使用matplotlib库的plot模块来显示图像给用户。
- 图像调整大小: 我们可以利用“resize”工具,将图像文件在水平和垂直方向都放大2倍。
- 转换为灰度图像: 然后,我们可以将调整大小后的图像文件转换为灰度图像,以优化检测并大幅减少图像中可用颜色的数量,从而使我们能够更容易地检测车牌号码。
- 去噪: 我们可以使用高斯模糊技术来去噪图像。这会使图像的边缘更加清晰和平滑,从而使字符更易读取。
让我们考虑以下示例以更好地理解这一过程。
文件:anpr.py
# image resizing
resize_test_NP = cv2.resize(
test_NP, None, fx = 2, fy = 2,
interpolation = cv2.INTER_CUBIC)
# converting image to grayscale
grayscale_resize_test_NP = cv2.cvtColor(
resize_test_NP, cv2.COLOR_BGR2GRAY)
# denoising the image
gaussian_blur_NP = cv2.GaussianBlur(
grayscale_resize_test_NP, (5, 5), 0)
解释:
在上述代码片段中,我们使用了OpenCV模块的一些工具来调整图像大小,将其转换为灰度图像并去噪。
完成上述步骤后,我们可以将经过转换的车牌文件传递给Tesseract OCR引擎,然后查看预测结果。
同样的操作可以在以下代码片段中观察到。
文件:anpy.py
new_pre_res_W5KHN = pytesseract.image_to_string(gaussian_blur_NP, lang ='eng')
filter_new_pre_res_W5KHN = "".join(new_pre_res_W5KHN.split()).replace(":", "").replace("-", "")
print(filter_new_pre_res_W5KHN)
输出:
W5KHN
解释:
在上述代码片段中,我们将最终处理过的图像传递给Tesseract OCR引擎,以提取车牌号码中的数字。
类似地,我们可以对所有其他车牌号码执行此图像处理操作,尽管准确度不一定达到100%。因此,车牌识别模型已经准备就绪。