diff --git a/src/bin/dctfilename.rs b/src/bin/dctfilename.rs index 2c59bb7..21a4ce4 100644 --- a/src/bin/dctfilename.rs +++ b/src/bin/dctfilename.rs @@ -1,4 +1,5 @@ -use image_similarity::descriptors::{Descriptor, DCT}; +//use image_similarity::descriptors::dct::DCT; +use image_similarity::descriptors::{DCT, Descriptor}; use std::env; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; diff --git a/src/bin/experiment.rs b/src/bin/experiment.rs index 76d2ad2..a17d45e 100644 --- a/src/bin/experiment.rs +++ b/src/bin/experiment.rs @@ -1,10 +1,11 @@ -use image_similarity::descriptors::{Descriptor, Median}; +use image_similarity::descriptors; +use image_similarity::descriptors::Descriptor; use std::collections::HashMap; use std::fs; fn main() { //Init all descriptors: - let desc = Median; + let desc = descriptors::dct::DCT::new(); //Initialize hashmap, empty or from cached file: let count = fs::read_dir("img").unwrap().count(); diff --git a/src/descriptors.rs b/src/descriptors/dct.rs similarity index 72% rename from src/descriptors.rs rename to src/descriptors/dct.rs index b7f419f..39b33e7 100644 --- a/src/descriptors.rs +++ b/src/descriptors/dct.rs @@ -1,77 +1,13 @@ use image::{save_buffer, GenericImageView}; use std::f64::consts::{PI, SQRT_2}; - -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() - } -} - -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 - } -} +use crate::descriptors::{Descriptor, print_matrix, DCT}; /// 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], -} - - -/// 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 { - output.push_str(&array[x*8+y].to_string()); - output.push_str(",\t"); - } - output.push('\n'); - } - output -} - - -// Define S such that if (Q < 50), then S = 5000/Q, else S = 200 – 2*Q. -// The output quantization matrix Ts[i,j] at each location of row i and column j is such that -// Ts[i,j] = floor((S * Tb[i,j] + 50) / 100) - +// pub struct DCT { +// quantization_matrix: [u8; 64], +// } impl DCT { pub fn new() -> DCT { @@ -196,4 +132,4 @@ impl Descriptor for DCT { } mask } -} +} \ No newline at end of file diff --git a/src/descriptors/mod.rs b/src/descriptors/mod.rs new file mode 100644 index 0000000..16e70f8 --- /dev/null +++ b/src/descriptors/mod.rs @@ -0,0 +1,64 @@ +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 { + output.push_str(&array[x*8+y].to_string()); + output.push_str(",\t"); + } + output.push('\n'); + } + output +} + +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 +// } +// }