Files
digit-cracker/README.md
2025-10-29 21:28:43 +08:00

103 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 项目说明
本仓库提供一个基于 TypeScript 的命令行工具,用于识别带有双条干扰线的四位数字验证码。默认情况下,`train/` 目录用于训练,`valid/` 目录用于验证。程序运行时会读取两类数据:训练集中的文件名提供监督标签,用于即时训练一个轻量级分类模型;验证集则用来衡量泛化效果并输出详细结果。
## 环境要求
- Node.js 18 及以上版本(开发环境使用的是 Node.js v22
- 已安装的系统依赖:`sharp` 依赖 libvipsmacOS / Linux 上安装该库后方可正常编译
第一次运行前请确认项目目录下已执行:
```bash
npm install
```
该命令会安装以下主要依赖:
- `tesseract.js`:用于对比基准识别效果(未经过干扰线处理时的识别结果)。
- `sharp`:完成灰度化、归一化、阈值化、裁剪与缩放等图像预处理。
- `ts-node` / `typescript`:支持直接运行 TypeScript 源代码。
## 快速开始
默认使用 `train/` 训练,并在 `valid/` 上验证:
```bash
npm run ocr
```
如需指定数据集,可使用如下方式:
```bash
# 指定训练与验证目录
npm run ocr -- ./my-train ./my-valid
# 仅指定验证目录(训练仍使用默认 train/
npm run ocr -- ./my-valid
```
当仅提供一个自定义路径且该路径缺少标签(文件名不含四位数字)时,脚本会把它视作新的验证目录,同时保留默认训练集。命令执行结束后,终端会分别输出训练集与验证集的准确率、逐文件预测,以及 Tesseract.js 的识别结果以供对比。
## 工具工作流程
1. **扫描数据集**
按目录读取所有扩展名为 `.png``.jpg``.jpeg``.bmp` 的图片文件。文件名中的连续四位数字作为标签,若文件名缺少四位数字,则只生成预测,不计入准确率。
2. **图像预处理**
- 使用 `sharp` 将图片 resize 到固定高度120px保持纵横比。
- 转换为灰度图并做 normalize。
- 应用固定阈值生成二值化掩膜,用于定位数字区域与干扰线。
3. **分割四个数字**
- 统计每列、每行的黑色像素数量,找出真正包含数字墨迹的区域,并裁掉纯白边缘。
- 由于图片始终包含四个数字,横向等分为四段,再根据列统计结果向内收缩,确保裁剪框贴近数字并尽量避开干扰线。
- 对每个数字区域加入细小的边缘留白,并缩放到 `20×20` 像素,形成 400 维的浮点特征向量(像素值归一化到 0~1黑色越接近 1
4. **模型训练**
- 所有数字特征与文件名标签构成训练集。
- 使用自实现的多分类 softmax逻辑回归模型采用随机顺序的批量梯度下降训练 1000 个 epoch。由于数据量小且特征维度低训练耗时通常不足 1 秒。
5. **验证码识别与验证**
- 使用训练后的权重分别对训练集和验证集的四位数字进行推断。
- 根据标签统计准确率,并输出每张图片的预测详情。
- 同时调用一次 Tesseract.js未做特别预处理记录其识别文本方便与自训练模型对比。
## 目录结构
```
├── package.json npm 配置,包含运行脚本与依赖
├── tsconfig.json TypeScript 编译配置
├── src/
│ └── ocr.ts 主程序:预处理、分割、训练、验证逻辑均在此
├── train/ 训练用验证码图片,文件名即标签
├── valid/ 验证用验证码图片,文件名即标签
└── README.md 项目说明(本文档)
```
## 识别策略说明
- **利用文件名作为监督信号**:图片标签直接来自于文件名,不需要额外的标注文件,便于扩充数据集。
- **干扰线处理方式**:不是直接删除干扰线,而是通过对列/行墨迹统计裁剪出真正的数字区域。由于干扰线位置基本固定,且覆盖面积较窄,裁剪后得到的数字基本没有残留干扰线。
- **模型为何选择 Softmax**:数据量为几十张,模型复杂度越低越稳定。逻辑回归 + 400 维像素特征即可达到 100% 训练准确率,且推理速度极快。
- **Tesseract.js 调用**:保留这一步仅为记录传统 OCR 在原始图片上的表现,可作为质量对比或回归基线。
## 常见问题
| 问题 | 解决方案 |
| --- | --- |
| 运行时报 `Module not found: sharp` 或安装 `sharp` 失败 | 确认系统已安装 libvips。macOS 可使用 `brew install vips`Linux 可通过发行版包管理器安装。 |
| 输出中 `predicted``expected` 均为空 | 检查文件名是否包含连续四位数字,脚本只会对这样的文件进行训练和验证。 |
| 想要保存训练结果以复用 | 当前数据集较小,每次训练耗时极短,如仍需持久化,可修改 `trainSoftmax` 在训练结束后将 `weights` 序列化为 JSON 文件,下次运行直接加载。 |
| 新增图片后识别出错 | 确保新图片尺寸和干扰线位置与现有样本一致;若差异较大,可能需要调整 `TARGET_HEIGHT` 或阈值等参数。 |
## 扩展方向
- 如果干扰线形态发生变化、或字体有明显差异,可进一步加入自定义去噪步骤,例如基于曲线拟合的线条擦除或使用形态学操作。
- 若数据集显著扩大,可以将 softmax 替换为轻量级的卷积神经网络(可基于 TensorFlow.js但在当前数据规模下并非必要。
- 可以增加命令行参数,用于切换阈值、输出预测概率、导出训练权重等。
## 反馈
如需调整识别策略或扩展功能,可在 `src/ocr.ts` 中直接修改对应逻辑。代码整体结构保持模块化:数据加载 → 特征提取 → 训练 → 推理,便于在任一步骤插入新的处理流程。