R Lesson #8 - Matrix manipulation and images
This lesson describes how to display images, manually locate points, and perform matrix manipulations. First it is necessary to install the "jpeg" package (see the first line), which is not part of base R. Similar packages exist for tiff, png, etc.#install.packages("jpeg") # only need to run this once
> library(jpeg)
> # access help for the new package's functions:
> ?readJPEG
> ?writeJPEG
>
> # recall that matrices are stored column-by-column
> m <- matrix(0, nrow=4, ncol=3)
> m - 1:4 # recycled
[,1] [,2] [,3]
[1,] -1 -1 -1
[2,] -2 -2 -2
[3,] -3 -3 -3
[4,] -4 -4 -4
>
> Rlogo <- system.file("img", "Rlogo.jpg", package="jpeg")
> Rlogo # there are multiple ways of specifying paths in R
[1] "/Library/Frameworks/R.framework/Versions/3.2/Resources/library/jpeg/img/Rlogo.jpg"
> # drag and drop a file on the R console to see its path
> img <- readJPEG(Rlogo)
> typeof(img)
[1] "double"
> class(img) # array
[1] "array"
> dim(img) # width x height x channels (Red/Green/Blue, RGB)
[1] 76 100 3
> m <- img[,, 1] # select the red channel
# method 1 - rasterImage
> # color, fast, can interpolate, requires R 2.11+
> # no pseudo-coloring (e.g., rainbow())
> plot(NA, # initialize an empty plot window
+ xlim=c(1, dim(img)[2]), ylim=c(1, dim(img)[1]),
+ xlab="Column", ylab="Row")
> rasterImage(img,
+ 1, 1, dim(img)[2], dim(img)[1],
+ interpolate=FALSE)
>
> # method 2 - image
> # slow, no interpolation, axes [0 to 1]
> # single channel: grayscale or pseudocoloring
> a <- (img[,, 1] + img[,, 2] + img[,, 3])/3
> image(a, col=gray(seq(0, 1, 0.01))) # note the scales
>
> # method 3 - rect (pixels as individual rectanges)
> # color, slow, no interpolation, almost any R version
> row <- rep(rev(seq_len(dim(img)[1])), dim(img)[2])
> col <- rep(seq_len(dim(img)[2]), each=dim(img)[1])
> plot(NA, # initialize an empty plot window
+ xlim=range(col), ylim=range(row),
+ xlab="Column", ylab="Row")
> rect(col - 1, row - 1, col, row,
+ col=rgb(img[,, 1], img[,, 2], img[,, 3]),
+ border=NA)
# Standard element-wise math with matrices
> layout(matrix(1:4, nrow=2))
> image(a, main="default")
> image(a > 0.5, main="thresholded")
> image(a*a, main="squared")
> image(a - a*a, main="a - a*a")
> # Matrix specific functions
> layout(matrix(1:4, nrow=2))
> image(a, main="default")
> image(t(a), main="transpose")
> image(a %*% t(a), main="matrix multiplication")
> # Inverting a matrix can be performed with `solve`
> image(solve(a[, 1:76]), main="inverse")
>
> # default coloring in image is heat.colors(12)
> layout(matrix(c(1, 2, 3, 2), nrow=2))
> image(a, col=rainbow(100), main="default in rainbow")
> b <- rbind(a, a, a) # bind the matrix row-wise
> dim(b)
[1] 228 100
> image(b, col=topo.colors(100), main="rbind in topo")
> image(cbind(a, a), col=terrain.colors(100),
+ main="cbind in terrain")
> # note that cbind/rbind perform differently on arrays
>
> range(img)
[1] 0 1
> img <- 1 - img # 'inverse' colors
> plot(NA, xlim=range(col), ylim=range(row))
> rasterImage(img,
+ 1, 1, dim(img)[2], dim(img)[1],
+ interpolate=FALSE)
l <- locator()
> l
$x
[1] 36.40051 62.93799
$y
[1] 58.30686 37.11001
> abline(h=l$y, v=l$x)
> # get a temporary file name with extension ".jpeg"
> fname <- tempfile(fileext=".jpg")
> fname
[1] "/var/folders/qr/4756lm1n6fn5yz76pp13xl740000gn/T//Rtmp9njRNb/file318225a92551.jpg"
> # optionally write the image to a file
> writeJPEG(img, fname)
> # delete the temporary file with unlink
> #unlink(fname) # Caution: be careful with unlink!