uz_assignments/assignment6/solution.py

232 lines
6.1 KiB
Python
Raw Normal View History

2022-12-26 17:08:10 +01:00
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()