文章封面
原创

基于Python+PyQt5+SVM的车牌识别系统设计与实现

前言

在计算机专业的毕业设计、课程设计选题中,基于计算机视觉的车牌识别系统是经典且热门的方向——既有技术深度,又有明确的实际应用场景,答辩认可度高。但很多同学从零实现时,常会遇到车牌定位不准、字符识别率低、界面开发繁琐等问题,网上零散的免费源码又普遍存在缺文件、跑不通、无售后的痛点。

本文就完整拆解一套基于Python+PyQt5+SVM算法的车牌识别系统,从算法原理、核心代码到界面实现逐一讲解,完整覆盖车牌定位、字符分割、模型训练、可视化交互全流程,非常适合用作毕设、课程设计、期末大作业的参考项目。


一、项目概述与技术栈

1.1 项目功能与适用场景

本项目是一套客户端式车牌识别软件,支持上传本地汽车图片,自动完成车牌定位、矫正、字符分割与识别,最终输出完整车牌号码与车牌颜色。

  • 支持蓝牌、绿牌、黄牌三种主流车牌识别

  • 自带可视化交互界面,操作直观

  • 识别速度快,清晰场景下准确率高

  • 适用于智能交通、园区车辆管理等场景,也可直接用于计算机专业毕设、课程设计项目

1.2 核心技术栈

技术模块选用工具/算法
开发语言Python 3.x
图像处理OpenCV
字符识别算法SVM支持向量机
图形界面PyQt5
开发环境PyCharm

二、系统整体架构与识别流程

2.1 系统分层架构

系统整体分为两层,职责清晰,便于二次开发与功能扩展:

  1. 界面UI层:基于PyQt5实现,负责图片导入、识别结果展示、操作交互,直观呈现车牌定位区域与识别号码

  2. 算法核心层:包含图像预处理、车牌定位、倾斜矫正、字符分割、SVM字符识别五大模块,是系统的核心功能支撑

2.2 完整识别流程

系统按标准化步骤处理图像,流程可控且可针对不同场景优化参数:

图像缩放 → 灰度化与去噪 → 边缘检测与形态学处理 → 轮廓筛选定位车牌 → 倾斜矫正 → 颜色判别 → 字符分割 → 特征提取 → SVM识别 → 结果输出


三、核心算法实现(附核心代码)

3.1 车牌定位与图像预处理

车牌定位是识别的第一步,直接决定最终识别准确率。本项目通过“去噪-边缘提取-轮廓筛选-颜色校验”多步组合,实现稳定的车牌区域提取。

3.1.1 图像去噪与灰度化

先对原图进行高斯模糊去除噪声,再转换为灰度图,降低计算量同时保留边缘特征。

import cv2
import numpy as np

# 高斯去噪 + 灰度化
def preprocess_image(img, blur=5):
    if blur > 0:
        # 高斯模糊去除噪声
        img = cv2.GaussianBlur(img, (blur, blur), 0)
    # BGR转灰度图
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return gray_img

3.1.2 边缘检测与形态学处理

通过Canny算子提取边缘,再用开闭运算将离散边缘连成完整区域,便于后续轮廓查找。

def edge_detect(gray_img):
    # 顶帽处理突出车牌区域
    kernel = np.ones((20, 20), np.uint8)
    img_opening = cv2.morphologyEx(gray_img, cv2.MORPH_OPEN, kernel)
    img_opening = cv2.addWeighted(gray_img, 1, img_opening, -1, 0)
    
    # Otsu二值化 + Canny边缘检测
    ret, img_thresh = cv2.threshold(img_opening, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    img_edge = cv2.Canny(img_thresh, 100, 200)
    
    # 闭运算连接边缘,开运算去除噪点
    kernel_close = np.ones((4, 19), np.uint8)
    img_edge1 = cv2.morphologyEx(img_edge, cv2.MORPH_CLOSE, kernel_close)
    img_edge2 = cv2.morphologyEx(img_edge1, cv2.MORPH_OPEN, kernel_close)
    return img_edge2

3.1.3 轮廓筛选与倾斜矫正

根据车牌长宽比(2:1~5.5:1)筛选候选矩形轮廓,再对倾斜的车牌进行仿射变换矫正,保证字符水平。

def find_plate_contours(img_edge, min_area=1000):
    # 查找所有轮廓
    contours, hierarchy = cv2.findContours(img_edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    plate_rects = []
    
    for cnt in contours:
        if cv2.contourArea(cnt) < min_area:
            continue
        # 获取最小外接矩形
        rect = cv2.minAreaRect(cnt)
        w, h = rect[1]
        if w < h:
            w, h = h, w
        # 按车牌长宽比筛选
        ratio = w / h
        if 2 < ratio < 5.5:
            plate_rects.append(rect)
    return plate_rects

3.1.4 车牌颜色判别

转换到HSV颜色空间,通过色调范围判断车牌颜色(蓝/绿/黄),同时反向处理黄、绿车牌,提升后续字符分割准确率。

def detect_plate_color(card_img):
    hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV)
    row_num, col_num = card_img.shape[:2]
    total = row_num * col_num
    yellow = green = blue = 0
    
    for i in range(row_num):
        for j in range(col_num):
            H, S, V = hsv[i, j]
            if 11 < H <= 34 and S > 34:
                yellow += 1
            elif 35 < H <= 99 and S > 34:
                green += 1
            elif 99 < H <= 124 and S > 34:
                blue += 1
    
    if yellow * 2 >= total:
        return "yellow"
    elif green * 2 >= total:
        return "green"
    elif blue * 2 >= total:
        return "blue"
    return "unknown"

3.2 字符分割与特征提取

3.2.1 基于直方图的字符分割

通过水平、垂直灰度直方图查找波峰,分离出单个字符,同时去除铆钉、边框等干扰因素。

def split_chars(gray_img, color):
    # 黄绿牌字符反转,便于分割
    if color in ["green", "yellow"]:
        gray_img = cv2.bitwise_not(gray_img)
    ret, binary = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    # 水平直方图裁剪上下边缘
    x_hist = np.sum(binary, axis=1)
    x_min = np.min(x_hist)
    x_avg = np.sum(x_hist) / x_hist.shape[0]
    x_thresh = (x_min + x_avg) / 2
    # 查找水平波峰,截取有效车牌区域
    
    # 垂直直方图分割单个字符
    y_hist = np.sum(binary, axis=0)
    # 按波峰分割字符,处理汉字与分隔点
    # 最终返回分割后的单字符图像列表
    pass

3.2.2 HOG特征提取

对单个字符提取HOG方向梯度直方图特征,作为SVM模型的输入,提升识别准确率。

def preprocess_hog(digits):
    samples = []
    for img in digits:
        # Sobel算子计算梯度
        gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
        gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
        mag, ang = cv2.cartToPolar(gx, gy)
        bin_n = 16
        bin = np.int32(bin_n * ang / (2 * np.pi))
        
        # 分块计算直方图
        bin_cells = bin[:10,:10], bin[10:,:10], bin[:10,10:], bin[10:,10:]
        mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
        hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
        hist = np.hstack(hists)
        
        # Hellinger核归一化
        eps = 1e-7
        hist /= hist.sum() + eps
        hist = np.sqrt(hist)
        hist /= np.linalg.norm(hist) + eps
        samples.append(hist)
    return np.float32(samples)

3.3 SVM字符分类模型

采用OpenCV内置的SVM分类器,分别训练汉字、字母数字两个模型,完成车牌字符识别。

class SVMClassifier:
    def __init__(self, C=1, gamma=0.5):
        self.model = cv2.ml.SVM_create()
        self.model.setGamma(gamma)
        self.model.setC(C)
        # RBF核函数,适配非线性分类
        self.model.setKernel(cv2.ml.SVM_RBF)
        self.model.setType(cv2.ml.SVM_C_SVC)
    
    def train(self, samples, labels):
        # 训练模型
        self.model.train(samples, cv2.ml.ROW_SAMPLE, labels)
    
    def predict(self, samples):
        # 预测字符类别
        _, result = self.model.predict(samples)
        return result.ravel()

四、PyQt5可视化界面实现

4.1 界面整体布局

界面采用左右分栏布局:

  • 左侧:图像显示区,展示原始车牌图片

  • 右侧:识别结果区 + 控制面板,展示车牌定位预览、识别号码、车牌颜色,以及打开图片、清空数据按钮

4.2 核心界面代码

from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
import sys

class PlateRecognitionWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("OpenCV SVM车牌识别系统")
        self.setMinimumSize(1100, 700)
        
        # 初始化识别器
        self.predictor = None
        
        # 构建界面
        self.init_ui()
        self.clean_state()
    
    def init_ui(self):
        # 主布局 左右分栏
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QHBoxLayout(central_widget)
        main_layout.setContentsMargins(30, 30, 30, 30)
        main_layout.setSpacing(25)
        
        # 左侧图像显示区
        self.image_label = QLabel("欢迎使用车牌识别系统")
        self.image_label.setAlignment(Qt.AlignCenter)
        self.image_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        main_layout.addWidget(self.image_label, 6)
        
        # 右侧功能区
        right_widget = QWidget()
        right_widget.setFixedWidth(360)
        right_layout = QVBoxLayout(right_widget)
        
        # 识别结果分组
        res_group = QGroupBox("识别结果分析")
        res_layout = QVBoxLayout(res_group)
        self.roi_label = QLabel("车牌预览区")
        self.result_label = QLabel("待识别")
        self.color_label = QLabel("车牌颜色:---")
        res_layout.addWidget(self.roi_label)
        res_layout.addWidget(self.result_label)
        res_layout.addWidget(self.color_label)
        
        # 控制面板分组
        btn_group = QGroupBox("系统控制面板")
        btn_layout = QVBoxLayout(btn_group)
        self.btn_load = QPushButton("打开本地图片")
        self.btn_clear = QPushButton("清空当前数据")
        btn_layout.addWidget(self.btn_load)
        btn_layout.addWidget(self.btn_clear)
        
        right_layout.addWidget(res_group)
        right_layout.addWidget(btn_group)
        main_layout.addWidget(right_widget, 4)
        
        # 绑定事件
        self.btn_load.clicked.connect(self.load_image)
        self.btn_clear.clicked.connect(self.clean_state)
    
    def load_image(self):
        # 打开本地图片并执行识别
        pass
    
    def clean_state(self):
        # 重置界面状态
        pass

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = PlateRecognitionWindow()
    window.show()
    sys.exit(app.exec_())

五、系统运行效果

  1. 蓝色车牌识别:常规民用蓝牌定位准确,字符识别率高,适合绝大多数日常场景

  2. 绿色新能源车牌:支持8位新能源车牌识别,自动适配绿牌颜色特征

  3. 黄色车牌:支持大型车辆黄牌识别,自动处理字符颜色反转

系统在光线充足、车牌清晰的场景下识别准确率优异,界面操作简洁,运行稳定,满足日常演示与项目交付需求。

对应的系统全功能操作演示、部署步骤实拍视频,我也同步更新在了B站账号 兵慌码乱,想看动态运行效果、跟着视频一步步部署的同学,可以自行搜索查看。


六、本地部署运行步骤

  1. 安装Python 3.8及以上版本

  2. 安装依赖库:

pip install opencv-python pyqt5 numpy
  1. 导入项目代码,配置好SVM训练模型文件

  2. 运行主程序文件,点击“打开本地图片”选择车牌图片即可自动识别


七、总结

本项目完整实现了从车牌定位到字符识别的全流程,基于Python开发上手难度低,代码结构清晰便于二次修改,同时自带可视化界面,非常适合作为计算机专业的毕业设计、课程设计项目。

八、资料获取

PyQt5SVM车牌识别
  • 作者:兵慌码乱(联系作者)
  • 发表时间:2026-07-19 20:17
  • 版权声明:兵慌码乱 版权所有,侵权必究
  • 转载声明:禁止转载,文章发表于 www.bhml.com.cn
  • 备注:文章如有疏漏,望请留言指出,如果对项目还有不清楚的地方,欢迎与我取得联系,欢迎交流学习!
QQ二维码

留言互动