基于STM32H743与CNN的实时手写数字识别系统
基于STM32H743与CNN的
实时手写数字识别系统
—— STM32H743 + OV7725摄像头 + ST7789 LCD + 卷积神经网络 ——
|
主控芯片 |
STM32H743VIT (Cortex-M7, 480MHz, 2MB Flash) |
|
图像采集 |
OV7725 摄像头 (DCMI接口, 160×120 RGB565) |
|
显示模块 |
ST7789 0.96寸 LCD (SPI6, 160×80) |
|
AI框架 |
X-CUBE-AI + TensorFlow/Keras 轻量CNN |
|
识别精度 |
MNIST测试集准确率 99.02% |
一、项目简介
本项目实现了一套基于STM32H743微控制器与卷积神经网络(CNN)的实时手写数字识别系统。系统通过OV7725摄像头实时采集图像,经图像预处理(裁剪、缩放、灰度化、二值化、归一化)后,输入轻量级CNN模型进行推理,最终在ST7789 LCD屏幕上实时显示识别结果(0~9)。
整个项目涵盖了从数据集准备、模型训练、模型转换到嵌入式部署的全流程,是一个完整的端到端嵌入式AI应用案例。模型在MNIST测试集上达到99.02%的准确率,部署到STM32H743后可实现每200ms一次的实时推理,并通过4帧滑动投票滤波抑制识别结果跳变,具有良好的实用价值。
核心技术栈
|
环节 |
技术/工具 |
说明 |
|
数据集 |
MNIST手写数字 |
60000张训练+10000张测试, 28×28灰度图 |
|
模型训练 |
Python + TensorFlow/Keras |
轻量CNN, 2卷积层+2全连接层 |
|
模型转换 |
TFLite Converter |
H5转TFLite, 保持float32精度 |
|
模型部署 |
STM32Cube.AI (X-CUBE-AI) |
自动生成C代码, CM7运行时库 |
|
图像采集 |
OV7725 + DCMI + DMA |
160×120 RGB565, DMA零拷贝传输 |
|
结果显示 |
ST7789 LCD + SPI6 |
0.96寸屏, 显示原图/预处理图/结果 |
|
结果优化 |
4帧滑动投票滤波 |
抑制实时识别结果跳变 |
二、系统总体架构
系统整体架构如下图所示,分为图像采集层、数据处理层、AI推理层和结果显示层四个部分:
|
【图像采集层】 OV7725摄像头 → DCMI接口 → DMA零拷贝传输 → 160×120 RGB565图像缓冲区 |
|
【数据处理层】 居中裁剪80×80 → 缩放至28×28 → RGB565转灰度 → 二值化(阈值180) → 归一化反转 |
|
【AI推理层】 ai_in[784]浮点输入 → X-CUBE-AI前向传播 → ai_out[10]概率输出 → argmax取最大值 |
|
【结果显示层】 4帧投票滤波 → ST7789 LCD显示原图+预处理图+识别结果 → 每200ms刷新一次 |
三、硬件设计
3.1 核心器件
|
器件 |
型号 |
关键参数 |
用途 |
|
主控MCU |
STM32H743VIT |
Cortex-M7, 480MHz, 2MB Flash, 1MB RAM |
系统主控+AI推理 |
|
摄像头 |
OV7725 |
1/4寸CMOS, VGA, RGB565, DVP接口 |
手写数字图像采集 |
|
显示屏 |
ST7789 |
0.96寸, 160×80, SPI接口, 65K色 |
实时显示图像与结果 |
|
晶振 |
25MHz HSE |
经PLL倍频至480MHz |
系统主时钟源 |
3.2 引脚分配
|
外设 |
STM32引脚 |
功能说明 |
|
DCMI数据线 |
PC6/PC7/PE0/PE1/PE4/PB6/PE5/PE6 |
摄像头8位数据D0~D7 |
|
DCMI_HSYNC |
PA4 |
行同步信号 |
|
DCMI_VSYNC |
PB7 |
场同步信号 |
|
DCMI_PIXCLK |
PA6 |
像素时钟 |
|
I2C1_SCL/SDA |
PB8/PB9 |
摄像头SCCB寄存器配置 |
|
SPI6_SCK/MISO/MOSI |
PG13/PG12/PG14 |
LCD显示屏SPI通信 |
|
LCD_RST/DC/PWR |
PG4/PG3/PG5 |
LCD复位/数据命令/背光控制 |
|
USART1_TX/RX |
PA9/PA10 |
调试串口 |
|
KEY |
PC13 |
用户按键 |
|
RGB LED |
PC0/PC1/PC2 |
状态指示灯 |
注:DCMI配合DMA1_Stream0实现图像数据零拷贝传输,摄像头采集的图像直接写入内存缓冲区,无需CPU干预,大幅提升图像采集效率。
四、神经网络模型设计与训练
4.1 MNIST数据集
本项目使用经典的MNIST手写数字数据集进行模型训练。MNIST包含60000张训练图像和10000张测试图像,每张图像为28×28像素的灰度手写数字(0~9),是深度学习入门的标准数据集。

图4-1 MNIST手写数字数据集样本展示
4.2 CNN模型结构
为适配STM32嵌入式平台的算力和存储限制,本项目设计了一个轻量级卷积神经网络,包含2个卷积层、2个最大池化层和2个全连接层。模型结构如下表:
|
层名 |
类型 |
输出形状 |
参数量 |
说明 |
|
Input |
输入层 |
1×28×28×1 |
- |
28×28灰度图 |
|
conv2d_0 |
Conv2D(16@3×3)+ReLU |
1×26×26×16 |
160 |
第一卷积层 |
|
pool_1 |
MaxPool2D(2×2) |
1×13×13×16 |
- |
下采样 |
|
conv2d_2 |
Conv2D(32@3×3)+ReLU |
1×11×11×32 |
4,736 |
第二卷积层 |
|
pool_3 |
MaxPool2D(2×2) |
1×5×5×32 |
- |
下采样 |
|
reshape_4 |
Flatten |
1×800 |
- |
展平 |
|
gemm_5 |
Dense(64)+ReLU |
1×64 |
51,264 |
全连接层 |
|
gemm_6 |
Dense(10) |
1×10 |
650 |
输出层 |
|
nl_7 |
Softmax |
1×10 |
- |
概率输出 |
4.3 模型训练
模型使用Python + TensorFlow/Keras框架进行训练,优化器为Adam,损失函数为稀疏交叉熵。训练代码如下图所示:

图4-2 MNIST模型训练代码(Python/TensorFlow)
训练过程截图如下,可以看到模型在训练过程中损失持续下降,准确率稳步提升:

图4-3 PyCharm中模型训练代码运行

图4-4 训练过程(Epoch 4~7损失与准确率)
训练最终结果如下图所示,模型在测试集上达到了99.02%的准确率:

图4-5 训练完成,测试集准确率99.02%
4.4 模型转换与部署
训练好的Keras H5模型需要转换为TFLite格式,再通过STM32Cube.AI工具链导入生成C代码,最终编译部署到STM32H743上。转换流程如下:
Step 1: H5模型转TFLite(不使用INT8量化,保持float32精度以确保CubeAI兼容性):

图4-6 H5转TFLite模型转换代码
Step 2: STM32Cube.AI导入TFLite模型,自动生成C代码:
在STM32CubeMX中配置X-CUBE-AI中间件,导入TFLite模型后,工具自动生成network_data.c(权重数据)、network_data_params.c(参数配置)和app_x-cube-ai.c(推理接口)等文件。
Step 3: 模型资源占用报告(X-CUBE-AI生成):
|
资源 |
占用 |
说明 |
|
Flash(权重) |
221.54 KiB |
模型权重存储在Flash中 |
|
RAM(激活值) |
16.21 KiB |
推理时的中间激活值 |
|
总Flash |
236.91 KiB |
权重+代码+常量 |
|
总RAM |
18.86 KiB |
激活值+IO缓冲区 |
|
MACC运算量 |
735,792 |
单次推理乘加运算次数 |
|
输入 |
f32(1×28×28×1) |
784个浮点数 |
|
输出 |
f32(1×10) |
10个概率值(softmax) |
注:STM32H743拥有2MB Flash和1MB RAM,模型占用不到12%的Flash和2%的RAM,资源充裕。
五、软件设计
5.1 主程序流程
系统上电后依次完成CPU缓存使能、HAL初始化、480MHz时钟配置、各外设初始化(GPIO/DMA/SPI6/DCMI/USART1/I2C1)、LCD初始化、摄像头初始化和AI模型初始化,随后启动DCMI DMA连续采集并进入主循环。主循环中并行处理图像显示和AI推理两个任务。主函数代码如下:

图5-1 主函数初始化与主循环代码
5.2 图像预处理
图像预处理是连接摄像头采集与AI模型推理的关键环节。由于OV7725采集的是160×120的RGB565彩色图像,而MNIST模型需要28×28的灰度归一化输入,因此需要经过以下处理步骤:
- 【裁剪】从160×120图像中居中裁剪80×80区域,聚焦数字主体
- 【缩放】使用最近邻采样将80×80缩放至28×28,匹配模型输入尺寸
- 【灰度化】RGB565转灰度:0.299R + 0.587G + 0.114B标准公式
- 【二值化】阈值180二值化:大于180设为255(白),否则0(黑)
- 【归一化】1.0 - gray/255.0 反转归一化,适配MNIST白底黑字格式

图5-2 图像预处理代码(裁剪/缩放/灰度化/二值化/归一化)
5.3 AI推理引擎
AI推理由X-CUBE-AI运行时库驱动。每次推理时,先将预处理后的784个浮点数拷贝到AI输入缓冲区,调用ai_network_run()执行前向传播,再将输出的10个概率值取回。推理接口代码如下:

图5-3 X-CUBE-AI推理引擎代码(输入填充/前向传播/输出取回)
5.4 识别结果滤波
由于实时识别中摄像头画面可能存在抖动或光照变化,单次识别结果可能出现跳变。系统采用4帧滑动窗口投票滤波:缓存最近4次识别结果,取出现次数最多的数字作为最终输出,有效抑制了结果跳变,提升了识别稳定性。滤波代码如下:

图5-4 识别结果滑动投票滤波代码
5.5 LCD显示
ST7789 LCD通过SPI6与STM32通信,屏幕分辨率为160×80(旋转90度后)。主循环中LCD实时显示三类内容:
- 【原图显示】160×80原始摄像头画面(左侧)
- 【预处理图】28×28预处理灰度图放大2倍显示(右侧)
- 【识别结果】"RES:X"格式的识别结果文字叠加在画面上
DCMI帧中断回调函数中刷新D-Cache并置位帧就绪标志,主循环检测到标志后执行显示更新。
六、项目文件结构
工程采用STM32CubeMX生成的HAL库架构,代码分层清晰。主要目录结构如下:
|
目录/文件 |
说明 |
|
python/ |
Python模型训练脚本(main.py训练, h5转tflite.py转换)+ H5/TFLite模型 |
|
MNIST/raw/ |
MNIST数据集原始文件(训练/测试图像与标签) |
|
Digit_Rec_keil/Core/Src/ |
STM32主程序(main.c)及外设初始化(dcmi/spi/i2c/dma/usart/gpio) |
|
Digit_Rec_keil/BSP/Camera/ |
摄像头驱动(OV7725/OV2640/OV5640/OV7670, 含寄存器配置表) |
|
Digit_Rec_keil/BSP/LCD_ST7789/ |
ST7789 LCD驱动(核心驱动/端口层/字体数据) |
|
Digit_Rec_keil/X-CUBE-AI/App/ |
AI推理引擎(app_x-cube-ai.c)+ 模型权重(network_data.c) |
|
Digit_Rec_keil/X-CUBE-AI/AI/Lib/ |
X-CUBE-AI运行时静态库(CM7专用) |
|
Digit_Rec_keil/MDK-ARM/ |
Keil MDK工程文件(.uvprojx) |
|
Digit_Rec_keil/*.ioc |
STM32CubeMX工程配置文件 |
七、演示视频
系统演示视频展示了实时手写数字识别的完整效果。演示内容包括:
- 上电启动,LCD显示摄像头实时画面
- 手写数字置于摄像头前,LCD右侧显示28×28预处理图像
- 系统每200ms执行一次AI推理,LCD左上角显示"RES:X"识别结果
- 4帧投票滤波后识别结果稳定,数字切换时无明显跳变
- 0~9各数字均可准确识别
图7-1 演示视频
八、总结
本项目成功实现了一套基于STM32H743与CNN的实时手写数字识别系统。通过OV7725摄像头采集图像,经裁剪、缩放、灰度化、二值化等预处理后,输入轻量CNN模型进行推理,在ST7789 LCD上实时显示识别结果。模型在MNIST测试集上达到99.02%的准确率,嵌入式部署后通过4帧投票滤波实现了稳定可靠的实时识别。
本项目是一个完整的端到端嵌入式AI应用案例,涵盖了数据集准备、模型训练(Python/TensorFlow)、模型转换(H5→TFLite)、嵌入式部署(STM32Cube.AI)和实时推理(X-CUBE-AI)的全流程,对学习嵌入式人工智能具有很好的参考价值。后续可扩展方向包括:支持更多字符识别、引入INT8量化加速推理、增加WiFi模块实现云端识别结果上传等。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
— END —

浙公网安备 33010602011771号