output fixes
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
use image_similarity::descriptors::{DCT, Descriptor};
|
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 _};
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
struct Cfg {
|
struct Cfg {
|
||||||
path: String
|
path: String
|
||||||
@@ -31,7 +32,8 @@ fn main() {
|
|||||||
let img = image::open(cfg.path)
|
let img = image::open(cfg.path)
|
||||||
.expect("Unable to open file");
|
.expect("Unable to open file");
|
||||||
let phash: u64 = desc.describe(img);
|
let phash: u64 = desc.describe(img);
|
||||||
println!("{phash}\n{phash:b}");
|
debug!("Phash integer:\n{phash}");
|
||||||
|
debug!("Phash binary:\n{phash:b}");
|
||||||
let output = URL_SAFE_NO_PAD.encode(phash.to_be_bytes());
|
let output = URL_SAFE_NO_PAD.encode(phash.to_be_bytes());
|
||||||
println!("{output}")
|
println!("{output}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ use std::collections::HashMap;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
//Init all descriptors:
|
env_logger::init();
|
||||||
|
|
||||||
let desc = DCT::new();
|
let desc = DCT::new();
|
||||||
|
|
||||||
//Initialize hashmap, empty or from cached file:
|
//Initialize hashmap, empty or from cached file:
|
||||||
|
|||||||
+11
-13
@@ -1,12 +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};
|
use crate::descriptors::{Descriptor, DCT, print_matrix};
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
|
|
||||||
impl DCT {
|
impl DCT {
|
||||||
/// Returns a new DCT instance with a base quality DCT matrix.
|
/// Returns a new DCT instance with a base quality DCT matrix.
|
||||||
pub fn new() -> DCT {
|
pub fn new() -> DCT {
|
||||||
let base_quantization_matrix: [u8; 64] = [
|
let quantization_matrix: [u8; 64] = [
|
||||||
16, 11, 10, 16, 24, 40, 51, 61,
|
16, 11, 10, 16, 24, 40, 51, 61,
|
||||||
12, 12, 14, 19, 26, 58, 60, 55,
|
12, 12, 14, 19, 26, 58, 60, 55,
|
||||||
14, 13, 16, 24, 40, 57, 69, 56,
|
14, 13, 16, 24, 40, 57, 69, 56,
|
||||||
@@ -16,7 +17,7 @@ impl DCT {
|
|||||||
49, 64, 78, 8, 10, 12, 12, 101,
|
49, 64, 78, 8, 10, 12, 12, 101,
|
||||||
72, 92, 95, 9, 11, 10, 103, 99,
|
72, 92, 95, 9, 11, 10, 103, 99,
|
||||||
];
|
];
|
||||||
DCT { quantization_matrix: base_quantization_matrix }
|
DCT { quantization_matrix }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builds DCT with given quality value
|
// Builds DCT with given quality value
|
||||||
@@ -37,9 +38,7 @@ impl DCT {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dct(&self, img: image::DynamicImage) -> [f64; 64] {
|
fn dct(&self, img: image::DynamicImage) -> [f64; 64] {
|
||||||
//let qmatrix = self.quantization_matrix(self.quality);
|
|
||||||
//println!("Q-{} quantization matrix:\n{}", self.quality, print_matrix(qmatrix));
|
|
||||||
let mut dct_values: [f64; 64] = [0.0; 64];
|
let mut dct_values: [f64; 64] = [0.0; 64];
|
||||||
img.save("resize.png").expect("Error saving file");
|
img.save("resize.png").expect("Error saving file");
|
||||||
for u in 0..8 {
|
for u in 0..8 {
|
||||||
@@ -65,13 +64,12 @@ impl DCT {
|
|||||||
(y*v*PI/16.0).cos()
|
(y*v*PI/16.0).cos()
|
||||||
}
|
}
|
||||||
dct_values[k] = alpha * sum;
|
dct_values[k] = alpha * sum;
|
||||||
//println!{"{}", dct_values[k]}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dct_values
|
dct_values
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn idct(&self, dct_values: [f64; 64]) -> [u8; 64] {
|
fn idct(&self, dct_values: [f64; 64]) -> [u8; 64] {
|
||||||
let mut reconstructed: [u8; 64] = [0; 64];
|
let mut reconstructed: [u8; 64] = [0; 64];
|
||||||
for k in 0..64 {
|
for k in 0..64 {
|
||||||
let x = (k%8) as f64;
|
let x = (k%8) as f64;
|
||||||
@@ -107,24 +105,24 @@ impl Descriptor for DCT {
|
|||||||
fn describe(&self, img: image::DynamicImage) -> u64 {
|
fn describe(&self, img: image::DynamicImage) -> u64 {
|
||||||
let img = self.resize(img);
|
let img = self.resize(img);
|
||||||
let mut dct_values = self.dct(img);
|
let mut dct_values = self.dct(img);
|
||||||
println!("DCT-coefficients:\n {}", print_matrix(dct_values));
|
debug!("DCT-coefficients:\n {}", print_matrix(dct_values));
|
||||||
|
|
||||||
// Quantization:
|
// Quantization:
|
||||||
println!("Using quantization matrix:\n{}", print_matrix(self.quantization_matrix));
|
debug!("Using quantization matrix:\n{}", print_matrix(self.quantization_matrix));
|
||||||
for i in 0..64 {
|
for i in 0..64 {
|
||||||
dct_values[i] = (dct_values[i] / self.quantization_matrix[i] as f64).round();
|
dct_values[i] = (dct_values[i] / self.quantization_matrix[i] as f64).round();
|
||||||
}
|
}
|
||||||
println!("DCT-coefficients, quantized:\n {}", print_matrix(dct_values));
|
debug!("DCT-coefficients, quantized:\n {}", print_matrix(dct_values));
|
||||||
|
|
||||||
// De-quantization:
|
// De-quantization:
|
||||||
for i in 0..64 {
|
for i in 0..64 {
|
||||||
dct_values[i] = dct_values[i] * self.quantization_matrix[i] as f64;
|
dct_values[i] = dct_values[i] * self.quantization_matrix[i] as f64;
|
||||||
}
|
}
|
||||||
println!("DCT-coefficients, de-quantized:\n {}", print_matrix(dct_values));
|
debug!("DCT-coefficients, de-quantized:\n {}", print_matrix(dct_values));
|
||||||
|
|
||||||
// Reconstruction original pixel values:
|
// Reconstruction original pixel values:
|
||||||
let reconstructed = self.idct(dct_values);
|
let reconstructed = self.idct(dct_values);
|
||||||
println!("Reconstructed pixel values:\n{}", print_matrix(reconstructed));
|
debug!("Reconstructed pixel values:\n{}", print_matrix(reconstructed));
|
||||||
|
|
||||||
save_buffer(
|
save_buffer(
|
||||||
"reconstructed.png",
|
"reconstructed.png",
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ impl DescriptorStore {
|
|||||||
Ok(f) => rmp_serde::from_slice(&f).unwrap(),
|
Ok(f) => rmp_serde::from_slice(&f).unwrap(),
|
||||||
Err(_e) => HashMap::with_capacity(count),
|
Err(_e) => HashMap::with_capacity(count),
|
||||||
};
|
};
|
||||||
DescriptorStore { map: map }
|
DescriptorStore { map }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true iff the store already contains the key
|
/// Returns true iff the store already contains the key
|
||||||
|
|||||||
Reference in New Issue
Block a user