matlab基于图像处理的车牌识别系统,可以去雾,参数较多
MATLAB 的 .m 代码。以下我为你整理了实现该系统核心功能的代码模
核心代码模块
对应界面上的“打开彩色图片”按钮。
function pushbutton_load_Callback(hObject, eventdata, handles)
% 打开文件选择对话框
[filename, pathname] = uigetfile({.jpg;.png.bmp;.tif’, ‘Image Files’}, ‘Select an Image’);
if isequal(filename, 0) return; % 用户点击取消 end % 读取图像 global I; % 使用全局变量方便在不同回调函数间传递 I = imread([pathname filename]); % 在axes1中显示原图 axes(handles.axes1); imshow(I); title('原始图像');图像预处理与边缘检测
对应界面上的“灰度处理”、“边缘检测”等步骤。
function pushbutton_preprocess_Callback(hObject, eventdata, handles)
global I;
if isempty(I)
errordlg(‘请先读取图片!’, ‘错误’);
return;
end
% 1. 灰度化 I_gray = rgb2gray(I); % 2. 边缘检测 (Canny算子) % 可以根据界面上的滑块获取阈值,这里写死为0.1和0.2 I_edge = edge(I_gray, 'Canny', [0.1 0.2]); % 显示灰度图 axes(handles.axes2); imshow(I_gray); title('灰度图像'); % 显示边缘图 axes(handles.axes3); imshow(I_edge); title('边缘检测');车牌定位与分割
function pushbutton_locate_Callback(hObject, eventdata, handles)
global I;
I_gray = rgb2gray(I);
% 1. 边缘检测 I_edge = edge(I_gray, 'sobel'); % 2. 形态学操作 (闭运算连接字符) se = strel('rectangle', [5, 15]); % 结构元素 I_close = imclose(I_edge, se); % 3. 填充孔洞并去除小区域 I_fill = imfill(I_close, 'holes'); I_clean = bwareaopen(I_fill, 500); % 去除小于500像素的噪点 % 4. 查找轮廓并定位车牌 [B, L] = bwboundaries(I_clean, 'noholes'); stats = regionprops(L, 'BoundingBox', 'Area', 'Extent'); plate_img = []; for k = 1:length(B) bbox = stats(k).BoundingBox; area = stats(k).Area; extent = stats(k).Extent; % 根据长宽比和面积筛选车牌 (车牌通常长宽比约为4.5:1) aspect_ratio = bbox(3) / bbox(4); if aspect_ratio > 2 && aspect_ratio 2000 % 截取车牌区域 plate_img = imcrop(I, bbox); % 显示定位结果 axes(handles.axes4); imshow(plate_img); title('车牌定位'); break; end end if isempty(plate_img) errordlg('未找到车牌区域', '警告'); endend
字符分割与识别
这一步通常涉及二值化、垂直投影分割字符,然后与模板库进行匹配。
function pushbutton_recognize_Callback(hObject, eventdata, handles)
% 假设已经得到了车牌图像 plate_img
% 这里展示简单的二值化和分割逻辑
% 1. 灰度化和二值化 plate_gray = rgb2gray(plate_img); level = graythresh(plate_gray); plate_bw = im2bw(plate_gray, level); % 2. 字符分割 (基于垂直投影) % 这是一个简化的示例,实际需要去除边框和噪点 horz_sum = sum(plate_bw, 1); % 垂直方向求和 chars = []; in_char = false; start_idx = 1; for i = 1:length(horz_sum) if horz_sum(i) < size(plate_bw, 1) * 0.9 % 阈值判断 if ~in_char start_idx = i; in_char = true; end else if in_char % 提取单个字符 char_img = plate_bw(:, start_idx:i); chars{end+1} = imresize(char_img, [40 20]); % 归一化大小 in_char = false; end end end % 3. 显示分割结果 (在界面对应的axes中) axes(handles.axes5); % 这里需要把分割出来的字符拼接显示,代码略繁琐 % ... % 4. 识别 (模板匹配或神经网络) % result_text = ocr(plate_img); % 如果有OCR工具箱可以直接用 % set(handles.text_result, 'String', result_text);end
关键提示
结构元素(se):在形态学处理中,strel(‘rectangle’, [5, 15]) 的参数需要根据你的图片分辨率调整
长宽比筛选:车牌识别的核心在于筛选出符合车牌长宽比(中国大陆车牌约为 4.5:1 或 3:1)的矩形区域。
工具箱:确保你的 MATLAB 安装了 Image Processing Toolbox。
主程序 (对应 QR_main.m)
这是整个系统的入口,负责按顺序调用各个子模块。
function QR_main()
clc; clear; close all;
%% 1. 读取图像 % 假设读取文件夹下的某张测试图片 [filename, pathname] = uigetfile({.jpg;.png;*.bmp', 'Image Files'}, '选择车牌图片'); if isequal(filename, 0), return; end I = imread([pathname filename]); figure(1); imshow(I); title('原始图像'); %% 2. 车牌定位 (对应 detection_color2.m 的逻辑) % 这里调用颜色或边缘检测定位车牌 % 假设子函数返回裁剪后的车牌图像 Plate Plate = detection_color2(I); figure(2); imshow(Plate); title('定位出的车牌'); %% 3. 字符分割 (对应 my_split.m 的逻辑) % 将车牌图像分割成 7 个字符(省份+字母+5位号码) % dw 是分割后的字符单元数组 dw = my_split(Plate); %% 4. 字符识别 (对应 BP_NET.m 的逻辑) % 加载训练好的神经网络模型 load my_net.mat; % 加载网络结构 Result = ''; for k = 1:7 % 预处理单个字符图像 (调整大小到 20x40 或其他训练尺寸) img = imresize(dw{k}, [40 20]); % 转为向量输入 input_vec = double(img(:)) / 255; % 使用神经网络进行预测 output = sim(net, input_vec'); % net 是 load 进来的网络 % 找到概率最大的索引 [~, index] = max(output); % 将索引转换为字符 (需要定义一个字符库,如 '京沪津...' '012...' 'ABC...') char_result = getword(index); % 假设有这个映射函数 Result = [Result, char_result]; end %% 5. 显示结果 msgbox(['识别结果: ', Result], '识别完成');end
核心模块 1:车牌定位 (对应 detection_color2.m)
这个文件通常使用颜色特征(如蓝色像素统计)或边缘检测来找到车牌位置。
function Plate = detection_color2(I)
% 简单的基于颜色的定位逻辑示例
% 1. 转为 HSV 空间,便于提取蓝色
hsv = rgb2hsv(I);
H = hsv(:,:,1); S = hsv(:,:,2); V = hsv(:,:,3);
% 2. 设定蓝色阈值 (具体数值需调试) % 蓝色在 HSV 中通常在 0.55 - 0.75 之间 blue_mask = (H > 0.55 & H 0.4) & (V > 0.3); % 3. 形态学操作去噪 se = strel('rectangle', [10, 10]); mask_clean = imclose(blue_mask, se); % 4. 寻找最大连通域 (即车牌) stats = regionprops(mask_clean, 'Area', 'BoundingBox', 'Eccentricity'); max_area = 0; box = []; for i = 1:length(stats) % 简单的长宽比过滤 wh_ratio = stats(i).BoundingBox(3) / stats(i).BoundingBox(4); if stats(i).Area > max_area && wh_ratio > 2 && wh_ratio < 5 max_area = stats(i).Area; box = stats(i).BoundingBox; end end % 5. 裁剪图像 if ~isempty(box) Plate = imcrop(I, box); else Plate = I; % 失败则返回原图 endend
核心模块 2:BP 神经网络训练 (对应 BP_train.m)
在使用识别功能前,必须先运行这个脚本训练网络并保存 my_net.mat。
function BP_train()
% 1. 准备数据
% 假设你有一个文件夹 ‘车牌库’,里面按类别分好了文件夹 (如 ‘0’, ‘1’, ‘A’, ‘B’…)
% 读取图片并转为向量
% inputs: 输入矩阵 (列向量为样本)
% targets: 目标矩阵 (one-hot 编码)
% 这里仅为伪代码框架 % inputs = ... % targets = ... % 2. 创建网络 % 输入层节点数 = 图片像素 (如 20*40=800) % 隐藏层节点数 = 经验值 (如 30) % 输出层节点数 = 字符类别数 (如 34 类) net = newff(inputs, targets, 30, {'tansig', 'purelin'}, 'trainlm'); % 3. 设置训练参数 net.trainParam.epochs = 1000; net.trainParam.goal = 0.01; % 4. 训练 net = train(net, inputs, targets); % 5. 保存网络 save('my_net.mat', 'net'); disp('训练完成,网络已保存!');end
如何运行这个项目
打开 MATLAB。
切换目录:在 MATLAB 左侧“当前文件夹”栏中,导航到你截图中的路径 D:Matlab 2022bprojecttest62车牌。