refactor into modules
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
use image::{save_buffer, GenericImageView};
|
||||
use std::f64::consts::{PI, SQRT_2};
|
||||
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],
|
||||
// }
|
||||
|
||||
impl DCT {
|
||||
pub fn new() -> DCT {
|
||||
let base_quantization_matrix: [u8; 64] = [
|
||||
16, 11, 10, 16, 24, 40, 51, 61,
|
||||
12, 12, 14, 19, 26, 58, 60, 55,
|
||||
14, 13, 16, 24, 40, 57, 69, 56,
|
||||
14, 17, 22, 29, 51, 87, 80, 62,
|
||||
18, 22, 37, 56, 6, 10, 103, 77,
|
||||
24, 35, 55, 64, 8, 10, 113, 92,
|
||||
49, 64, 78, 8, 10, 12, 12, 101,
|
||||
72, 92, 95, 9, 11, 10, 103, 99,
|
||||
];
|
||||
DCT { quantization_matrix: base_quantization_matrix }
|
||||
}
|
||||
pub fn quantization_matrix(&self, quality: u8) -> [u8; 64] {
|
||||
let mut quantization_matrix = self.quantization_matrix.clone();
|
||||
let scalar: f32 = match quality {
|
||||
1..=49 => 5000.0/quality as f32,
|
||||
50..=100 => 200.0 - 2.0*quality as f32,
|
||||
_ => 1.0 //TODO: error
|
||||
};
|
||||
for i in 0..64 {
|
||||
quantization_matrix[i] = ((scalar * self.quantization_matrix[i] as f32 + 50.0) / 100.0).floor() as u8;
|
||||
if quantization_matrix[i] == 0 {
|
||||
quantization_matrix[i] = 1;
|
||||
}
|
||||
}
|
||||
quantization_matrix
|
||||
}
|
||||
}
|
||||
|
||||
impl Descriptor for DCT {
|
||||
fn describe(&self, img: image::DynamicImage) -> u64 {
|
||||
let quality: u8 = 15;
|
||||
let qmatrix = self.quantization_matrix(quality);
|
||||
|
||||
println!("Base quantization matrix:\n{}", print_matrix(self.quantization_matrix));
|
||||
println!("Q-{} quantization matrix:\n{}", quality, print_matrix(qmatrix));
|
||||
let mut dct_values: [f64; 64] = [0.0; 64];
|
||||
let mut reconstructed: [u8; 64] = [0; 64];
|
||||
let img = self.resize(img);
|
||||
img.save("resize.png").expect("Error saving file");
|
||||
for u in 0..8 {
|
||||
for v in 0..8 {
|
||||
let k = (v*8)+u;
|
||||
let mut alpha = 0.25;
|
||||
if u == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
}
|
||||
if v == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
}
|
||||
let v: f64 = v as f64;
|
||||
let u: f64 = u as f64;
|
||||
let mut sum: f64 = 0.0;
|
||||
for (x, y, pix) in img.pixels() {
|
||||
let x: f64 = 1.0 + 2.0 * x as f64;
|
||||
let y: f64 = 1.0 + 2.0 * y as f64;
|
||||
let pixel = (pix[0] as i16 - 127) as f64;
|
||||
sum +=
|
||||
pixel *
|
||||
(x*u*PI/16.0).cos() *
|
||||
(y*v*PI/16.0).cos()
|
||||
}
|
||||
dct_values[k] = alpha * sum;
|
||||
//println!{"{}", dct_values[k]}
|
||||
}
|
||||
}
|
||||
println!("DCT-coefficients:\n {}", print_matrix(dct_values));
|
||||
// Quantization:
|
||||
for i in 0..64 {
|
||||
dct_values[i] = (dct_values[i] / qmatrix[i] as f64).round();
|
||||
}
|
||||
println!("DCT-coefficients, quantized:\n {}", print_matrix(dct_values));
|
||||
// De-quantization:
|
||||
for i in 0..64 {
|
||||
dct_values[i] = dct_values[i] * qmatrix[i] as f64;
|
||||
}
|
||||
println!("DCT-coefficients, de-quantized:\n {}", print_matrix(dct_values));
|
||||
for k in 0..64 {
|
||||
let x = (k%8) as f64;
|
||||
let y = (k/8) as f64;
|
||||
let mut sum = 0.0;
|
||||
for u in 0..8 {
|
||||
for v in 0..8 {
|
||||
let mut alpha = 1.0;
|
||||
if u == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
}
|
||||
if v == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
}
|
||||
let uv = (v*8)+u;
|
||||
let v = v as f64;
|
||||
let u = u as f64;
|
||||
sum +=
|
||||
alpha *
|
||||
dct_values[uv] *
|
||||
((2.0 * x + 1.0) * u * PI / 16.0).cos() *
|
||||
((2.0 * y + 1.0) * v * PI / 16.0).cos()
|
||||
}
|
||||
}
|
||||
sum = 127.0 + (0.25 * sum).round();
|
||||
//println!("Reconstructed pixel: {}", sum);
|
||||
reconstructed[k] = std::cmp::min(255_u8, sum as u8);
|
||||
}
|
||||
//println!("{}", print_matrix(reconstructed));
|
||||
save_buffer(
|
||||
"reconstructed.png",
|
||||
&reconstructed,
|
||||
8,
|
||||
8,
|
||||
image::ColorType::L8
|
||||
).expect("Error saving buffer");
|
||||
let mut mask: u64 = 0;
|
||||
for dct in dct_values {
|
||||
if dct > 0.0 {
|
||||
mask += 1
|
||||
}
|
||||
mask = mask << 1;
|
||||
}
|
||||
mask
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user