From 659b53ed5cba9a17b7b1724fcba17031aa2a835a Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Sun, 12 May 2024 14:37:41 +0200 Subject: [PATCH] DCT mask calculation updated --- src/bin/dctfilename.rs | 2 +- src/descriptors/dct.rs | 66 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/bin/dctfilename.rs b/src/bin/dctfilename.rs index 931ced6..0641c45 100644 --- a/src/bin/dctfilename.rs +++ b/src/bin/dctfilename.rs @@ -33,7 +33,7 @@ fn main() { .expect("Unable to open file"); let phash: u64 = desc.describe(&img); debug!("Phash integer:\n{phash}"); - debug!("Phash binary:\n{phash:b}"); + debug!("Phash binary:\n{phash:064b}"); let output = URL_SAFE_NO_PAD.encode(phash.to_be_bytes()); println!("{output}") } diff --git a/src/descriptors/dct.rs b/src/descriptors/dct.rs index 1244af9..d6835fa 100644 --- a/src/descriptors/dct.rs +++ b/src/descriptors/dct.rs @@ -107,7 +107,7 @@ impl Descriptor for DCT { debug!("DCT-coefficients:\n {}", print_matrix(dct_values)); // Quantization: - debug!("Using quantization matrix:\n{}", print_matrix(self.quantization_matrix)); + //debug!("Using quantization matrix:\n{}", print_matrix(self.quantization_matrix)); for i in 0..64 { dct_values[i] = (dct_values[i] / self.quantization_matrix[i] as f64).round(); } @@ -119,11 +119,10 @@ impl Descriptor for DCT { for i in 0..64 { dct_values[i] = dct_values[i] * self.quantization_matrix[i] as f64; } - debug!("DCT-coefficients, de-quantized:\n {}", print_matrix(dct_values)); + //debug!("DCT-coefficients, de-quantized:\n {}", print_matrix(dct_values)); // Reconstruction original pixel values: let reconstructed = self.idct(dct_values); - debug!("Reconstructed pixel values:\n{}", print_matrix(reconstructed)); save_buffer( "reconstructed.png", @@ -135,13 +134,64 @@ impl Descriptor for DCT { } // Calculating descriptor from dct values: - let mut mask: u64 = 0; - for dct in dct_values { - if dct > 0.0 { - mask += 1 + + // Zigzag order for our flattened array, + // first 28 elements only + let zigzag: [usize; 28] = [ + 0, + 1, 8, + 16, 9, 2, + 3, 10, 17, 24, + 32, 25, 18, 11, 4, + 5, 12, 19, 26, 33, 40, + 48, 41, 34, 27, 20, 13, 6, + ]; + + // Mask that indicates if a dct coefficient is positive or negative + // By convention, when sign bit is 1, number is negative + let mut sign_mask: u64 = 0; + // If first horizontal AC coefficient is negative + // This might account for horizontal flips when applied to all horizontal coefficients. + let sign_mult = dct_values[1].signum(); + + // Mask that indicates if a coefficient is bigger or smaller than previous in order + let mut pearson_mask: u64 = 0; + let mut prev = dct_values[0]; + + + for i in zigzag { + let cur = dct_values[i]; + if cur > prev { + pearson_mask += 1; } - mask = mask << 1; + prev = cur; + + let signum = dct_values[i].signum(); + // Only multiply sign if dct-coefficient contains a horizontal component. + if + i % 8 != 0 && sign_mult * signum < 0.0 + || + signum < 0.0 + { + sign_mask += 1; + } + + // Shift masks + sign_mask = sign_mask << 1; + pearson_mask = pearson_mask << 1; } + debug!("Sign mask: {:028b}", sign_mask); + debug!("Pearson mask: {:028b}", pearson_mask); + + let mut mask = sign_mask; + debug!("Mask: {:064b}", mask); + mask = mask << 28; + debug!("Mask: {:064b}", mask); + mask += pearson_mask; + debug!("Mask: {:064b}", mask); + mask = mask << 8; + debug!("Mask: {:064b}", mask); + // TODO: Do something with these last 8 bits. mask } } \ No newline at end of file