Principal Component Analysis (PCA) is a linear dimensionality reduction technique (algorithm) that transform a set of correlated variables into a smaller number of uncorrelated variables called principal components while keeping as much of the variability in the original data as possible. Here, I used image compression method — a technique that minimizes the size in bytes of an image while keeping as much of the quality of the image as possible.
First and foremost,let’s load the necessary packages beforehand for use.
library(jpeg)
library(factoextra)
## Loading required package: ggplot2
## Warning in register(): Can't find generic `scale_type` in package ggplot2 to
## register S3 method.
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(gridExtra)
library(ggplot2)
library(magick)
## Linking to ImageMagick 6.9.12.3
## Enabled features: cairo, freetype, fftw, ghostscript, heic, lcms, pango, raw, rsvg, webp
## Disabled features: fontconfig, x11
library(png)
library(Metrics)
library(knitr)
library(imgpalr)
library(abind)
Now we need to import and plot the color eagle of an eagle.
eagle <- readJPEG("C:\\Users\\ellaz\\OneDrive\\Desktop\\Leyla\\University of Warsaw\\1st semester\\USL\\Final projects\\eagle.jpg")
plot(1, type="n")
rasterImage(eagle, 0.6, 0.6, 1.4, 1.4)
In color eagle we always have 3 matrices - pixel by pixel. Each of them determines the one component of RGB(Red,Green,Blue) color. To sum up RGB shades, we can convert the image to the grey scale and then divide by maximum value.
eagle.sum<-eagle[,,1]+eagle[,,2]+eagle[,,3]
eagle.bw<-eagle.sum/max(eagle.sum)
Now let’s plot the back and white image.
plot(1, type="n")
rasterImage(eagle.bw, 0.6, 0.6, 1.4, 1.4)
PCA for pictures is for running individual PCA on each of RGB shades. We can integrate new shades into picture. We can do it by multiplying “x” and “rotation” components of PCA. And each color scale (R,G,B) gets own matrix and own PCA.
r<-eagle[,,1]
g<-eagle[,,2]
b<-eagle[,,3]
r.pca<-prcomp(r, center=FALSE, scale.=FALSE)
g.pca<-prcomp(g, center=FALSE, scale.=FALSE)
b.pca<-prcomp(b, center=FALSE, scale.=FALSE)
We can merge all PCA into 1 object.
rgb.pca<-list(r.pca, g.pca, b.pca)
Let’s see the importance of PC.
f1<-fviz_eig(r.pca, main="red", barfill="red", ncp=5, addlabels=TRUE)
f2<-fviz_eig(g.pca, main="green", barfill="green", ncp=5, addlabels=TRUE)
f3<-fviz_eig(b.pca, main="blue", barfill="blue", ncp=5, addlabels=TRUE)
grid.arrange(f1, f2, f3, ncol=3)
Number of pixels in a eagle defines the number of principal components (PC). In this code below, we make 9 eagles, with min. 3 & max=n PC. Then we multiply x * rotation and apply it on existing pixels grid. Finally, we save all eagles into working directory and as objects.
vec<-seq.int(3, round(nrow(eagle)), length.out=9)
for(i in vec){
eagle.pca<-sapply(rgb.pca, function(j) {
new.RGB<-j$x[,1:i] %*% t(j$rotation[,1:i])}, simplify="array")
assign(paste("eagle_", round(i,0), sep=""), eagle.pca)
writeJPEG(eagle.pca, paste("eagle_", round(i,0), "_princ_comp.jpg", sep=""))
}
Here, we plot all the 9 images and then save them. From the first image to the last one images are becoming more clear. We increase their resolution and see the results together.
par(mfrow=c(3,3))
par(mar=c(1,1,1,1))
plot(image_read(get(paste("eagle_", round(vec[1],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[2],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[3],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[4],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[5],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[6],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[7],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[8],0), sep=""))))
plot(image_read(get(paste("eagle_", round(vec[9],0), sep=""))))
Let’s see how we can make own palette from our image. We can see different color shades with their exact color ID.
col1<-image_pal("C:\\Users\\ellaz\\OneDrive\\Desktop\\Leyla\\University of Warsaw\\1st semester\\USL\\Final projects\\eagle.jpg", n=8, type="div", saturation=c(0.75, 1), brightness=c(0.75, 1), plot=TRUE)
col2<-image_pal("C:\\Users\\ellaz\\OneDrive\\Desktop\\Leyla\\University of Warsaw\\1st semester\\USL\\Final projects\\eagle.jpg", n=11, type="seq", k=2, saturation=c(0.5, 1), brightness=c(0.25, 1), seq_by="hsv", plot=TRUE)
col3<-image_pal("C:\\Users\\ellaz\\OneDrive\\Desktop\\Leyla\\University of Warsaw\\1st semester\\USL\\Final projects\\eagle.jpg", n=11, type="div", k=2, saturation=c(0.5, 1), brightness=c(0.25, 1), plot=TRUE)
col4<-image_pal("C:\\Users\\ellaz\\OneDrive\\Desktop\\Leyla\\University of Warsaw\\1st semester\\USL\\Final projects\\eagle.jpg", n=11, k=30, type="div", saturation=c(0.75, 1), brightness=c(0.75, 1), bw=c(0.1, 0.9), plot=TRUE)
THANK YOU!