image_hdr/
stretch.rs

1//! Apply basic histogram stretch to a linear image to make it viewable.
2
3use crate::extensions::NDArrayBuffer;
4use crate::Error;
5use image::DynamicImage;
6use rayon::prelude::*;
7
8fn scale_pixel(pixel: f32, min: f32, max: f32) -> f32 {
9    (pixel - min) * (1. / (max - min))
10}
11
12/// Contrast stretch (normalize) a given image.
13///
14/// # Errors
15/// - if image cannot be constructed from processed pixels.
16pub fn apply_histogram_stretch(image: &DynamicImage) -> Result<DynamicImage, Error> {
17    let mut buffer = image.to_nd_array_buffer();
18
19    let input_max_value = buffer.iter().copied().reduce(f32::max).unwrap_or(1.);
20    let input_min_value = buffer.iter().copied().reduce(f32::min).unwrap_or(0.);
21
22    buffer.par_iter_mut().for_each(|pixel| {
23        *pixel = scale_pixel(*pixel, input_min_value, input_max_value);
24    });
25
26    Ok(DynamicImage::from_nd_array_buffer(buffer))
27}