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. For example, the following code builds an H. x=c(rep(0,500),seq(0,1,length.out=1000), rep(1,500)) y=c(seq(-1,1,length.out=500),rep(0,1000), seq(-1,1,length.out=500)) z=rbind(x,y) plot(y~x, xlim=c(-3,3), ylim=c(-3,3))
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.
Hint: Use x11() to open a new plotting window in R. Upload your document as a .RMD file. I will know if your assignment is correct if the animation runs. correctly
library(gifski)
library(anim.plots)
library(stringr)
library(ggplot2)
library(dplyr)##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(plotly)##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
Plot Initials
These are the points required to spell out my initials, “AM”
x = c(seq(0,0.5, length.out=500),
seq(.5,1,length.out=500),
seq(.25,.75, length.out=250),
seq(1.5,1.5,length.out=500),
seq(1.5,2,length.out=500),
seq(2,2.5,length.out=500),
seq(2.5,2.5, length.out=500))
y = c(seq(-1,1,length.out=500),
seq(1,-1,length.out=500),
rep(0,250),
seq(-1,1,length.out=500),
seq(1,-1,length.out=500),
seq(-1,1,length.out=500),
seq(1,-1,length.out=500))
z = rbind(x,y)
plot(y~x, xlim=c(-1,3), ylim=c(-3,3))Create left multiply function for later processing
This function will be used to multiply our transformation matrix with the points above in order to scale, shear, rotate, and project.
left_multiply <- function(x,y){
x %*% y
}Create function that performs transformation and saves image
visualize_transformation <- function(square_values, z){
square = matrix(square_values,nrow=2, ncol=2)
z_shifted = left_multiply(square, z)
y_shifted = z_shifted[2,]
x_shifted = z_shifted[1,]
plot <- ggplot() +
geom_point(aes(x=x_shifted, y=y_shifted))
plot
return(plot)
}Horizontal Scaling
By changing the first value in our square matrix, we affect the horizontal spread of our image.
for (i in seq(0,10,by=1)){
square_values = c(i,0,0,1)
p <- visualize_transformation(square_values, z)
file_name = str_interp("horizontal_scaling_${i}.png")
ggsave(plot=p, filename=file_name)
}## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
image_names = list("horizontal_scaling_0.png","horizontal_scaling_1.png","horizontal_scaling_2.png","horizontal_scaling_3.png","horizontal_scaling_4.png","horizontal_scaling_5.png","horizontal_scaling_6.png","horizontal_scaling_7.png","horizontal_scaling_8.png","horizontal_scaling_9.png","horizontal_scaling_10.png")
images <- lapply(image_names, magick::image_read)
stitched_images <- magick::image_join(images)
animated_images <- magick::image_animate(stitched_images, fps = 1)
animated_imagesVertical Shearing
By changing the second value we affect the shearing of the image
for (i in seq(-10,10,by=1)){
square_values = c(1,i,0,1)
p <- visualize_transformation(square_values, z)
file_name = str_interp("shearing_${i}.png")
ggsave(plot=p, filename=file_name)
}## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
image_names = list("shearing_-10.png","shearing_-9.png","shearing_-8.png","shearing_-7.png","shearing_-6.png","shearing_-5.png","shearing_-4.png","shearing_-3.png","shearing_-2.png","shearing_-1.png", "shearing_0.png","shearing_1.png","shearing_2.png","shearing_3.png","shearing_4.png","shearing_5.png","shearing_6.png","shearing_7.png","shearing_8.png","shearing_9.png","shearing_10.png")
images <- lapply(image_names, magick::image_read)
stitched_images <- magick::image_join(images)
animated_images <- magick::image_animate(stitched_images, fps = 1)
animated_imagesHorizontal Shearing
By changing the third variable we get horizontal shearing
for (i in seq(-10,10,by=1)){
square_values = c(1,0,i,1)
p <- visualize_transformation(square_values, z)
file_name = str_interp("third_${i}.png")
ggsave(plot=p, filename=file_name)
}## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
image_names = list("third_-10.png","third_-9.png","third_-8.png","third_-7.png","third_-6.png","third_-5.png","third_-4.png","third_-3.png","third_-2.png","third_-1.png","third_0.png","third_1.png","third_2.png","third_3.png","third_4.png","third_5.png","third_6.png","third_7.png","third_8.png","third_9.png","third_10.png")
images <- lapply(image_names, magick::image_read)
stitched_images <- magick::image_join(images)
animated_images <- magick::image_animate(stitched_images, fps = 1)
animated_imagesLast Value Shearing
By changing the third variable we get horizontal shearing
for (i in seq(-10,10,by=1)){
square_values = c(1,0,0,i)
p <- visualize_transformation(square_values, z)
file_name = str_interp("last_${i}.png")
ggsave(plot=p, filename=file_name)
}## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
image_names = list("last_-10.png","last_-9.png","last_-8.png","last_-7.png","last_-6.png","last_-5.png","last_-4.png","last_-3.png","last_-2.png","last_-1.png","last_0.png","last_1.png","last_2.png","last_3.png","last_4.png","last_5.png","last_6.png","last_7.png","last_8.png","last_9.png","last_10.png")
images <- lapply(image_names, magick::image_read)
stitched_images <- magick::image_join(images)
animated_images <- magick::image_animate(stitched_images, fps = 1)
animated_imagesRotation
t=1
for (i in seq(0,pi*4,length.out=20)){
square_values = c(cos(i),-sin(i),sin(i),cos(i))
p <- visualize_transformation(square_values, z)
file_name = str_interp("circle_${t}.png")
ggsave(plot=p, filename=file_name)
t = t+1
}## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
## Saving 7 x 5 in image
image_names = list("circle_1.png","circle_2.png","circle_3.png","circle_4.png","circle_5.png","circle_6.png","circle_7.png","circle_8.png","circle_9.png","circle_10.png","circle_11.png","circle_12.png","circle_13.png","circle_14.png","circle_15.png","circle_16.png","circle_17.png","circle_18.png","circle_19.png","circle_20.png")
images <- lapply(image_names, magick::image_read)
stitched_images <- magick::image_join(images)
animated_images <- magick::image_animate(stitched_images, fps = 1)
animated_images