Introduction:

One of the most useful applications for linear algebra in data science is image manipulation. We often need to compress, expand, warp, skew, etc. images. To do so, we left multiply a transformation matrix by each of the point vectors.
For this assignment, build the first letters for both your first and last name using point plots in R.

Then, write R code that will left multiply (%>%) a square matrix (x) against each of the vectors of points (y). Initially, that square matrix will be the Identity matrix.

Use a loop that changes the transformation matrix incrementally to demonstrate 1) shear, 2) scaling, 3) rotation , and 4) projection in animated fashion.

Method

  1. Create Letters
w_coord <- subset(hershey, font == 'rowmans' & char == 'W')
w_coord2 <- w_coord %>%
    group_by(stroke) %>%
    do(as_tibble(approx(.)))

a_coord <- subset(hershey, font == 'rowmans' & char == 'A')
a_coord2 <- a_coord %>%
     group_by(stroke) %>%
     do(as_tibble(approx(.)))

a_coord2$x <- a_coord2$x + 15
initials <- rbind(w_coord2, a_coord2)

initials <- initials %>% ungroup() %>% select(-stroke)

plot(initials$y ~ initials$x, pch = 19)

  1. Create a function that creates a transformation matrix
multiplier <- function(x,y){
   x %*% y
}


head(multiplier(as.matrix(initials),diag(ncol(initials))))
##            [,1]      [,2]
## [1,] -10.000000 12.000000
## [2,]  -9.897959 11.571429
## [3,]  -9.795918 11.142857
## [4,]  -9.693878 10.714286
## [5,]  -9.591837 10.285714
## [6,]  -9.489796  9.857143

Shearing

  • Increase one of the 0s in the identity matrix
for (i in seq(0,1, length.out=10)) {
  new <- as.data.frame(multiplier(as.matrix(initials),matrix(c(1,i,0,1),nrow=2,ncol=2)))
  plot(new$V2~new$V1, pch = 19, xlim=c(-20, 30), ylim=c(-10,10))
}

Scaling

  • Lets get bigger! We increase the 1s in the identity matrix
for (i in seq(1,2, length.out=10)) {
  new <- as.data.frame(multiplier(as.matrix(initials),matrix(c(i,0,0,i),nrow=2,ncol=2)))
  plot(new$V2~new$V1, pch = 19, xlim=c(-20,30), ylim=c(-10,10))
}

Rotation

for (i in seq(1,-1, length.out=10)) {
  new <- as.data.frame(multiplier(as.matrix(initials),matrix(c(cos(i),-sin(i),sin(i),cos(i)),nrow=2,ncol=2)))
  plot(new$V2~new$V1, pch = 19, xlim=c(-20,30), ylim=c(-10,10))
}

Projection

for (i in seq( 0, 1, length.out=10)) {
  new <- as.data.frame(multiplier(as.matrix(initials),matrix(c(i,0,0,0),ncol=2)))
  plot(new$V2~new$V1, pch = 19, xlim=c(-20,30), ylim=c(-10,10))
}

# Conclusion

It’s pretty amazing how powerful linear algebra is when it comes to image transformation. With simple matrix multiplication I’m able to scale, rotate and manipulate an image