1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::definitions::{Clamp, HasBlack, HasWhite, Image};
use crate::math::cast;
use conv::ValueInto;
use image::Pixel;
use rand::{rngs::StdRng, SeedableRng};
use rand_distr::{Distribution, Normal, Uniform};
pub fn gaussian_noise<P>(image: &Image<P>, mean: f64, stddev: f64, seed: u64) -> Image<P>
where
P: Pixel + 'static,
P::Subpixel: ValueInto<f64> + Clamp<f64>,
{
let mut out = image.clone();
gaussian_noise_mut(&mut out, mean, stddev, seed);
out
}
pub fn gaussian_noise_mut<P>(image: &mut Image<P>, mean: f64, stddev: f64, seed: u64)
where
P: Pixel + 'static,
P::Subpixel: ValueInto<f64> + Clamp<f64>,
{
let mut rng: StdRng = SeedableRng::seed_from_u64(seed);
let normal = Normal::new(mean, stddev).unwrap();
for p in image.pixels_mut() {
for c in p.channels_mut() {
let noise = normal.sample(&mut rng);
*c = P::Subpixel::clamp(cast(*c) + noise);
}
}
}
pub fn salt_and_pepper_noise<P>(image: &Image<P>, rate: f64, seed: u64) -> Image<P>
where
P: Pixel + HasBlack + HasWhite + 'static,
{
let mut out = image.clone();
salt_and_pepper_noise_mut(&mut out, rate, seed);
out
}
pub fn salt_and_pepper_noise_mut<P>(image: &mut Image<P>, rate: f64, seed: u64)
where
P: Pixel + HasBlack + HasWhite + 'static,
{
let mut rng: StdRng = SeedableRng::seed_from_u64(seed);
let uniform = Uniform::new(0.0, 1.0);
for p in image.pixels_mut() {
if uniform.sample(&mut rng) > rate {
continue;
}
let r = uniform.sample(&mut rng);
*p = if r >= 0.5 { P::white() } else { P::black() };
}
}
#[cfg(test)]
mod tests {
use super::*;
use image::GrayImage;
use test::{black_box, Bencher};
#[bench]
fn bench_gaussian_noise_mut(b: &mut Bencher) {
let mut image = GrayImage::new(100, 100);
b.iter(|| {
gaussian_noise_mut(&mut image, 30.0, 40.0, 1);
});
black_box(image);
}
#[bench]
fn bench_salt_and_pepper_noise_mut(b: &mut Bencher) {
let mut image = GrayImage::new(100, 100);
b.iter(|| {
salt_and_pepper_noise_mut(&mut image, 0.3, 1);
});
black_box(image);
}
}