1. 简介
车牌识别(Vehicle License Plate Recognition,VLPR) 是从一张或一系列数字图片中自动定位车牌区域并提取车牌信息的图像识别技术。
生活中应用的自动车牌检测系统往往包括三个部分:
1. 车辆检测
2. 图像采集
3. 车牌识别
车牌识别以数字图像处理、模式识别、计算机视觉等技术为基础,是现代智能交通系统的重要组成部分,广泛应用于日常生活中,如停车场收费管理,车辆出入管理,自动放行,交通流量 控制指标测量,车辆定位,汽车防盗,高速公路超速自动化监管、闯红灯电子警察、 公路收费站等。
2. 发展历史
车牌识别的概念最早在 1976 年由英国的公安科学发展处(Police Scientific Development Branch)提出,它的第一个实验室原型诞生于 1979 年,同年,第一相关行业生产标准在英国沃金厄姆颁发。车牌识别早期的试验系统部署在英国最长 的编号公路 A1 公路和达特福德隧道,然而由于硬件设备价格昂贵和处理器计算能 力有限,直到上世纪 90 年代 VLPR 才开始快速发展,许多复杂的算法得以应用, 程序处理的对象也由黑白图片、灰度图片转变为彩色图片和视频,车牌识别率和识 别速度均得到显著提高。
3. 基本步骤
车牌识别的问题一般分为:
1. 车牌定位(Plate Detection)
2. 字符识别(Chars Recognition)
车牌定位(Plate Detection)+字符分割+字符识别(Chars Recognition)
4. 车牌定位
Plate Detection是物体检测过程,
4.1. 传统方法
4.1.1. 基于边缘(推荐)
基本步骤:
1. 在对车牌进行定位前,先将汽车图像通过灰度变换
2. 直方图均衡化等增强预处理,再经二值化,
3. 最后利用边缘检测算子对图像进行边缘检测。
检测到边缘后在进行区域膨胀,腐蚀去无关的小物件,这时图像会呈现出多个连通的判断区域,最后找出所有连通域中最可能是车牌的那一个便可
import cv2 import numpy as np def detect(image): # 1. 变成灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 2. 高斯滤波 blurred = cv2.GaussianBlur(gray, (5, 5), 0, 0, cv2.BORDER_DEFAULT) # cv2.imshow('blurred', blurred) # 3. 开运算 kernel = np.ones((23, 23), np.uint8) opened = cv2.morphologyEx(blurred, cv2.MORPH_OPEN, kernel) # cv2.imshow('opened',opened) # 4. 线性混合 opened = cv2.addWeighted(blurred, 1, opened, -1, 0) # cv2.imshow('opened', opened) # 5. 阈值分割 ret, thresh = cv2.threshold(opened, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 6. Canny边缘检测 edge = cv2.Canny(thresh, 100, 200) # 找到图像边缘 #cv2.imshow('canny',edge) # 7. 使用开运算和闭运算让图像边缘连成一个整体 kernel = np.ones((10, 10), np.uint8) edge1 = cv2.morphologyEx(edge, cv2.MORPH_CLOSE, kernel) edge2 = cv2.morphologyEx(edge1, cv2.MORPH_OPEN, kernel) cv2.imshow('edge',edge2) # 查找图像边缘整体形成的矩形区域,可能有很多,车牌就在其中一个矩形区域中 contours, hierarchy = cv2.findContours(edge2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) temp_contours = [] for contour in contours: # 计算图像轮廓的面积 if cv2.contourArea(contour) > 2000: temp_contours.append(contour) car_plates = [] for temp_contour in temp_contours: rect_tupple = cv2.minAreaRect(temp_contour) rect_width, rect_height = rect_tupple[1] if rect_width < rect_height: rect_width, rect_height = rect_height, rect_width aspect_ratio = rect_width / rect_height # 车牌正常情况下宽高比在2 - 5.5之间 if aspect_ratio > 2 and aspect_ratio < 5.5: car_plates.append(temp_contour) rect_vertices = cv2.boxPoints(rect_tupple) rect_vertices = np.int0(rect_vertices) if len(car_plates) == 1: for car_plate in car_plates: row_min, col_min = np.min(car_plate[:, 0, :], axis=0) row_max, col_max = np.max(car_plate[:, 0, :], axis=0) cv2.rectangle(image, (row_min, col_min), (row_max, col_max), (0, 255, 0), 2) card = image[col_min:col_max, row_min:row_max, :] cv2.ims how("img", image) cv2.imshow("card_img.jpg", card) if __name__ == '__main__': image = cv2.imread('Image/5.jpg') detect(image) cv2.waitKey(0) cv2.destroyAllWindows()
4.2. 基于深度学习
Wpod NET
车牌本质上是附加在车上的矩形平面物体。为了充分的利用车牌的形状优势,本文提出了一种 扭曲平面检测网络(Warped Planar Object Detection Network., WPOD NET)。该网络可以学习识别不同扭曲程度的车牌,并学习回归仿射变换的系数,将就扭曲的车牌unwarps成正面视图下的矩形形状。WOPD的检测流程如下图所示。
经过WPOD网络之后是一个8通道的特征图(图片中显示的是6通道,应该是8)
在特征图上提取扭曲的车牌,首先会设置固定大小的单元(m, n)
如果该单元的目标概率大于给定的阈值(threshold),那么部分回归参数用于构建放射变换矩阵,将虚拟正方形区域转换成车牌的区域
该网络的结构总共21层卷积,其中14层是内部残差块(ResBlock);所有的卷积核大小均为固定大小的33;除了识别块(Detection)以外,其他的激励函数全部是ReLu;包含有4个22大小的max pooling,stride=2,这样可以使得输入的维度减少了16倍(224);最后在识别模块有两个并行的卷积层
具体结构如下图(fig4)所示,左侧是网络的整体结构,右侧是ResBlock和Detection块的结构。
车牌识别1:License Plate Detection and Recognition in Unconstrained Scenarios阅读笔记
https://www.cnblogs.com/greentomlee/p/10863363.html