A pure-MoonBit OCR engine: BMP/PGM/PPM decoding, binarization, segmentation, feature extraction and nearest-neighbour classification of digits and letters.
图像 ──▶ 解码 ──▶ 二值化 ──▶ 分割 ──▶ 特征 ──▶ 分类 ──▶ 文本
(BMP/PGM/PPM) (Otsu/固定/自适应) (连通域+行分组+部件) (8×8 网格) (最近邻)| 阶段 | 模块 | 说明 |
|---|---|---|
| 图像模型 | image.mbt | Image、BT.601 rgb_to_gray |
| 解码 | bmp.mbt / pgm.mbt / ppm.mbt | parse_bmp、parse_pgm(P1/P2/P4/P5)、parse_ppm(P3/P6) |
| 二值化 | binarize.mbt | 固定阈值 / Otsu / 自适应 / Sauvola / Niblack |
| 矫正 | deskew.mbt | 投影直方图、图像旋转、倾斜检测与 deskew |
| 分割 | segment.mbt | 连通域、噪声过滤、行分组、部件装配 |
| 特征 | feature.mbt | 保持纵横比的 8×8 网格 |
| 分类 | classify.mbt | 汉明距离最近邻 / 加权 / 平移增强 |
| 识别 | recognize.mbt | 单行 / 多行 |
moon check # 类型检查
moon test # 运行全部测试(79 项)
moon bench # 运行基准moon run cmd/main -- Hello World 42 ABCabc 2026input:
Hello
World
42
ABCabc
2026
output: Hello
World
42
ABCabc
2026字母 A 数字 7
...##... .######.
..####.. .....##.
.##..##. ....##..
.##..##. ...##...
.######. ...##...
.##..##. ...##...
.##..##. ...##...
.##..##. ...##...| 阶段 | 平均耗时 |
|---|---|
| classify(单个字形) | ~10 µs |
| binarize_otsu | ~92 µs |
| connected_components | ~149 µs |
| binarize_adaptive | ~327 µs |
| binarize_niblack | ~496 µs |
| binarize_sauvola | ~529 µs |
| recognize_digits(12 位数字) | ~408 µs |
| recognize_text(3 行文本) | ~469 µs |
let img = parse_pgm(bytes) // 或 parse_bmp / parse_ppm
let gray = img.at(x, y) // 0..=255,0 为墨迹,255 为纸白let text = recognize_text(img) // 多行,以 "\n" 连接
let line = recognize_digits(img) // 单行let bin = binarize_otsu(img)
let adaptive = binarize_adaptive(img, window=15, c=20)
let sauvola = binarize_sauvola(img, window=15, k=0.3, r=128.0)
let niblack = binarize_niblack(img, window=15, k=-0.2)
let straight = deskew(img, max_angle=10.0, step=1.0)
let components = connected_components(bin)
let big = filter_small(components, min_area=8)
let lines = group_lines(big)
let glyphs = merge_parts(lines[0])
let grid = glyph_grid(bin, glyphs[0], size=8)
let m = classify(grid, alphanumeric_references()) // Match?
let w = classify_weighted(grid, alphanumeric_references(), center_weights())
let s = classify_shifted(grid, alphanumeric_references(), size=8)moon test # 79 项测试,全部通过pub struct Component {
x : Int
y : Int
w : Int
h : Int
area : Int
}pub struct Image {
width : Int
height : Int
pixels : Bytes
}fn rgb_to_gray(r : Int, g : Int, b : Int) -> IntInstall
Download zipA pure-MoonBit OCR engine: BMP/PGM/PPM decoding, binarization, segmentation, feature extraction and nearest-neighbour classification of digits and letters.