pub trait Descriptor { fn info(&self) -> String { "Descriptor".to_string() } fn resize(&self, img: image::DynamicImage) -> image::DynamicImage { img.grayscale().thumbnail_exact(8, 8) } fn describe(&self, img: image::DynamicImage) -> u64; fn distance(&self, a: u64, b: u64) -> u64 { (a^b).count_ones().into() } } /// Interprets a 64-element array as an 8x8 matrix /// returns a nicely printable string fn print_matrix(array: [T; 64]) -> String { let mut output = String::new(); for x in 0..8 { for y in 0..8 { let element = format!("{:.2}", &array[x*8+y]); let element = format!("{:8}\t", element); output.push_str(&element); } output.push('\n'); } output } /// A struct representing a Discrete Cosine Transform descriptor /// Transforms an image into an 8x8 grayscale version, and transforms it /// into the frequency domain pub struct DCT { quantization_matrix: [u8; 64] } pub mod dct; // fn median64(values: &[T]) -> T { // let mut sorted_values = values.to_vec(); // sorted_values.sort(); // let len = sorted_values.len(); // sorted_values[len/2] // } // pub struct Median; // impl Descriptor for Median { // fn describe(&self, img: image::DynamicImage) -> u64 { // let img = self.resize(img); // let mut values: [u8; 64] = [0; 64]; // let mut i: usize = 0; // for (_, _, pix) in img.pixels() { // values[i] = pix[0]; // i = i+1; // } // let median = median64(&values); // let mut mask: u64 = 0; // img.save("debug.png").unwrap(); // for (_, _, pix) in img.pixels() { // if pix[0] > median { // mask += 1; // } // mask = mask << 1; // } // mask // } // }