Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/noise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,59 @@ where
}
}

/// Adds multiplicative speckle noise to an image with the given mean and standard deviation.
/// Noise can be added independently per channel for data augmentation, or just per pixel for
/// realistic sensor noise simulation.
pub fn speckle_noise<P>(
image: &Image<P>,
per_channel: bool,
mean: f64,
stddev: f64,
seed: u64,
) -> Image<P>
where
P: Pixel,
P::Subpixel: Into<f64> + Clamp<f64>,
{
let mut out = image.clone();
speckle_noise_mut(&mut out, per_channel, mean, stddev, seed);
out
}
#[doc=generate_mut_doc_comment!("speckle_noise")]
pub fn speckle_noise_mut<P>(
image: &mut Image<P>,
per_channel: bool,
mean: f64,
stddev: f64,
seed: u64,
) where
P: Pixel,
P::Subpixel: Into<f64> + Clamp<f64>,
{
let mut rng: StdRng = SeedableRng::seed_from_u64(seed);
let normal = Normal::new(mean, stddev).unwrap();

if per_channel {
// Add sampled noise per channel in each pixel
for p in image.pixels_mut() {
p.apply(|c| {
let noise = normal.sample(&mut rng);
let original = c.into();
P::Subpixel::clamp(original + original * noise)
});
}
} else {
// Use the same noise pattern for each channel
for p in image.pixels_mut() {
let noise = normal.sample(&mut rng);
p.apply(|c| {
let original = c.into();
P::Subpixel::clamp(original + original * noise)
});
}
}
}

/// Converts pixels to black or white at the given `rate` (between 0.0 and 1.0).
/// Black and white occur with equal probability.
pub fn salt_and_pepper_noise<P>(image: &Image<P>, rate: f64, seed: u64) -> Image<P>
Expand Down Expand Up @@ -84,4 +137,13 @@ mod benches {
});
black_box(image);
}

#[bench]
fn bench_speckle_noise_mut(b: &mut Bencher) {
let mut image = GrayImage::new(100, 100);
b.iter(|| {
speckle_noise_mut(&mut image, true, 0.0, 0.4, 1);
});
black_box(image);
}
}
Loading