Load Dependencies

library(tidyverse)
## Warning: package 'dplyr' was built under R version 4.2.3
## Warning: package 'stringr' was built under R version 4.2.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(jpeg)

Data Processing and Load Data into Array

image_path = file.path(getwd(), 'jpg/')
files <- list.files(path = image_path, pattern = "jpg")
image <- readJPEG(paste0(image_path,files[1]))

# get info
num <- length(files)
image_dim <- dim(image)
height <- image_dim[1]
width <- image_dim[2]
scale <- image_dim[3]

Vectorize and Plot Image

# vectorize the image
a <- array(rep(0, num * height * width * scale), dim =
               c(num, height, width, scale))

for (i in 1:num){
    img <- readJPEG(paste0(image_path,files[i]))
    a[i,,,] <- array(img, dim = c(1, height, width, scale))
}

A <- matrix(0, num, prod(image_dim))

for (i in 1:num){
    img <- readJPEG(paste0(image_path,files[i]))
    r <- as.vector(img[,,1])
    g <- as.vector(img[,,2])
    b <- as.vector(img[,,3])
    A[i,] <- t(c(r, g, b))
}

eigen_shoe <- as.data.frame(t(A))
# plot the image
plot_jpeg <- function(path, add = FALSE){
    img = readJPEG(path, native = TRUE)
    res = dim(img)[2:1]
    if (!add){
        plot(1,1,xlim=c(1,res[1]),ylim=c(1,res[2]),asp=1,type='n',xaxs='i',
             yaxs='i',xaxt='n',yaxt='n',xlab='',ylab='',bty='n')
        rasterImage(img,1,1,res[1],res[2])
    }
}

par(mfrow=c(6,3))
par(mai=c(.05,.05,.05,.05))
for (i in 1:length(files)){
  plot_jpeg(writeJPEG(a[i,,,]))
}

Scale and Eigen Calculation

scaled_shoe <- scale(eigen_shoe, center = TRUE, scale = TRUE)
eigen_sigma <- cor(scaled_shoe)
myeigen <- eigen(eigen_sigma)
calculation <- cumsum(myeigen$values) / sum(myeigen$values)
calculation
##  [1] 0.6833138 0.7824740 0.8353528 0.8629270 0.8825040 0.8996099 0.9144723
##  [8] 0.9271856 0.9374462 0.9472860 0.9561859 0.9647964 0.9732571 0.9804242
## [15] 0.9874038 0.9941511 1.0000000
# only 15 passed the 80%
scaling <- diag(myeigen$values[1:15]^(-1/2)) / (sqrt(nrow(scaled_shoe)-1))
eigenshoes <- scaled_shoe%*%myeigen$vectors[,1:15]%*%scaling

#new data based on 80% variability
new_data <- a
dim(new_data) <- c(num, height * width * scale)
mypca <- princomp(t(as.matrix(new_data)), scores=TRUE, cor=TRUE)
# plot the new image
mypca2 <- t(mypca$scores)
dim(mypca2) <- c(num, height, width, scale)
par(mfrow=c(6,3))
par(mai=c(.05,.05,.05,.05))
for (i in 1:15){
  plot_jpeg(writeJPEG(mypca2[i,,,]))
}