请给出一段完整代码,演示基于OpenCV的车牌识别
时间: 2024-04-06 12:30:14 浏览: 46
基于OpenCV的车牌号码识别的Python代码(可直接运行).zip
5星 · 资源好评率100%
好的,以下是一个基于OpenCV的车牌识别的Python示例代码:
``` python
import cv2
import numpy as np
# 车牌定位
def locate_plate(img):
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# 边缘检测
edges = cv2.Canny(blur, 100, 200)
# 膨胀操作
dilate_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
dilate = cv2.dilate(edges, dilate_kernel)
# 轮廓检测
contours, hierarchy = cv2.findContours(dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 筛选可能的车牌区域
plate_contours = []
for cnt in contours:
area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
aspect_ratio = float(w) / h
if area > 1000 and aspect_ratio > 2 and aspect_ratio < 5:
plate_contours.append(cnt)
# 绘制可能的车牌区域
plate_img = img.copy()
cv2.drawContours(plate_img, plate_contours, -1, (0, 255, 0), 2)
return plate_img, plate_contours
# 车牌字符分割
def segment_chars(img, plate_contours):
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 获取车牌区域的坐标范围
plate_rect = cv2.boundingRect(plate_contours[0])
# 裁剪出车牌区域
plate = thresh[plate_rect[1]:plate_rect[1] + plate_rect[3], plate_rect[0]:plate_rect[0] + plate_rect[2]]
# 垂直投影
vertical_sum = np.sum(plate, axis=0)
# 寻找字符分割点
index = []
for i in range(len(vertical_sum)):
if vertical_sum[i] > 0:
index.append(i)
index.append(plate.shape[1])
segments = []
for i in range(len(index) - 1):
x1 = index[i]
x2 = index[i + 1]
segment = plate[:, x1:x2]
segments.append(segment)
# 绘制字符分割线
plate_img = img.copy()
for i in index:
cv2.line(plate_img, (plate_rect[0] + i, plate_rect[1]), (plate_rect[0] + i, plate_rect[1] + plate_rect[3]), (0, 255, 0), 2)
return plate_img, segments
# 车牌字符识别
def recognize_chars(segments):
# 加载字符分类器
svm = cv2.ml.SVM_load('svm.xml')
# 字符识别
chars = []
for segment in segments:
# 调整大小
h, w = segment.shape
if h > 0 and w > 0:
if h > w:
scale = 32 / h
h = 32
w = int(w * scale)
else:
scale = 32 / w
w = 32
h = int(h * scale)
resized = cv2.resize(segment, (w, h), interpolation=cv2.INTER_AREA)
# 填充
pad_h = (64 - h) // 2
pad_w = (64 - w) // 2
padded = cv2.copyMakeBorder(resized, pad_h, pad_h, pad_w, pad_w, cv2.BORDER_CONSTANT, value=0)
# 特征提取
feature = np.reshape(padded, (1, 64 * 64))
# 预测
response = svm.predict(feature.astype(np.float32))[1]
char = chr(response + ord('A'))
chars.append(char)
return chars
# 主函数
if __name__ == '__main__':
# 读取图像
img = cv2.imread('plate.jpg')
# 车牌定位
plate_img, plate_contours = locate_plate(img)
# 车牌字符分割
plate_img, segments = segment_chars(img, plate_contours)
# 车牌字符识别
chars = recognize_chars(segments)
# 显示结果
print(''.join(chars))
cv2.imshow('Plate', plate_img)
cv2.waitKey(0)
```
需要注意的是,以上代码仅供参考,实际应用中还需要根据具体情况进行适当调整和优化。
阅读全文