기존에 64x64=4096 차원이었던 이미지 데이터를 k 차원으로 축소하고 싶다면, 가장 큰 Eigenvalue(고유값) 값을 가진 k개의 고유벡터(Eigenvector)를 골라 이 벡터들을 축으로 데이터를 투영시키면 된다.
def perform_pca(X, eigenvecs, k):
# k: 몇 차원으로 축소할 것인가?
V = eigenvecs[:, :k]
X_reduced = X @ V
return X_reduced
Xred = perform_pca(imgs_flatten, eigenvecs, 2)
이미지 데이터를 담고 있는 imgs_flatten과 k개의 Eigenvector를 담고 있는 행렬의 행렬곱을 통해 k차원으로 축소를 시켰다. 위 코드에서는 k=2 이기 때문에 이미지 데이터가 2차원으로 축소된다.
plt.figure(figsize=(10, 8))
plt.scatter(Xred[:, 0], Xred[:, 1])
for i in range(Xred.shape[0]):
plt.text(Xred[i, 0], Xred[i, 1], str(i), fontsize=9)
plt.grid(True)
plt.show()
모든 110개의 이미지들에 대해서 PCA를 진행한 결과를 간단히 plot 해보자. 결과는 다음과 같았다!

비슷한 특성을 가진 이미지들은 PCA를 통해 차원이 축소된 후에도 비슷한 값을 가질 것이라는 사실을 유추해볼 수 있다. 이를 검증하기 위해 좌표상 가까운 63번 이미지와 93번 이미지의 원본을 비교해보고, 좌표상 멀리 떨어져있는 37번 이미지와 104번 이미지 역시 비교해보자.
plt.figure(figsize=(8, 16))
plt.subplot(1, 2, 1)
plt.imshow(imgs[63])
plt.title("Image 63")
plt.subplot(1, 2, 2)
plt.imshow(imgs[93])
plt.title("Image 93")

예상한대로 PCA를 통한 차원축소 결과가 비슷한 두 데이터의 원본 이미지를 비교해본 결과, 비슷하게 생긴 강아지 두마리가 나왔다!
plt.figure(figsize=(8, 16))
plt.subplot(1, 2, 1)
plt.imshow(imgs[37])
plt.title("Image 37")
plt.subplot(1, 2, 2)
plt.imshow(imgs[104])
plt.title("Image 104")

차원축소 결과가 크게 상이한 두 이미지의 원본이다. 비슷한 구석을 찾아보기 힘든 고양이와 강아지의 사진이 나온 것을 확인할 수 있다. 이러한 두 결과는 PCA를 통한 차원축소가 어느정도 이미지의 특성을 잘 반영해준다는 것을 의미한다!
이제 PCA를 통해 k차원으로 축소된 데이터를 다시 원본 이미지에 가깝에 복원해보자.
이를 위해서는 단순히 축소된 k차원 데이터에 Eigenvector 행렬의 Transpose를 곱해주면 된다.
def reconstruct_image(Xred, eigenvecs, k):
X_reconstructed = Xred @ eigenvecs[:, :k].T
return X_reconstructed
Xrec = reconstruct_image(Xred[25, :], eigenvecs, 2)
plt.subplot(1, 2, 1)
plt.imshow(Xrec.reshape(64, 64))
plt.title("Reconstructed Image")
plt.subplot(1, 2, 2)
plt.imshow(imgs[25])
plt.title("Original Image")

단 2개의 Eigenvector를 따라 축소시킨 이미지를 복원시킨 결과이다. 원본 이미지와 약간은 흡사해 보인다!
만약 더 많은 수의 Eigenvector를 사용한다면 원본 데이터의 더 많은 정보를 가진 채로 축소될 것이므로, 복원시켰을 때에도 원본 이미지에 더 가까운 결과를 얻을 것이라는 생각이 들었다.

확실히 많은 수의 차원으로 축소시킨 후 복원했을 때 원본 이미지에 가까운 모습을 보인다.

110개의 Eigenvector 모두를 사용하고 복원시켰을 때는 원본 이미지와 같은 결과를 얻을 수 있다.
'컴퓨터 비전' 카테고리의 다른 글
| AlexNet의 구조와 구현 (0) | 2026.01.10 |
|---|---|
| 이미지에서의 Edge Detection (First Derivative, Laplacian, Canny Edge Detection) (0) | 2026.01.04 |
| openCV 활용한 문서 스캐너 프로그램 만들기(2) (0) | 2025.12.28 |
| openCV 활용한 문서 스캐너 프로그램 만들기 (0) | 2025.12.16 |
| PCA(주성분 분석)를 통해 이미지에서 특성 추출하기 - (1) (0) | 2025.11.14 |