这个基于BP神经网络的手写数字/字母识别系统,是我在模式识别课程设计中完成的实战项目。不同于简单的MNIST数字识别,该项目扩展实现了以下特色功能:
整套代码在Matlab R2021b环境开发,经过实测在普通办公电脑(i5-8250U/8GB内存)上完成26个字母+10个数字的训练仅需约35分钟,最终测试集准确率达到96.7%。下面将详细解析各模块实现细节。
mermaid复制graph TD
A[原始图像] --> B[灰度化]
B --> C[二值化]
C --> D[字符分割]
D --> E[尺寸归一化]
E --> F[特征提取]
F --> G[BP神经网络]
G --> H[识别结果]
图像采集模块
预处理模块
神经网络结构
matlab复制% 加载自定义数据集
datasetPath = 'HandwrittenDataset/';
categories = {'0','1',...,'Z'};
imds = imageDatastore(fullfile(datasetPath, categories),...
'LabelSource', 'foldernames');
% 数据集分割
[trainingSet, testSet] = splitEachLabel(imds, 0.7, 'randomized');
matlab复制layers = [
imageInputLayer([32 32 1])
fullyConnectedLayer(256)
tanhLayer
fullyConnectedLayer(36)
softmaxLayer
classificationLayer];
options = trainingOptions('sgdm',...
'MaxEpochs',50,...
'Plots','training-progress');
matlab复制function processedImg = preprocessImage(img)
% 灰度化
if size(img,3)==3
img = rgb2gray(img);
end
% 二值化
thresh = graythresh(img);
bwImg = imbinarize(img, thresh);
% 反色处理(白底黑字)
processedImg = imcomplement(bwImg);
end
采用带动量的梯度下降法:
matlab复制Δw(t) = η*δ*x + α*Δw(t-1)
其中:
基于垂直投影的峰值检测:
matlab复制function bboxes = charSegment(bwImg)
verticalProj = sum(bwImg,1);
[peaks,locs] = findpeaks(-verticalProj);
% 计算字符边界
bboxes = [];
for i=1:length(locs)-1
width = locs(i+1)-locs(i);
if width>5 % 过滤噪声
bboxes = [bboxes; [locs(i),1,width,size(bwImg,1)]];
end
end
end
数据增强策略
加速训练技巧
matlab复制options.ExecutionEnvironment = 'gpu';
精度提升方法
code复制HandwritingRecognition/
├── Dataset/ # 包含36个分类文件夹
├── PretrainedModels/ # 保存的.mat模型文件
├── Utils/
│ ├── preprocess.m # 图像预处理
│ ├── visualize.m # 结果可视化
│ └── evaluate.m # 性能评估
├── trainNetwork.m # 训练主程序
└── recognizeText.m # 识别接口
matlab复制img = imread('test_A.png');
label = recognizeCharacter(img, net);
disp(['识别结果:', label]);
matlab复制textImg = imread('document.jpg');
lines = detectLines(textImg); % 基于水平投影
for i=1:length(lines)
chars = charSegment(lines{i});
text = '';
for j=1:size(chars,1)
charImg = imcrop(lines{i}, chars(j,:));
text = [text, recognizeCharacter(charImg, net)];
end
disp(['第',num2str(i),'行:', text]);
end
识别率突然下降
字符分割错误
训练不收敛
关键提示:当处理倾斜文本时,建议先进行Hough变换校正,再进行字符分割
动态学习系统
matlab复制function onlineLearning(newSamples)
% 增量更新网络权重
net = adapt(net, newSamples);
save('updatedModel.mat', 'net');
end
多语言支持
移动端部署
java复制MatlabRuntime.loadLibrary("handwriting");
float[] result = recognize(imageBytes);
自定义数据集
预训练模型
扩展工具包
(注:实际开发中建议使用EMNIST数据集作为补充)