calib_targets_core/
image.rs

1#[derive(Clone, Copy, Debug)]
2pub struct GrayImageView<'a> {
3    pub width: usize,
4    pub height: usize,
5    pub data: &'a [u8], // row-major, len = w*h
6}
7
8#[derive(Clone, Debug)]
9pub struct GrayImage {
10    pub width: usize,
11    pub height: usize,
12    pub data: Vec<u8>,
13}
14
15impl GrayImage {
16    pub fn view(&self) -> GrayImageView<'_> {
17        GrayImageView {
18            width: self.width,
19            height: self.height,
20            data: &self.data,
21        }
22    }
23}
24
25#[inline]
26fn get_gray(src: &GrayImageView<'_>, x: i32, y: i32) -> u8 {
27    if x < 0 || y < 0 || x >= src.width as i32 || y >= src.height as i32 {
28        return 0;
29    }
30    src.data[y as usize * src.width + x as usize]
31}
32
33#[inline]
34pub fn sample_bilinear(src: &GrayImageView<'_>, x: f32, y: f32) -> f32 {
35    let x0 = x.floor() as i32;
36    let y0 = y.floor() as i32;
37    let fx = x - x0 as f32;
38    let fy = y - y0 as f32;
39
40    let p00 = get_gray(src, x0, y0) as f32;
41    let p10 = get_gray(src, x0 + 1, y0) as f32;
42    let p01 = get_gray(src, x0, y0 + 1) as f32;
43    let p11 = get_gray(src, x0 + 1, y0 + 1) as f32;
44
45    let a = p00 + fx * (p10 - p00);
46    let b = p01 + fx * (p11 - p01);
47    a + fy * (b - a)
48}
49
50#[inline]
51pub fn sample_bilinear_fast(src: &GrayImageView<'_>, x: f32, y: f32) -> f32 {
52    let x0 = x.floor() as i32;
53    let y0 = y.floor() as i32;
54
55    if x0 < 0 || y0 < 0 || x0 + 1 >= src.width as i32 || y0 + 1 >= src.height as i32 {
56        return sample_bilinear(src, x, y);
57    }
58
59    let fx = x - x0 as f32;
60    let fy = y - y0 as f32;
61    let base = y0 as usize * src.width + x0 as usize;
62
63    let p00 = src.data[base] as f32;
64    let p10 = src.data[base + 1] as f32;
65    let p01 = src.data[base + src.width] as f32;
66    let p11 = src.data[base + src.width + 1] as f32;
67
68    let a = p00 + fx * (p10 - p00);
69    let b = p01 + fx * (p11 - p01);
70    a + fy * (b - a)
71}
72
73#[inline]
74pub fn sample_bilinear_u8(src: &GrayImageView<'_>, x: f32, y: f32) -> u8 {
75    sample_bilinear(src, x, y).clamp(0.0, 255.0) as u8
76}