本文目录导读:

我来介绍一个基于OpenCV和Tesseract的车牌识别Python实现方案。
环境准备
# 安装必要的库 pip install opencv-python pip install pytesseract pip install numpy pip install matplotlib
车牌识别完整案例
import cv2
import numpy as np
import pytesseract
import re
from matplotlib import pyplot as plt
class LicensePlateRecognizer:
def __init__(self):
# 配置Tesseract路径(Windows用户需要)
# pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
pass
def load_image(self, image_path):
"""加载图像"""
img = cv2.imread(image_path)
if img is None:
raise ValueError("无法加载图像")
return img
def preprocess_image(self, img):
"""图像预处理"""
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊去噪
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 自适应阈值处理
adaptive_thresh = cv2.adaptiveThreshold(
blurred, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2
)
return adaptive_thresh
def find_license_plate_contour(self, processed_img, original_img):
"""查找车牌轮廓"""
# 形态学操作
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 3))
morph_img = cv2.morphologyEx(processed_img, cv2.MORPH_CLOSE, kernel)
# 查找轮廓
contours, _ = cv2.findContours(
morph_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# 筛选车牌候选区域
license_plate_candidates = []
for contour in contours:
# 计算轮廓面积
area = cv2.contourArea(contour)
if area < 1000: # 过滤小区域
continue
# 获取外接矩形
x, y, w, h = cv2.boundingRect(contour)
aspect_ratio = w / float(h)
# 车牌宽高比通常在2:1到5:1之间
if 2.0 < aspect_ratio < 5.0:
# 提取候选区域
license_plate = original_img[y:y+h, x:x+w]
license_plate_candidates.append({
'contour': contour,
'rect': (x, y, w, h),
'image': license_plate
})
return license_plate_candidates
def enhance_license_plate(self, roi):
"""增强车牌区域图像质量"""
# 转换为灰度
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
# 直方图均衡化
equalized = cv2.equalizeHist(gray)
# 二值化处理
_, binary = cv2.threshold(equalized, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 去噪
denoised = cv2.medianBlur(binary, 3)
return denoised
def recognize_characters(self, plate_img):
"""识别车牌字符"""
try:
# 增强图像
enhanced_plate = self.enhance_license_plate(plate_img)
# 使用Tesseract进行OCR识别
# 配置识别参数
config = '--psm 7 -c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
text = pytesseract.image_to_string(enhanced_plate, config=config)
# 清理识别结果
text = ''.join(text.split()).upper()
# 使用正则表达式提取有效的车牌号
license_pattern = r'[A-Z]{1,2}[A-Z0-9]{5,6}'
match = re.search(license_pattern, text)
if match:
return match.group()
return text
except Exception as e:
print(f"字符识别失败: {e}")
return ""
def visualize_results(self, original_img, candidates, recognized_plate):
"""可视化识别结果"""
# 复制原图
result_img = original_img.copy()
# 绘制所有候选区域
for candidate in candidates:
x, y, w, h = candidate['rect']
cv2.rectangle(result_img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 显示结果
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.imshow(cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB))
plt.title('原始图像')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB))
plt.title('检测结果')
plt.axis('off')
# 显示识别的车牌
if recognized_plate:
plt.subplot(1, 3, 3)
plt.text(0.5, 0.5, f"车牌号: {recognized_plate}",
fontsize=14, ha='center', va='center')
plt.title('识别结果')
plt.axis('off')
plt.tight_layout()
plt.show()
def recognize(self, image_path):
"""完成车牌识别主流程"""
try:
# 1. 加载图像
original_img = self.load_image(image_path)
# 2. 预处理
processed_img = self.preprocess_image(original_img)
# 3. 查找车牌区域
license_plate_candidates = self.find_license_plate_contour(
processed_img, original_img
)
if not license_plate_candidates:
print("未检测到车牌区域")
return None
# 4. 识别字符
best_plate = None
max_confidence = 0
for candidate in license_plate_candidates:
plate_img = candidate['image']
recognized_text = self.recognize_characters(plate_img)
if recognized_text:
# 简单的置信度评估(可以根据实际需求优化)
confidence = len(recognized_text)
if confidence > max_confidence:
max_confidence = confidence
best_plate = recognized_text
candidate['recognized'] = True
# 5. 可视化结果
self.visualize_results(original_img, license_plate_candidates, best_plate)
if best_plate:
print(f"识别到的车牌号: {best_plate}")
return best_plate
else:
print("无法识别车牌")
return None
except Exception as e:
print(f"车牌识别失败: {e}")
return None
# 使用示例
def main():
# 创建识别器实例
recognizer = LicensePlateRecognizer()
# 识别车牌(请替换为实际图像路径)
result = recognizer.recognize('car_license_plate.jpg')
if result:
print(f"成功识别车牌: {result}")
else:
print("车牌识别失败")
if __name__ == "__main__":
main()
使用深度学习的方法(更准确)
import cv2
import numpy as np
from tensorflow import keras
import matplotlib.pyplot as plt
class AdvancedLicensePlateRecognizer:
def __init__(self):
# 加载预训练的深度学习模型(这里需要你先训练或下载模型)
# self.model = keras.models.load_model('license_plate_model.h5')
pass
def detect_plate_deep_learning(self, image):
"""使用深度学习检测车牌(示例结构)"""
# 这里需要实现你的深度学习模型推理
# 可以使用YOLO、SSD等目标检测模型
pass
def recognize_characters_cnn(self, plate_img):
"""使用CNN识别字符(示例结构)"""
# 字符分割和识别
# 可以使用CNN+LSTM+CTC的网络结构
pass
# 简化的车牌字符分割与识别
def segment_characters(plate_img):
"""分割车牌字符"""
# 转换为灰度
gray = cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY)
# 二值化
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 筛选字符轮廓
char_contours = []
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
if h > 30 and w > 15: # 根据实际图像调整
char_contours.append((x, y, w, h))
# 按x坐标排序
char_contours = sorted(char_contours, key=lambda x: x[0])
# 提取字符图像
char_images = []
for x, y, w, h in char_contours:
char = binary[y:y+h, x:x+w]
# 调整为统一大小
char = cv2.resize(char, (28, 28))
char_images.append(char)
return char_images
快速测试脚本
import cv2
import sys
def quick_test(image_path):
"""快速测试车牌识别"""
recognizer = LicensePlateRecognizer()
result = recognizer.recognize(image_path)
if result:
print(f"车牌号: {result}")
else:
print("识别失败")
# 命令行使用
if __name__ == "__main__":
if len(sys.argv) > 1:
quick_test(sys.argv[1])
else:
print("请提供图像路径")
优化建议
1 提高准确率的方法
# 1. 图像增强
def enhance_plate_image(plate_img):
# 自适应直方图均衡化
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
enhanced = clahe.apply(plate_img)
return enhanced
# 2. 角度校正
def deskew_plate(plate_img):
# 检测倾斜角度并进行校正
coords = np.column_stack(np.where(plate_img > 0))
angle = cv2.minAreaRect(coords)[-1]
if angle < -45:
angle = 90 + angle
# 旋转校正
(h, w) = plate_img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(plate_img, M, (w, h))
return rotated
2 自定义训练模型
# 如果需要训练自己的OCR模型
def train_custom_ocr(training_data_path):
"""
训练自定义的OCR模型
可以使用TensorFlow或PyTorch框架
"""
# 实现你的训练逻辑
pass
使用说明
- 安装依赖:确保安装了OpenCV、Tesseract等必要库
- 准备图像:选择清晰的车牌图像
- 运行代码:调用
recognize()方法 - 查看结果:程序会显示原始图像、检测结果和识别出的车牌号
这个实现适用于大多数标准车牌识别场景,对于特殊场景(如角度大、光照不均等),建议使用深度学习模型提高准确率。