Added function mse
This commit is contained in:
parent
f6b458cafa
commit
a521e879f8
40
src/lib.rs
40
src/lib.rs
|
@ -1,13 +1,37 @@
|
||||||
extern crate image;
|
extern crate image;
|
||||||
|
|
||||||
use image::{Pixel, GenericImage, ImageResult};
|
use image::{Pixel, GenericImage, ImageResult, Rgba};
|
||||||
|
|
||||||
/// Compute a PSNR between two images.
|
/// Compute a MSE between an image and its color.
|
||||||
///
|
///
|
||||||
/// Will panic an error if the two images don't have the same size.
|
/// Will panic an error if the two images don't have the same size.
|
||||||
pub fn psnr<P: Pixel<Subpixel=u8>, T: GenericImage<Pixel=P>>(img1: &T, img2: &T) -> f64 {
|
pub fn mse_color<P: Pixel<Subpixel=u8>, T: GenericImage<Pixel=P>>(img: &T, color: &Rgba<u8>) -> f64 {
|
||||||
|
|
||||||
let twenty_log10_max: f64 = 20.0 * (std::u8::MAX as f64).log10();
|
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<P: Pixel<Subpixel=u8>, T: GenericImage<Pixel=P>>(img1: &T, img2: &T) -> f64 {
|
||||||
|
|
||||||
assert_eq!(img1.dimensions(), img2.dimensions());
|
assert_eq!(img1.dimensions(), img2.dimensions());
|
||||||
|
|
||||||
|
@ -31,8 +55,12 @@ pub fn psnr<P: Pixel<Subpixel=u8>, T: GenericImage<Pixel=P>>(img1: &T, img2: &T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mse /= (img1.dimensions().0 * img1.dimensions().1 * 3) as f64;
|
mse / (img1.dimensions().0 * img1.dimensions().1 * 3) as f64
|
||||||
twenty_log10_max - 10.0 * mse.log10()
|
}
|
||||||
|
|
||||||
|
pub fn psnr<P: Pixel<Subpixel=u8>, T: GenericImage<Pixel=P>>(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<f64> {
|
pub fn psnr_files(path1: &str, path2: &str) -> ImageResult<f64> {
|
||||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -11,24 +11,32 @@ fn psnr_dir(path1: &str, path2: &str) -> Vec<(String, ImageResult<f64>)> {
|
||||||
let mut dirs1: Vec<_> = fs::read_dir(path1).unwrap()
|
let mut dirs1: Vec<_> = fs::read_dir(path1).unwrap()
|
||||||
.map(|x|x.unwrap())
|
.map(|x|x.unwrap())
|
||||||
.filter(|x| x.file_name().into_string().unwrap().ends_with(".png"))
|
.filter(|x| x.file_name().into_string().unwrap().ends_with(".png"))
|
||||||
|
.map(|x| x.file_name().to_owned().into_string().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut dirs2: Vec<_> = fs::read_dir(path2).unwrap()
|
let metadata = fs::metadata(path2).unwrap();
|
||||||
|
|
||||||
|
let mut dirs2: Vec<_> = if metadata.is_dir() {
|
||||||
|
fs::read_dir(path2).unwrap()
|
||||||
.map(|x|x.unwrap())
|
.map(|x|x.unwrap())
|
||||||
.filter(|x| x.file_name().into_string().unwrap().ends_with(".png"))
|
.filter(|x| x.file_name().into_string().unwrap().ends_with(".png"))
|
||||||
.collect();
|
.map(|x| x.file_name().to_owned().into_string().unwrap())
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
vec![path2.to_owned()]
|
||||||
|
};
|
||||||
|
|
||||||
dirs1.sort_by_key(|x| x.file_name());
|
dirs1.sort();
|
||||||
dirs2.sort_by_key(|x| x.file_name());
|
dirs2.sort();
|
||||||
|
|
||||||
let mut res = vec!();
|
let mut res = vec!();
|
||||||
|
|
||||||
for file in dirs1 {
|
for file in dirs1 {
|
||||||
let p1 = path1.to_owned() + &file.file_name().to_owned().into_string().unwrap();
|
let p1 = path1.to_owned() + &file;
|
||||||
let p2 = path2.to_owned() + &file.file_name().to_owned().into_string().unwrap();
|
let p2 = if dirs2.len() != 1 { path2.to_owned() + &file } else { path2.to_owned() };
|
||||||
let psnr = psnr_files(&p1, &p2);
|
let psnr = psnr_files(&p1, &p2);
|
||||||
|
|
||||||
let elt = (file.file_name().to_owned().into_string().unwrap(), psnr.unwrap());
|
let elt = (file, psnr.unwrap());
|
||||||
println!("{} {}", elt.0, elt.1);
|
println!("{} {}", elt.0, elt.1);
|
||||||
res.push((elt.0, Ok(elt.1)));
|
res.push((elt.0, Ok(elt.1)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue