42 lines
1.1 KiB
Rust
42 lines
1.1 KiB
Rust
extern crate image;
|
|
|
|
use image::{Pixel, GenericImage, ImageResult, ImageError};
|
|
|
|
pub fn psnr<P: Pixel<Subpixel=u8>, T: GenericImage<Pixel=P>>(img1: &T, img2: &T) -> ImageResult<f64> {
|
|
|
|
let twenty_log10_max: f64 = 20.0 * (std::u32::MAX as f64).log10();
|
|
|
|
if img1.dimensions() != img2.dimensions() {
|
|
return Err(ImageError::DimensionError);
|
|
}
|
|
|
|
let mut mse = 0.0;
|
|
|
|
for x in 0 .. img1.dimensions().0 {
|
|
for y in 0 .. img1.dimensions().1 {
|
|
|
|
let p1 = img1.get_pixel(x, y).to_rgba();
|
|
let p2 = img2.get_pixel(x, y).to_rgba();
|
|
|
|
let dx = p1.data[0] as f64 - p2.data[0] as f64;
|
|
let dy = p1.data[1] as f64 - p2.data[1] as f64;
|
|
let dz = p1.data[2] as f64 - p2.data[2] as f64;
|
|
|
|
let dx = dx * dx;
|
|
let dy = dy * dy;
|
|
let dz = dz * dz;
|
|
|
|
mse += dx + dy + dz;
|
|
}
|
|
}
|
|
|
|
mse /= (img1.dimensions().0 * img1.dimensions().1 * 3) as f64;
|
|
Ok(twenty_log10_max - 10.0 * mse.log10())
|
|
}
|
|
|
|
pub fn psnr_files(path1: &str, path2: &str) -> ImageResult<f64> {
|
|
let img1 = image::open(path1)?;
|
|
let img2 = image::open(path2)?;
|
|
psnr(&img1, &img2)
|
|
}
|