# Let’s Add Some More Noise

Like in my yesterday’s post mentioned, there are more kinds of noise. So let’s first load today’s picture and then add some multiplicative noise!

library(jpeg)
pigeonBW <- pigeon[,,1]
plot(as.raster(pigeonBW))


Oh look it’s a pigeon on a lantern. I wonder what this little guy was thinking? But let’s not dwell on this. Rather let’s think how we can scramble up this picture!
I will first try multiplicative normal distributed noise, which is pretty straight forward, if you followed yesterday’s post.

set.seed(1)
pigeonNormalNoise <- pigeonBW * (1 + rnorm(length(pigeonBW), sd = sd(pigeonBW)))
pigeonNormalNoise[pigeonNormalNoise > 1] <- 1
pigeonNormalNoise[pigeonNormalNoise < 0] <- 0
plot(as.raster(pigeonNormalNoise))


Can you see the difference to the additive noise from yesterday? Indeed the darker areas of the pictures seem nearly untouched from the noise. That’s because the intensity of the noise is now dependent on the intensity of the pixel. And intensity is what dark pixels are lacking… So to speak.

But it’s really annoying and redundant to have to write the same stuff over and over again, isn’t it? So let’s do, what a Computer Scientist is best in. Let’s generalize some methods.
But where to start?

In my view it would be useful to have some kind of an (black and white) image class, which saves the image and operations on it. Hence the process would also be reproducible, which is always nice.

imageBW <- setClass("imageBW", slots=list(original="matrix", current="matrix", operations="list"))
imageBWFromJpeg <-function(pathToJpeg){
require(jpeg)
imageBW <- image[,,1]
return(new("imageBW", original = imageBW, current = imageBW, operations = list()))
}
plot.imageBW <- function(object){
plot(as.raster(object@current))}


As an illustration I also overwrote the default plot function. This makes our lives even easier. In the next step I’ll implement the different noise functions. There are probably more generalized ways of doing so, but for now this will suffice. I also haven’t come up with a good way of storing the done operations yet. So I’ll probably also do that another day.

cropPixels<- function(object){
object@current[object@current > 1] <- 1
object@current[object@current < 0] <- 0
return(object)
}
slot(object, "current") <- slot(object, "current") +
runif(length(slot(object, "current")), min = -1, max = 1)
return(cropPixels(object))
}
addNormalNoise <- function(object, sd = NULL){
if(is.null(sd)){
object@current <- object@current + rnorm(length(object@current), sd = sd(object@current))
}else{
object@current <- object@current + rnorm(length(object@current), sd = sd)
}
return(cropPixels(object))
}
multiplyUnifNoise <- function(object){
object@current <- object@current * (1 + runif(length(object@current), min = -1, max = 1))
return(cropPixels(object))
}
multiplyNormalNoise <- function(object, sd = NULL){
if(is.null(sd)){
object@current <- object@current * ( 1 + rnorm(length(object@current),
sd = sd(object@current)))
}else{
object@current <- object@current * ( 1 + rnorm(length(object@current),
sd = sd))
}
return(cropPixels(object))
}


For the future I would also like to have this working with infix operators. Meaning that I could do stuff like image <- image + normalNoise(...) or image <- image * (1 + normalNoise(...)) so that I have a neat little grammar for working with images. However for the moment those functions will do the job. Now let us make use of the newly implemented methods and add a lot of noise to the picture.

image <- imageBWFromJpeg("pigeon.jpg")
image <- multiplyUnifNoise(image)