DEV Community

Henri Wang
Henri Wang

Posted on

how can I compute PCA between different images, tell me its mathematics.

Computing Principal Component Analysis (PCA) between different images involves treating each image (or image patch) as a high-dimensional vector and then performing PCA to find the dominant patterns (principal components) across these vectors. Below, I’ll explain the mathematics step-by-step and provide a clear method to implement it.


Key Idea of PCA for Images

  1. Flatten each image into a 1D vector (e.g., a 64x64 image becomes a 4096-dim vector).
  2. Stack all images into a data matrix X (each row is an image, columns are pixel values).
  3. Compute PCA on X to find the principal components (PCs) that explain the most variance across images.

Step-by-Step Mathematics

Let’s say you have N images, each of size H × W (height × width).

1. Flatten and Create Data Matrix

  • Reshape each image into a column vector of size D = H × W.
  • Stack all images into a N × D data matrix X: [ X = \begin{bmatrix} \text{Image}_1^{(1)} & \text{Image}_1^{(2)} & \cdots & \text{Image}_1^{(D)} \ \text{Image}_2^{(1)} & \text{Image}_2^{(2)} & \cdots & \text{Image}_2^{(D)} \ \vdots & \vdots & \ddots & \vdots \ \text{Image}_N^{(1)} & \text{Image}_N^{(2)} & \cdots & \text{Image}_N^{(D)} \end{bmatrix} ] (Each row is an image, columns are pixel intensities.)

2. Center the Data (Subtract Mean)

  • Compute the mean image: [ \mu = \frac{1}{N} \sum_{i=1}^N \text{Image}_i ]
  • Subtract the mean from each image: [ X_{\text{centered}} = X - \mu ]

3. Compute Covariance Matrix

  • The covariance matrix C (size D × D) measures how pixel intensities vary together: [ C = \frac{1}{N-1} X_{\text{centered}}^T X_{\text{centered}} ] (For N < D, computing C directly is inefficient—see Efficient Computation below.)

4. Eigenvalue Decomposition

  • Solve for the eigenvectors (V) and eigenvalues (\Lambda) of C: [ C V = V \Lambda ]
  • The eigenvectors (columns of V) are the principal components (PCs).
  • The eigenvalues (\Lambda) indicate the variance explained by each PC.

5. Project Data onto Principal Components

  • To reduce dimensionality, select the top k PCs (e.g., k=3).
  • Project the centered data onto these PCs: [ \text{Scores} = X_{\text{centered}} V_k ] (Scores is an N × k matrix representing each image in the PCA space.)

Efficient Computation (for High-Dimensional Images)

If D (number of pixels) is large (e.g., D = 4096 for 64x64 images), computing the D × D covariance matrix is expensive. Instead:

  1. Compute the Gram matrix G = X_{\text{centered}} X_{\text{centered}}^T (size N × N).
  2. Find its eigenvectors U and eigenvalues \Lambda: [ G U = U \Lambda ]
  3. The PCs are then: [ V = X_{\text{centered}}^T U \Lambda^{-1/2} ] (This avoids computing the large D × D covariance matrix.)

Example in Python (using NumPy)

import numpy as np

# Example: 10 images of size 64x64 (flattened to 4096-dim vectors)
N, H, W = 10, 64, 64
X = np.random.rand(N, H * W)  # Replace with actual images

# Step 1: Center data
mean = np.mean(X, axis=0)
X_centered = X - mean

# Step 2: Compute covariance matrix (use Gram matrix trick for D >> N)
G = X_centered @ X_centered.T  # Gram matrix (N x N)
eigenvals, eigenvecs = np.linalg.eigh(G)  # Eigen decomposition

# Step 3: Get top k=3 principal components
k = 3
top_k_eigenvecs = eigenvecs[:, -k:]  # Last k eigenvectors (largest eigenvalues)
top_k_pcs = (X_centered.T @ top_k_eigenvecs) / np.sqrt(eigenvals[-k:])

# Step 4: Project data onto PCs
scores = X_centered @ top_k_pcs  # N x k matrix (PCA scores for each image)
print("PCA Scores (first 3 components):\n", scores)
Enter fullscreen mode Exit fullscreen mode

Interpretation

  • Each row of scores gives the coordinates of an image in the PCA space.
  • The first PC (scores[:, 0]) captures the direction of maximum variance across images.
  • Plotting scores[:, 0] vs scores[:, 1] visualizes image similarities.

Key Notes

  • Normalization: If pixel scales vary, standardize X (subtract mean, divide by std).
  • Whitening: To make all PCs equally important, divide by sqrt(eigenvals).
  • PCA vs. SVD: In practice, PCA is often computed via SVD (more numerically stable).

Top comments (0)