In this document, we will blur out the face of Teddy Roosevelt in an image of Mt. Rushmore (sorry, Teddy). This example is taken from Matloff - The Art of R Programming.
We will need the pixmap
package.
install.packages("pixmap")
library(pixmap)
Download the file mtrush1.pgm
from the course website
and move it to your working directory. Then load it as follows:
mtrush1 <- read.pnm("mtrush1.pgm")
str(mtrush1)
## Formal class 'pixmapGrey' [package "pixmap"] with 6 slots
## ..@ grey : num [1:194, 1:259] 0.278 0.263 0.239 0.212 0.192 ...
## ..@ channels: chr "grey"
## ..@ size : int [1:2] 194 259
## ..@ cellres : num [1:2] 1 1
## ..@ bbox : num [1:4] 0 0 259 194
## ..@ bbcent : logi FALSE
The str
function gives the “structure” of
mtrush1
. We see that mtrush1@grey
is a \(194\times 259\) numeric matrix.
is.matrix(mtrush1@grey)
## [1] TRUE
dim(mtrush1@grey)
## [1] 194 259
This matrix encodes a picture of Mt. Rushmore, which can be seen by
plotting the mtrush1
object:
plot(mtrush1)
The top left \(5\times 5\) corner of the matrix is given below:
mtrush1@grey[1:5, 1:5]
## [,1] [,2] [,3] [,4] [,5]
## [1,] 0.2784314 0.2588235 0.2431373 0.2549020 0.2784314
## [2,] 0.2627451 0.2470588 0.2352941 0.2431373 0.2627451
## [3,] 0.2392157 0.2274510 0.2196078 0.2274510 0.2392157
## [4,] 0.2117647 0.2117647 0.2078431 0.2117647 0.2156863
## [5,] 0.1921569 0.2000000 0.2039216 0.2039216 0.2000000
Note that all the values are between 0 and 1. A value of 0 indicates a black pixel and 1 indicates a white pixel. Hence this greyscale image is represented by a matrix of values between 0 and 1.
We can blur out the face of the 26th U.S. president as follows.
First, create a copy of the object called mtrush_blur
.
mtrush_blur <- mtrush1
The coordinates of Teddy’s face range from 84 to 163 on the \(y\)-axis and 135 to 177 on the \(x\)-axis. Let’s set up these coordinates in code.
y <- 84:163
x <- 135:177
y_len <- length(y)
x_len <- length(x)
Now we will generate a matrix of random noise. Remember that
runif(n)
generates a vector of \(n\) random values between 0 and 1. We want
y_len * x_len
random values in total, to cover up Teddy’s
face.
noise <- runif(y_len * x_len) # generate the noise
noise_mx <- matrix(noise, nrow=y_len, ncol=x_len) # form a noise matrix
mtrush_blur@grey[y, x] <- noise_mx
plot(mtrush_blur)
And he’s gone!
The above perhaps blurs him too much. We can control the amount of noise to add to the image by adjusting the weight of the noise.
We will continue to use noise_mx
but this time take a
weighted average between the noise and the true pixel value:
mtrush_blur@grey[y, x] <- mtrush1@grey[y, x] * 0.55 + noise_mx * 0.45
plot(mtrush_blur)
Now the image is only partially blurred; noise is added but you can still discern his face. By adjusting the numbers \(0.55\) and \(1-0.55 = 0.45\), you can control how much to blur the image.