232 lines
6.1 KiB
Python
232 lines
6.1 KiB
Python
|
import numpy as np
|
||
|
import numpy.typing as npt
|
||
|
from matplotlib import pyplot as plt
|
||
|
import cv2
|
||
|
import uz_framework.image as uz_image
|
||
|
import uz_framework.text as uz_text
|
||
|
import os
|
||
|
|
||
|
def one_a() -> None:
|
||
|
print('Hello')
|
||
|
|
||
|
def one_b() -> None:
|
||
|
points = np.loadtxt('./data/points.txt')
|
||
|
|
||
|
uz_image.compute_PCA(points)
|
||
|
|
||
|
def one_d() -> None:
|
||
|
points = np.loadtxt('./data/points.txt')
|
||
|
|
||
|
U, S, VT = uz_image.compute_PCA(points)
|
||
|
|
||
|
uz_image.plot_histogram_pca(U, S, VT)
|
||
|
|
||
|
# U is the matrix of eigenvectors
|
||
|
# S is the vector of eigenvalues
|
||
|
# VT is the matrix of eigenvectors
|
||
|
|
||
|
def one_e() -> None:
|
||
|
"""
|
||
|
Now remove the direction of the lowest variance from the input data. This means
|
||
|
we will project the data into the subspace of the first eigenvector. We can do this
|
||
|
by transforming the data into the PCA space then setting to 0 the components
|
||
|
corresponding to the eigenvectors we want to remove. The resulting points can
|
||
|
then be transformed back to the original space. Project each of the input points to
|
||
|
PCA space, then project them back to Cartesian space by multiplying them by the
|
||
|
diminished matrix U.
|
||
|
"""
|
||
|
points = np.loadtxt('./data/points.txt')
|
||
|
|
||
|
U, S, VT, mean = uz_image.compute_PCA(points)
|
||
|
|
||
|
# Drop all but first eigenvector
|
||
|
U = U[:, 0:1]
|
||
|
|
||
|
# Project points into PCA subspace
|
||
|
y_i = np.matmul(points - mean, U)
|
||
|
|
||
|
# Project points back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original points and the projected points
|
||
|
plt.scatter(points[:, 0], points[:, 1], c='b', label='Original')
|
||
|
plt.scatter(x_i[:, 0], x_i[:, 1], c='r', label='Projected')
|
||
|
|
||
|
plt.show()
|
||
|
|
||
|
|
||
|
def two_a():
|
||
|
points = np.loadtxt('./data/points.txt')
|
||
|
|
||
|
def two_b():
|
||
|
points = np.loadtxt('./data/points.txt')
|
||
|
U, S, VT, mean = dual_PCA(points)
|
||
|
|
||
|
print(U)
|
||
|
y_i = np.matmul(points - mean, U)
|
||
|
|
||
|
# Project points back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original points and the projected points
|
||
|
plt.scatter(points[:, 0], points[:, 1], c='b', label='Original')
|
||
|
plt.scatter(x_i[:, 0], x_i[:, 1], c='r', label='Projected')
|
||
|
plt.show()
|
||
|
|
||
|
def dual_PCA(points):
|
||
|
X = points.T.copy()
|
||
|
mean = np.mean(X, axis=1)
|
||
|
X = X - mean[:, np.newaxis]
|
||
|
|
||
|
# Compute the covariance matrix
|
||
|
C = (1/(X.shape[1]-1)) * X.T @ X
|
||
|
|
||
|
# Compute the eigenvalues and eigenvectors
|
||
|
U, S, VT = np.linalg.svd(C)
|
||
|
S += 1e-15
|
||
|
|
||
|
U = X @ U @ np.sqrt(np.diag(1/(S * (X.shape[1]-1))))
|
||
|
return U, S, VT, mean
|
||
|
|
||
|
def three_a():
|
||
|
imgs = read_images('./data/faces/1')
|
||
|
|
||
|
def three_b():
|
||
|
imgs = read_images('./data/faces/1')
|
||
|
U, S, VT, mean = dual_PCA(imgs)
|
||
|
|
||
|
# Plot those eigenvectors
|
||
|
fig, axs = plt.subplots(1, 5)
|
||
|
for i in range(5):
|
||
|
axs[i].imshow(U[:, i].reshape((96, 84)), cmap='gray')
|
||
|
plt.show()
|
||
|
|
||
|
# Project images into PCA subspace
|
||
|
y_i = np.matmul(imgs - mean, U)
|
||
|
|
||
|
# Project images back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original images and the projected images
|
||
|
fig, axs = plt.subplots(1, 5)
|
||
|
for i in range(5):
|
||
|
axs[i].imshow(imgs[i].reshape((96, 84)), cmap='gray')
|
||
|
plt.show()
|
||
|
|
||
|
img = imgs[0].copy()
|
||
|
|
||
|
# Add noise to index 4074
|
||
|
img[4074] = 0
|
||
|
|
||
|
# Project image into PCA subspace
|
||
|
y_i = np.matmul(img - mean, U)
|
||
|
|
||
|
# Project image back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original image and the projected image
|
||
|
fig, axs = plt.subplots(1, 2)
|
||
|
axs[0].imshow(img.reshape((96, 84)), cmap='gray')
|
||
|
axs[1].imshow(x_i.reshape((96, 84)), cmap='gray')
|
||
|
plt.show()
|
||
|
|
||
|
# Count the difference in pixels
|
||
|
print(np.sum(np.abs(img - x_i)))
|
||
|
|
||
|
img2 = imgs[0].copy()
|
||
|
|
||
|
# Project image into PCA subspace
|
||
|
y_i = np.matmul(img2 - mean, U)
|
||
|
y_i[0] = 0
|
||
|
|
||
|
# Project image back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original image and the projected images
|
||
|
fig, axs = plt.subplots(1, 2)
|
||
|
axs[0].imshow(img2.reshape((96, 84)), cmap='gray')
|
||
|
axs[1].imshow(x_i.reshape((96, 84)), cmap='gray')
|
||
|
plt.show()
|
||
|
|
||
|
# Count the number of pixels that are different
|
||
|
print(np.sum(np.abs(img - x_i)))
|
||
|
|
||
|
|
||
|
def read_images(data_path):
|
||
|
imgs = np.array([])
|
||
|
for filename in os.listdir(data_path):
|
||
|
img = uz_image.imread_gray(os.path.join(data_path, filename), uz_image.ImageType.float64)
|
||
|
# Reshape image into a vector
|
||
|
img = img.reshape((img.shape[0] * img.shape[1], 1))
|
||
|
if imgs.size == 0:
|
||
|
imgs = img
|
||
|
else:
|
||
|
imgs = np.hstack((imgs, img))
|
||
|
return imgs.T
|
||
|
|
||
|
def three_c():
|
||
|
imgs = read_images('./data/faces/1')
|
||
|
U, S, VT, mean = dual_PCA(imgs)
|
||
|
|
||
|
img = imgs[0].copy()
|
||
|
|
||
|
values = [32, 16, 8, 4, 2, 1]
|
||
|
|
||
|
for value in values:
|
||
|
# Projcet image into PCA subspace
|
||
|
y_i = np.matmul(img - mean, U)
|
||
|
y_i[value:] = 0
|
||
|
|
||
|
# Project image back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original image and the projected images
|
||
|
fig, axs = plt.subplots(1, 2)
|
||
|
axs[0].imshow(img.reshape((96, 84)), cmap='gray')
|
||
|
axs[1].imshow(x_i.reshape((96, 84)), cmap='gray')
|
||
|
plt.show()
|
||
|
|
||
|
# Count the number of pixels that are different
|
||
|
print(np.sum(np.abs(img - x_i)))
|
||
|
|
||
|
def three_e():
|
||
|
imgs = read_images('./data/faces/1')
|
||
|
U, S, VT, mean = dual_PCA(imgs)
|
||
|
|
||
|
elephant = uz_image.imread_gray('./data/elephant.jpg', uz_image.ImageType.float64)
|
||
|
elephant = elephant.reshape((elephant.shape[0] * elephant.shape[1], 1)).T
|
||
|
|
||
|
# Project image into PCA subspace
|
||
|
y_i = np.matmul(elephant - mean, U)
|
||
|
|
||
|
# Project image back into original subspace
|
||
|
x_i = np.matmul(y_i, U.T) + mean
|
||
|
|
||
|
# Plot the original image and the projected images
|
||
|
fig, axs = plt.subplots(1, 2)
|
||
|
axs[0].imshow(elephant.reshape((96, 84)), cmap='gray')
|
||
|
axs[1].imshow(x_i.reshape((96, 84)), cmap='gray')
|
||
|
plt.show()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
# ######## #
|
||
|
# SOLUTION #
|
||
|
# ######## #
|
||
|
|
||
|
def main():
|
||
|
#one_b()
|
||
|
#one_d()
|
||
|
#one_e()
|
||
|
#two_b()
|
||
|
#three_a()
|
||
|
#three_c()
|
||
|
three_e()
|
||
|
#two_c()
|
||
|
#ex2()
|
||
|
#ex3()
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|