Technical Details
技术细节
视频采集链路
OV5640 负责提供实时图像流,cam_capture 对像素同步、有效区域和数据节拍做整理。采集链路只负责提供稳定图像源,不直接喂给 LeNet。
SDRAM 帧缓存
SDRAM 位于 OV5640 与后续显示 / 识别链路之间。它吸收摄像头写入和 HDMI、ROI 裁剪读取之间的节拍差异,是从静态输入改造为实时视频系统的关键桥梁。
识别框与 ROI 读取
HDMI 链路负责实时显示和识别框绘制。识别区域从 SDRAM 读出的当前帧中截取,随后进入灰度、极性和尺寸标准化,而不是直接进入 CNN。
灰度、极性与对比度
早期识别异常的核心原因之一,是输入图像可能出现白底黑字或黑底白字不统一。系统通过背景估计、阈值去噪和增益拉伸,将最终输入统一为黑底亮字。
64x64 识别框与下采样
直接使用 32x32 识别框时,摄像头画面容易丢失笔画细节。改为 64x64 后先捕获更完整的数字,再用 2x2 平均下采样送入 LeNet,兼顾容错与原模型输入尺寸。
重心居中
LeNet 对输入位置偏移较敏感。mnist_recenter32 在写入 src_buf 前对数字重心做标准化,减少手写位置偏差带来的误判,尤其有助于 6、9、0、8 这类结构相近数字。
src_buf 最终输入缓存
src_buf 是标准化和居中之后的唯一 CNN 输入源。UART dump、Python golden model 和 LeNet 读取路径都围绕这块最终缓存对齐,避免出现“导出图像正确但 CNN 读到另一路 RAM”的问题。
LeNet 定点推理核心
CNN 侧使用 int16 权重、int24 bias 与 Q15 右移近似硬件定点行为。层间启动从简单 ready 信号改为真实 write_done 脉冲推进,保证下一层只在上一层输出写完后启动。
跨时钟域启动
标准化模块完成写入后产生 norm_ready,再通过 go_CDC_go 同步到 CNN 时钟域。这样 CNN 不会在 32x32 图像尚未写完时提前读取 src_buf。
HDMI 与 OSD 输出
HDMI 链路承担实时画面显示,并通过 digit_osd 与 draw_rectangle 叠加识别框、分类结果和调试状态,使工程从单纯推理模块变成完整可交互系统。
UART 调试通道
UART 用于导出 FPGA 实际 CNN 输入图像,配合 PC 端脚本复原 32x32 灰度图。它让调试从猜测分类结果,转为逐帧检查输入质量和硬件路径一致性。
Python Golden Model
Python 版本不是普通浮点网络,而是尽量模拟 FPGA 内部定点计算、截位、卷积与池化流程。它用于区分问题来自图像预处理、层间时序还是 CNN 前向计算本身。
Modules
硬件与工程组成
cam_capture
摄像头输入采集、像素同步与有效区域输出。
sdram_ctrl
视频帧缓存,衔接 OV5640、识别链路与 HDMI。
hdmi_ctrl
视频主控、OSD 叠加、识别框绘制和 UART 调试协调。
capture_lenet / capture_lenet_scaled2x
截取识别区域,并组织 64x64 到 32x32 的 CNN 输入图像。
mnist_recenter32
32x32 图像位置标准化与重心调整。
src_buf
标准化后最终 CNN 输入缓存。
lenet / cnn.v
LeNet 顶层控制、卷积、池化、ReLU、MAC 与层间启动时序。
lenet_roms / ram_blocks
权重 ROM、自定义 RAM 与 eLinx 平台适配。
go_CDC_go
跨时钟域启动脉冲同步。
digit_osd / draw_rectangle
显示识别框与最终分类结果。
Debugging
关键问题与调试闭环
灰度极性不统一
通过四角背景估计、自动极性判断、阈值去噪和增益拉伸,将输入统一为黑底亮字。
CNN 层间启动过早
把层间推进条件从 iterator.ready 改为真实 write_done 脉冲,避免下一层读取未写完的输出。
标准化后启动时机错误
将 CNN 启动源从 capture_ready 改为 norm_ready,并通过 CDC 同步到 CNN 时钟域。
src_buf 连接错误
统一串口 dump、Python 验证与 LeNet 实际读取的 RAM,解决图像正常但分类固定的问题。
Optimization
输入标准化与 6 / 9 分析
已验证有效的优化
- 64x64 识别框 -> 2x2 平均下采样 -> 32x32 CNN 输入。
- 自动极性判断,统一黑底亮字输入。
- soft recenter 与目标居中处理。
- 提高阈值并削弱弱连接对闭环数字的干扰。
6 / 9 仍较困难的原因
- 结构依赖闭环和竖笔,形态变化更敏感。
- LeNet 对位置和重心偏移较敏感。
- MNIST 训练分布与摄像头输入分布存在差异。
- 闭环过强时容易向 0 或 8 混淆。
Result
项目成果
Future Work
后续优化方向
当前系统已经具备较完整的实时识别能力,也建立了软硬件对齐的调试基础。后续重点可放在 6 / 9 专项测试、FPGA logits dump、多位置推理投票,以及面向摄像头输入分布的轻量微调。