基于opencv的车牌识别用python
时间: 2023-05-24 16:04:34 浏览: 275
python opencv 车牌识别 PlateRecogntionpython_PlateRecogntion.zip
5星 · 资源好评率100%
实现车牌识别的Python程序通常包括以下步骤:
1. 导入库和数据集:导入OpenCV、numpy、skimage、matplotlib、imutils等库,并加载训练好的机器学习模型和数据集。
2. 读取车辆图像:读取车辆图像文件,并把图像转换成二值图像。
3. 车牌定位:通过车牌定位算法(如Sobel算子、Canny边缘检测、形态学运算等方法)对车身图像进行处理,找出其中的车牌区域。
4. 车牌字符分割:根据车牌镜像的特性,通过垂直方向的投影法、水平方向的投影法等方法,把车牌区域切分成若干个字符。
5. 字符识别:基于机器学习算法(如支持向量机、K最近邻等算法),对每个字符进行识别,识别结果就是车牌号码。
以下是一个简单的基于OpenCV的车牌识别Python程序的代码示例:
``` python
import cv2
import imutils
import numpy as np
import argparse
# 定义车牌定位函数
def locate_license_plate(img):
# 图像的预处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 100, 200)
# 查找轮廓
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
# 定义最大的轮廓面积
max_area = 0
max_cnt = None
# 循环遍历所有轮廓
for cnt in cnts:
area = cv2.contourArea(cnt)
if area > max_area:
max_area = area
max_cnt = cnt
# 定义车牌区域的边界框
x, y, w, h = cv2.boundingRect(max_cnt)
plate_img = img[y:y+h, x:x+w]
return plate_img
# 定义字符分割函数
def segment_license_plate(plate_img):
# 图像的预处理:灰度化、二值化、去除噪声
gray = cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opened = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
# 执行水平方向的投影
hist = cv2.reduce(opened, 1, cv2.REDUCE_AVG)
th = 0
H, W = plate_img.shape[:2]
points = []
result = plate_img.copy()
for y in range(H):
if hist[y] <= th:
y0 = y
while y < H and hist[y] <= th:
y += 1
y1 = y
if y1-y0 > 10:
cv2.line(result, (0, y0), (W-1, y0), (0, 255, 0), 2)
cv2.line(result, (0, y1-1), (W-1, y1-1), (0, 255, 0), 2)
points.append((y0, y1))
# 执行字符分割
segments = []
for i in range(len(points)):
y0, y1 = points[i]
roi = opened[y0:y1, 0:W]
column_hists = cv2.reduce(roi, 0, cv2.REDUCE_AVG)
th2 = 0
X = int(W*0.1)
while X < W:
if column_hists[X] <= th2:
x0 = X
while X < W and column_hists[X] <= th2:
X += 1
x1 = X
if x1-x0 >= 6:
segments.append((x0, y0, x1, y1))
X += 1
return segments
# 定义字符识别函数
def recognize_license_plate(plate_img, segments):
# 导入机器学习模型
svm = cv2.ml.SVM_create()
svm.load('svm.xml')
# 定义检测结果
result = ''
# 循环遍历每个字符
for i, segment in enumerate(segments):
x0, y0, x1, y1 = segment
roi = plate_img[y0:y1, x0:x1]
roi = cv2.resize(roi, (20, 20))
hog_desc = hog.compute(roi).flatten()
pred = svm.predict(hog_desc)
result += str(int(pred[1][0]))
return result
# 测试程序
if __name__ == '__main__':
# 解析命令行参数
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--image', required=True, help='path to input image')
args = parser.parse_args()
# 读取车辆图像
img = cv2.imread(args.image)
# 定位车牌区域
plate_img = locate_license_plate(img)
# 把车牌区域可视化
cv2.imshow('Plate', plate_img)
# 分割字符
segments = segment_license_plate(plate_img)
# 对每个字符执行识别
result = recognize_license_plate(plate_img, segments)
# 输出识别结果
print('License Plate:', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
阅读全文