基于opencv的SVM算法的车牌识别系统设计与实现
车牌识别技术是智能交通系统中的一项关键技术,它能够自动识别车辆的车牌号码。本文将详细介绍如何使用Python编程语言结合OpenCV库和SVM算法来实现车牌识别系统。
系统架构
车牌识别系统主要包括以下几个模块:
图像预处理:对输入的图像进行处理,以提高车牌检测的准确性。
车牌定位:在预处理后的图像中定位车牌的位置。
车牌矫正:对定位到的车牌图像进行矫正,以便于后续的字符分割和识别。
字符分割:将车牌上的字符分割开来,为字符识别做准备。
图像预处理
图像预处理的目的是去除图像中的噪声,并突出车牌的特征,以便于后续的车牌定位。预处理步骤如下:
读取图像:使用OpenCV的imread函数读取原始图像。
img_bgr = cv2.imread(pic_path, cv2.IMREAD_COLOR)
灰度转换:将彩色图像转换为灰度图像,便于后续处理。
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY) • 1
高斯模糊:使用高斯模糊平滑图像,减少噪声。
kernel = np.ones((20, 20), np.float32) / (20 * 20) img_opening = cv2.filter2D(img_gray, -1, kernel)
二值化:通过Otsu方法自动计算阈值,并将图像二值化。
_, img_edge = cv2.threshold(img_opening, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
形态学操作:通过闭操作连接车牌区域的边缘。
contours, _ = cv2.findContours(img_edge.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) img_contours = cv2.drawContours(img_edge.copy(), contours, -1, (255, 255, 255), 3)
车牌定位
车牌定位是识别过程中的关键步骤,它直接影响到后续字符分割和识别的准确性。我们采用边缘检测和颜色分割的方法来定位车牌。
边缘检测定位:利用车牌的垂直边缘特征,通过寻找垂直边缘来定位车牌。
for contour in contours: # 根据轮廓的面积和长宽比进行筛选 if minAreaRect(contour)[1][0] / minAreaRect(contour)[1][1] > 3 and minAreaRect(contour)[1][0] < minAreaRect(contour)[1][1] * 2: # 进一步处理和定位车牌
颜色分割定位:根据车牌颜色的特征,通过颜色空间分析来定位车牌区域。
hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV) # 定义颜色阈值范围 lower_color = np.array([lower_h, lower_s, lower_v]) upper_color = np.array([upper_h, upper_s, upper_v]) mask = cv2.inRange(hsv, lower_color, upper_color) # 应用形态学操作和轮廓查找
车牌矫正
车牌矫正的目的是将车牌图像调整为接近矩形的形状,以便于字符的准确分割和识别。这通常涉及到图像的透视变换。
字符分割
字符分割是将车牌上的字符分割开来,为字符识别做准备。这通常涉及到图像的投影分析和连通区域的查找。
字符识别
字符识别是使用训练好的SVM模型对分割后的字符进行识别。SVM是一种监督学习算法,它通过在训练数据集上学习来识别新的样本。
def pic(self, pic_path): # 以uint8方式读取 pic_path 放入 img_bgr 中,cv2.IMREAD_COLOR读取彩色照片 img_bgr = img_math.img_read(pic_path) # 缩小图片 转化成灰度图像 创建20*20的元素为1的矩阵 开操作,并和img重合 基于OTSU的二值化处理 找到图像边缘 # first_img, oldimg 已经处理好的图像文件 原图像文件 first_img, oldimg = self.predictor.img_first_pre(img_bgr) # 未开启摄像头时显示经过resize的图片 if not self.cameraflag: self.imgtk = self.get_imgtk(img_bgr) self.image_ctl.configure(image=self.imgtk) # 开始进行识别 # img_color_contours形状定位识别 输入 预处理好的图像 原图像 # 排除面积最小的点 进行矩形矫正 转换 分隔字符 分离车牌字符 # return 识别到的字符、定位的车牌图像、车牌颜色 # img_only_color颜色定位识别 输入 预处理好的图像 原图像 # 根据阈值找到对应颜色 认为水平方向,最大的波峰为车牌区域 查找垂直直方图波峰 去掉车牌上下边缘1个像素,避免白边影响阈值判断 分隔字符 分离车牌字符 # return 识别到的字符、定位的车牌图像、车牌颜色 th1 = ThreadWithReturnValue(target=self.predictor.img_color_contours, args=(first_img, oldimg)) th2 = ThreadWithReturnValue(target=self.predictor.img_only_color, args=(oldimg, oldimg, first_img)) th1.start() th2.start() r_c, roi_c, color_c = th1.join() r_color, roi_color, color_color = th2.join() # 显示 识别到的字符、定位的车牌图像、车牌颜色 self.show_roi2(r_color, roi_color, color_color) self.show_roi1(r_c, roi_c, color_c)