-
Notifications
You must be signed in to change notification settings - Fork 3
/
05-compress-image-cpca.R
116 lines (85 loc) · 2.18 KB
/
05-compress-image-cpca.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
### inc
library(png)
library(ggplot2)
library(grid)
library(gridExtra)
### par
imgfile <- "data/lena_std.png"
imgfile2 <- "data/img-rarpack.png"
### local fucntions
compress_pca <- function(m, k, center = TRUE)
{
factorize <- function(m, c, k)
{
cat(" EVD on", c, "...\n")
mat <- m[, , c]
if(center) {
means <- colMeans(mat)
mat <- sweep(mat, 2, means, "-")
}
fac <- eigen(crossprod(mat), symmetric = TRUE)
m <- mat %*% fac$vectors[, 1:k] %*% t(fac$vectors[, 1:k])
if(center) {
m <- sweep(m, 2, means, "+")
}
m[m < 0] <- 0
m[m > 1] <- 1
return(m)
}
rimg <- array(c(factorize(m, 1, k), factorize(m, 2, k), factorize(m, 3, k)),
dim(img))
return(rimg)
}
compress_cpca <- function(img, k, center = TRUE)
{
K <- dim(img)[3]
### prepare data
means <- list()
cov <- list()
ng <- rep(as.integer(NA), K)
for(i in 1:K) {
cat(" * ", i, "/", K, "\n")
m <- img[, , i]
meansi <- colMeans(m)
if(center) {
m <- sweep(m, 2, meansi, "-")
}
means[[i]] <- meansi
cov[[i]] <- crossprod(m)
ng[i] <- nrow(m)
}
### run CPCA
out <- cpca(cov, ng, ncomp = k)
### reconstruct
dat <- array(as.numeric(NA), dim(img))
for(i in 1:K) {
cat(" * ", i, "/", K, "\n")
m <- img[, , i]
meansi <- means[[i]]
if(center) {
m <- sweep(m, 2, meansi, "-")
}
mat <- m %*% out$CPC[, 1:k, drop = FALSE] %*% t(out$CPC[, 1:k, drop = FALSE])
if(center) {
mat <- sweep(mat, 2, means[[i]], "+")
}
mat[mat < 0] <- 0
mat[mat > 1] <- 1
dat[, , i] <- mat
}
return(dat)
}
viewImg <- function(img)
{
marrangeGrob(list(rasterGrob(img)), nrow = 1, ncol = 1, top = NULL)
}
lineImg <- function(img, k, ncol = 10, center = TRUE)
{
imgs <- c(llply(k, function(x) compress_pca(img, x, center = center)), list(img),
llply(k, function(x) compress_cpca(img, x, center = center)), list(img))
marrangeGrob(llply(imgs, rasterGrob),
nrow = 2, ncol = length(k) + 1, top = NULL)
}
### read file
img <- readPNG(imgfile)
#img <- readPNG(imgfile2)