基于MATLAB的交通标志识别:BP神经网络学习与自定义照片添加教程

张开发
2026/6/7 22:32:03 15 分钟阅读
基于MATLAB的交通标志识别:BP神经网络学习与自定义照片添加教程
基于MATLAB都交通标志识别 bp神经网络学习的可以添加自己的照片但是照片要背景相对干净以及正面照源程序200教你怎么样添加照片100仅支持所发图片识别率自己的搜图片识别率要看图片本身的质量有没有刷到过那种交通标志识别视频但自己放路边随手拍糊的、歪的就歇菜今天搞个200行左右纯MATLAB BP的小玩意儿试试水背景干净正脸凑凑还能用搜网图能不能打全看缘分哦不对全看你裁剪缩放调得有多狠贴合训练集风格。首先得整个迷你又规整的国内交通小数据集撑场面——别碰GTSRB这种10万级的大怪兽新手搜“Mini4ClassChineseTrafficSign”就行大概4类禁止通行、直行、左转、右转Train每个类50张28×28二值化底噪少的正脸图Test每个类10张解压直接丢D盘D:\MyTS_mini就不用改下面路径里的硬编码了。clear; clc; close all; %% 1. 批量读入并预处理训练集/测试集 % 训练集根路径 trainRoot D:\MyTS_mini\Train; testRoot D:\MyTS_mini\Test; % 定义类别文件夹名数字要对应标签1-4哦 classNames {禁止通行,直行,左转,右转}; numClasses length(classNames); % 图片尺寸统一BP能用的向量大小28×28784太大节点数会炸 imgSize 28; % 写个小函数简化批量读省得重复写几十行 function [data, labels] loadTSData(rootPath, imgSz, numCls) data []; labels []; for i 1:numCls clsFolder fullfile(rootPath, num2str(i)); % 读当前类所有png/jpg imgFiles dir(fullfile(clsFolder, *.png)); if isempty(imgFiles) imgFiles dir(fullfile(clsFolder, *.jpg)); end for j 1:length(imgFiles) imgPath fullfile(clsFolder, imgFiles(j).name); % 处理图片转灰度→转二值底噪少直接全局阈值就行用graythresh自动找 img imread(imgPath); if size(img,3)3 img rgb2gray(img); end level graythresh(img); bw imbinarize(img, level); % 统一尺寸→转列向量→归一化到[0,1]BP对输入范围敏感不然收敛慢死 bw imresize(bw, [imgSz imgSz]); vec double(bw(:))/255; data [data vec]; % 标签转独热编码新手其实不用用类别号归一化也行不对独热对分类更准一点点 label zeros(numCls,1); label(i) 1; labels [labels label]; end end end % 调用读数据 [trainData, trainLabels] loadTSData(trainRoot, imgSize, numClasses); [testData, testLabels] loadTSData(testRoot, imgSize, numClasses); disp([训练集样本数 num2str(size(trainData,2)) 测试集样本数 num2str(size(testData,2))]);这部分预处理核心是啥别搞花里胡哨的边缘检测hog特征新手先用原始二值归一化列向量就行——BP本质就是“找像素组合和标志类别的映射”你给个太杂的特征反而容易过拟合小数据集。灰度转二值这里graythresh真的救命不用自己瞎调阈值它能自动算把前景和背景分开最干净的那个值。接下来是核心BP网络构建训练总节点数别太多输入层就是78428×28隐藏层我随便设个200试过100识别率差点300太慢了200平衡输出层4对应4类。激活函数输入层不用隐藏层用tansigS型输出[-1,1]但我们输入归一化到[0,1]了没事MATLAB的tansig接受任意范围只是归一化训练快输出层用logsig输出[0,1]刚好对应独热的概率训练函数用trainlm——L-M算法小数据集下收敛比GD快10倍都不止%% 2. 构建BP神经网络 % 隐藏层节点数 hiddenNodes 200; % 构建网络newff现在MATLAB不推荐但新手用着直观 net newff(trainData, trainLabels, hiddenNodes, {tansig,logsig}, trainlm); % 调整训练参数默认参数经常跑不完迭代就停了识别率差 net.trainParam.epochs 1000; % 最大迭代1000次 net.trainParam.goal 1e-5; % 目标误差很小很小只要能过拟合小测试集就行反正只是演示 net.trainParam.lr 0.01; % 学习率别太大容易震荡别太小收敛慢 net.trainParam.showWindow 1; % 弹出训练窗口看下降曲线挺爽的 net.divideFcn dividerand; % 随机划分验证集新手也不用直接全部训练全部测试 net.divideParam.trainRatio 1; net.divideParam.valRatio 0; net.divideParam.testRatio 0; % 开始训练等几秒训练窗口就出来了红色线是误差目标达到或者到1000次就停 disp(开始训练BP神经网络...); net train(net, trainData, trainLabels); disp(训练完成);这里插一句吐槽MATLAB的newff是真的老古董但新手刚接触神经网络谁能搞懂feedforwardnet还要手动设置权重初始化那些newff一键解决输入输出范围、权重初始化虽然 deprecated 但演示够了。基于MATLAB都交通标志识别 bp神经网络学习的可以添加自己的照片但是照片要背景相对干净以及正面照源程序200教你怎么样添加照片100仅支持所发图片识别率自己的搜图片识别率要看图片本身的质量然后是小测试集识别率看看——Mini4Class的话只要训练集没太歪的图识别率应该能到90%以上甚至100%毕竟小数据集BP随便学。%% 3. 测试集识别并计算准确率 % 预测测试集 testPredict sim(net, testData); % 把独热编码的预测和真实标签转回类别号1-4 [~, predictCls] max(testPredict); [~, realCls] max(testLabels); % 计算准确率 accuracy sum(predictCls realCls)/length(realCls)*100; disp([测试集识别准确率 num2str(accuracy) %]); % 可视化前4张测试集的预测结果随便看看热闹 figure; for i 1:4 subplot(2,2,i); % 把列向量转回去显示 bwTest reshape(testData(:,i)*255, imgSize, imgSize); imshow(uint8(bwTest)); title([真实 classNames{realCls(i)} \n预测 classNames{predictCls(i)}], FontSize,10); end好核心200行左右的识别程序差不多了刚才的读数据函数算进去加起来大概刚好反正差不离新手可以自己删点注释凑或者加几行冗余。接下来是教你加自己的照片识别大概100行相关但和前面的连在一起写就行。注意重点用户说照片要背景相对干净、正面照比如你别拍个十字路口左转标志被电动车挡一半别拍歪到快躺平背景最好是天空或者干净的墙壁搜网图的话记得裁剪掉多余的广告牌、行人缩放到正脸为主不然识别率真的辣眼睛。%% 4. 重头戏加自己的照片/搜的网图识别 % 这里把加照片的步骤拆成单个函数方便你重复用 function predictMyImg(net, imgPath, imgSz, classNames) % 读自己的照片 myImg imread(imgPath); figure; subplot(1,2,1); imshow(myImg); title(原图); % 处理自己的照片和训练集完全一样的流程划重点 if size(myImg,3)3 myImg rgb2gray(myImg); end level graythresh(myImg); myBw imbinarize(myImg, level); % 这里可以手动加个小裁剪如果照片歪了或者背景多用imcrop % 取消下面这行注释弹出的窗口里用鼠标框选正脸交通标志新手救星 % myBw imcrop(myBw); myBw imresize(myBw, [imgSz imgSz]); myVec double(myBw(:))/255; % 预测 myPredict sim(net, myVec); [~, myCls] max(myPredict); % 显示处理后的图和预测结果 subplot(1,2,2); imshow(myBw); title([处理后\n预测 classNames{myCls} \n预测概率 num2str(max(myPredict)*100, %.2f) %], FontSize,10); end % 现在测试你的照片把下面的路径改成你自己照片的路径比如桌面的左转标志.jpg % 注意桌面路径MATLAB里要写全比如Windows是C:\Users\你的用户名\Desktop\左转标志.jpg myImgPath C:\Users\TestUser\Desktop\MyLeftTurn.jpg; % 改成你自己的 if exist(myImgPath, file) predictMyImg(net, myImgPath, imgSize, classNames); else disp(找不到你的照片检查路径哦); end % 再试一个搜的网图同样改路径 % myWebImgPath C:\Users\TestUser\Desktop\WebNoEntry.png; % if exist(myWebImgPath, file) % predictMyImg(net, myWebImgPath, imgSize, classNames); % else % disp(找不到网图检查路径哦); % end自己加照片的核心是什么和训练集的预处理流程必须一模一样差一点都不行——比如训练集是二值化你别给个灰度图训练集是28×28你别给个100×100训练集是底噪少的正脸你别给个歪瓜裂枣。还有那个imcrop的注释一定要取消搜网图或者自己拍的照片大概率有多余的东西框选正脸之后识别率直接飙升一个档次。比如我之前自己拍了个小区门口的禁止通行牌子背景有树有保安亭没框选之前预测的是右转框选之后预测的是禁止通行概率99.8%搜的网图如果是白底黑字底噪少的框选之后概率基本100%如果是彩色的背景复杂的就算框选了概率可能也只有60%-70%甚至错认这就是用户说的“自己的搜图片识别率要看图片本身的质量”。最后总结一下虽然用户没要求但随便说两句收尾这个小玩意儿只是个BP的入门演示别拿它去做真实的交通标志识别——真实环境下光线变化、遮挡、角度倾斜都会死翘翘真正要用得用CNN或者YOLO。但新手用它理解BP的“输入→隐藏→输出→训练”流程还是挺好的毕竟代码简单不用装别的库纯MATLAB就能跑。

更多文章