#[derive(Copy, Clone, Debug)]
pub struct Patch {
center : (f64, f64),
n : usize,
color : u8,
extension : (usize, usize),
last_pos : (usize, usize)
}
impl Patch {
pub fn new(center : (usize, usize), color : u8) -> Self {
let center = (center.0 as f64, center.1 as f64);
let color = color;
let n = 1;
let extension = (0, 0);
let last_pos = (0, 0);
Self{ center, n, color, extension, last_pos }
}
pub fn increment(&mut self, pos: (usize, usize), color : u8) {
assert!(pos.0 >= self.center.0 as usize || pos.1 >= self.center.1 as usize, "New pixel smaller than current center");
assert!(pos.0 >= self.last_pos.0 || pos.1 >= self.last_pos.1 as usize, "New position smaller than previous position");
self.n += 1;
let n = self.n as f64;
let dist_y = pos.0 as f64 - self.center.0;
let dist_x = pos.1 as f64 - self.center.1;
self.center.0 = (1./n) * dist_y + ((n-1.)/n) * self.center.0;
self.center.1 = (1./n) * dist_x + ((n-1.)/n) * self.center.1;
self.color = ((1./n)*color as f64 + (self.color as f64)*(n-1.)/n) as u8;
if dist_y > self.extension.0 as f64 {
self.extension.0 = dist_y as usize;
}
if dist_x > self.extension.1 as f64 {
self.extension.1 = dist_x as usize
}
self.last_pos = pos;
}
pub fn enclosing_rect(&self) -> ((usize, usize), (usize, usize)) {
let tl_y = (self.center.0 - self.extension.0 as f64).max(0.0);
let tl_x = (self.center.1 - self.extension.1 as f64).max(0.0);
let tl_yu = (tl_y as usize).min(self.last_pos.0);
let tl_xu = (tl_x as usize).min(self.last_pos.1);
let h = 2 * self.extension.0;
let w = 2 * self.extension.1;
((tl_yu, tl_xu), (h, w))
}
pub fn update(&mut self, _img : &[u8]) {
unimplemented!()
}
pub fn color(&self) -> u8 {
self.color
}
pub fn center(&self) -> (f64, f64) {
self.center
}
pub fn dist(&self, coord : (usize, usize)) -> f64 {
((self.center.0 - coord.0 as f64).powf(2.) +
(self.center.1 - coord.1 as f64).powf(2.)).sqrt()
}
}
#[derive(Clone, Debug)]
pub struct PatchGroup {
patches : Vec<Patch>,
threshold : u8,
dim : (usize, usize)
}
impl PatchGroup {
pub fn segment(img : &[u8], ncols : usize, threshold : u8) -> Self {
let mut patches = Vec::new();
for (i, px) in img.iter().enumerate() {
let r = i / ncols;
let c = i % ncols;
if i == 0 {
patches.push(Patch::new((r, c), *px));
} else {
let last_patch = &mut patches.last_mut().unwrap();
if last_patch.color() - px < threshold {
last_patch.increment((r, c), *px);
} else {
let mut any_close = false;
if r >= 2 && c >= 2 {
for prev_patch in patches.iter_mut().rev() {
let close_row = prev_patch.last_pos.0 - r <= 2;
let close_col = prev_patch.last_pos.1 - c <= 2;
if (close_row || close_col) && prev_patch.color() - px < threshold {
if !any_close {
any_close = true;
prev_patch.increment((r, c), *px);
}
}
}
}
if !any_close {
patches.push(Patch::new((r, c), *px));
}
}
}
}
Self{ patches, threshold, dim : (img.len() / ncols, ncols) }
}
pub fn patches(&self) -> &[Patch] {
&self.patches[..]
}
}
#[test]
fn patch() {
}