refactor into modules

This commit is contained in:
2024-05-06 23:12:14 +02:00
parent dcf4be921c
commit 4c55afa1f4
4 changed files with 74 additions and 72 deletions
+2 -1
View File
@@ -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 std::env;
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
+3 -2
View File
@@ -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::collections::HashMap;
use std::fs; use std::fs;
fn main() { fn main() {
//Init all descriptors: //Init all descriptors:
let desc = Median; let desc = descriptors::dct::DCT::new();
//Initialize hashmap, empty or from cached file: //Initialize hashmap, empty or from cached file:
let count = fs::read_dir("img").unwrap().count(); let count = fs::read_dir("img").unwrap().count();
+4 -68
View File
@@ -1,77 +1,13 @@
use image::{save_buffer, GenericImageView}; use image::{save_buffer, GenericImageView};
use std::f64::consts::{PI, SQRT_2}; use std::f64::consts::{PI, SQRT_2};
use crate::descriptors::{Descriptor, print_matrix, DCT};
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<T: Ord + Copy>(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
}
}
/// A struct representing a Discrete Cosine Transform descriptor /// A struct representing a Discrete Cosine Transform descriptor
/// Transforms an image into an 8x8 grayscale version, and transforms it /// Transforms an image into an 8x8 grayscale version, and transforms it
/// into the frequency domain /// into the frequency domain
pub struct DCT { // pub struct DCT {
quantization_matrix: [u8; 64], // quantization_matrix: [u8; 64],
} // }
/// Interprets a 64-element array as an 8x8 matrix
/// returns a nicely printable string
fn print_matrix<T: ToString>(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)
impl DCT { impl DCT {
pub fn new() -> DCT { pub fn new() -> DCT {
+64
View File
@@ -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<T: ToString>(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<T: Ord + Copy>(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
// }
// }