extern crate image; use image::{Pixel, GenericImage, ImageResult, Rgba}; /// Compute a MSE between an image and its color. /// /// Will panic an error if the two images don't have the same size. pub fn mse_color, T: GenericImage>(img: &T, color: &Rgba) -> f64 { let mut mse = 0.0; for x in 0 .. img.dimensions().0 { for y in 0 .. img.dimensions().1 { let p1 = img.get_pixel(x, y).to_rgba(); let dx = p1.data[0] as f64 - color.data[0] as f64; let dy = p1.data[1] as f64 - color.data[1] as f64; let dz = p1.data[2] as f64 - color.data[2] as f64; let dx = dx * dx; let dy = dy * dy; let dz = dz * dz; mse += dx + dy + dz; } } mse / (img.dimensions().0 * img.dimensions().1 * 3) as f64 } /// Compute a MSE between two images. /// /// Will panic an error if the two images don't have the same size. pub fn mse, T: GenericImage>(img1: &T, img2: &T) -> f64 { assert_eq!(img1.dimensions(), img2.dimensions()); 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 } pub fn psnr, T: GenericImage>(img1: &T, img2: &T) -> f64 { let twenty_log10_max: f64 = 20.0 * (std::u8::MAX as f64).log10(); twenty_log10_max - 10.0 * mse(img1, img2).log10() } pub fn psnr_files(path1: &str, path2: &str) -> ImageResult { let img1 = image::open(path1)?; let img2 = image::open(path2)?; Ok(psnr(&img1, &img2)) }