use std::path::PathBuf;
use bobine::rapid_ocr::OcrLine;
use bobine::rapid_table::RapidTable;
fn temp_dir() -> PathBuf {
std::env::temp_dir().join("bobine_table_test")
}
fn render_table_image() -> (image::DynamicImage, [[f32; 2]; 4]) {
let w = 400u32;
let h = 200u32;
let mut img = image::RgbImage::from_pixel(w, h, image::Rgb([255, 255, 255]));
for y in 0..h {
for x in 0..w {
if y == 0 || y == 99 || y == 199 || x == 0 || x == 199 || x == 399 {
img.put_pixel(x, y, image::Rgb([0, 0, 0]));
}
}
}
let cells = [(10u32, 20u32), (210, 20), (10, 120), (210, 120)];
for (cx, cy) in cells {
for dy in 0..40u32 {
for dx in 0..150u32 {
img.put_pixel(cx + dx, cy + dy, image::Rgb([30, 30, 30]));
}
}
}
(
image::DynamicImage::ImageRgb8(img),
[[0.0, 0.0], [400.0, 0.0], [400.0, 200.0], [0.0, 200.0]],
)
}
fn ocr_line(x0: f32, y0: f32, x1: f32, y1: f32, text: &str) -> OcrLine {
OcrLine {
box_points: [[x0, y0], [x1, y0], [x1, y1], [x0, y1]],
text: text.to_string(),
confidence: 0.95,
}
}
#[test]
fn table_model_load_and_recognize() {
let cache = temp_dir().join("cache");
std::fs::create_dir_all(&cache).unwrap();
let img_lines = render_table_image();
let lines = vec![
ocr_line(10.0, 20.0, 160.0, 60.0, "Name"),
ocr_line(210.0, 20.0, 360.0, 60.0, "Value"),
ocr_line(10.0, 120.0, 160.0, 160.0, "alpha"),
ocr_line(210.0, 120.0, 360.0, 160.0, "42"),
];
let mut engine = bobine::OnnxEngine::new(&bobine::ConverterConfig::default(), &cache);
engine.set_table_model(
&bobine::rapid_table::download_slanet_plus(&cache).expect("model download"),
);
let html = engine
.recognize_table(&img_lines.0, &lines)
.expect("recognize_table failed")
.expect("no cells decoded");
assert!(html.contains("<table"), "{html}");
assert!(html.contains("</tr>"), "{html}");
eprintln!("HTML: {html}");
let gfm = bobine::html_tables_to_gfm(&html);
assert!(gfm.contains('|'), "{gfm}");
}