Skip to main content

rec_check/
rec_check.rs

1//! 识别检查:载入识别模型,逐个读 PPM(P6,8 位 RGB)行图,打印识别文字、置信度和耗时。
2//!     cargo run --profile release-fast -p pagesift-ocr --example rec_check -- <模型目录> <行图.ppm>...
3use std::time::Instant;
4
5/// 最小的 P6 PPM 读取:头是 "P6 宽 高 255"(空白分隔,可有 # 注释),之后紧跟 RGB 数据。
6fn read_ppm(path: &str) -> pagesift_ocr::Image {
7    let b = std::fs::read(path).unwrap_or_else(|e| panic!("读 {path} 失败:{e}"));
8    let mut fields = Vec::new();
9    let mut i = 0;
10    while fields.len() < 4 {
11        while b[i].is_ascii_whitespace() {
12            i += 1;
13        }
14        if b[i] == b'#' {
15            while b[i] != b'\n' {
16                i += 1;
17            }
18            continue;
19        }
20        let s = i;
21        while !b[i].is_ascii_whitespace() {
22            i += 1;
23        }
24        fields.push(String::from_utf8_lossy(&b[s..i]).into_owned());
25    }
26    assert_eq!(fields[0], "P6", "{path} 不是 P6 PPM");
27    assert_eq!(fields[3], "255", "{path} 不是 8 位");
28    let (w, h): (usize, usize) = (fields[1].parse().unwrap(), fields[2].parse().unwrap());
29    let data = b[i + 1..i + 1 + w * h * 3].to_vec();
30    pagesift_ocr::Image {
31        width: w,
32        height: h,
33        channels: 3,
34        data,
35    }
36}
37
38fn main() {
39    let a: Vec<String> = std::env::args().skip(1).collect();
40    let t = Instant::now();
41    let rec = pagesift_ocr::rec::Rec::load(std::path::Path::new(&a[0])).unwrap();
42    println!("载入 {:.0} ms", t.elapsed().as_secs_f64() * 1e3);
43    for p in &a[1..] {
44        let img = read_ppm(p);
45        let t = Instant::now();
46        let (text, score) = rec.recognize(&img).unwrap();
47        let ms = t.elapsed().as_secs_f64() * 1e3;
48        let name = std::path::Path::new(p)
49            .file_name()
50            .unwrap()
51            .to_string_lossy();
52        println!(
53            "{name}\t{}x{}\t{ms:.0} ms\t{score:.3}\t{text}",
54            img.width, img.height
55        );
56    }
57}