v9.1.1
Menu

SVD Image Compression

hardFREEMatrices & TransformationsTransformationsCV: Mathematical Foundations

Implement image compression using Truncated Singular Value Decomposition (SVD).

SVD decomposes an image matrix AA (m×n) into: A=UΣVTA = U \Sigma V^T

Where:

  • UU (m×m): Left singular vectors (row patterns)
  • Σ\Sigma (m×n): Diagonal matrix of singular values
  • VTV^T (n×n): Right singular vectors (column patterns)

Truncated SVD keeps only the top kk singular values, achieving compression: Ak=UkΣkVkTA_k = U_k \Sigma_k V_k^T

The compression ratio is: m×nk(m+n+1)\frac{m \times n}{k(m + n + 1)}, rounded to 2 decimal places.

Quality measure: The retained energy/variance is: energy=∑i=1kσi2∑i=1rσi2\text{energy} = \frac{\sum_{i=1}^{k} \sigma_i^2}{\sum_{i=1}^{r} \sigma_i^2}

where rr is the rank of the original matrix.

Example

Input
image = [[100, 100, 100],
         [100, 100, 100],
         [100, 100, 100]]
k = 1
Output
{'compressed': [[100, 100, 100], [100, 100, 100], [100, 100, 100]], 'compression_ratio': 1.29}
Reasoning
  • Inputs: image is a 3×33 \times 3 grayscale matrix AA with every pixel equal to 100, so m=n=3m = n = 3; k = 1 means only the single largest singular value is kept.
  • Every row is identical, so AA has rank 1. With the unit vector u=v=13(1,1,1)u = v = \tfrac{1}{\sqrt{3}}(1, 1, 1) it factors as A=300 uvTA = 300\, u v^T, giving σ1=100⋅3⋅3=300\sigma_1 = 100 \cdot \sqrt{3} \cdot \sqrt{3} = 300 and σ2=σ3=0\sigma_2 = \sigma_3 = 0.
  • Keeping k=1k = 1 retains all the energy: 30023002=1\frac{300^2}{300^2} = 1. Each entry of A1=σ1uvTA_1 = \sigma_1 u v^T is 300⋅13=100300 \cdot \tfrac{1}{3} = 100 — already an integer in [0,255][0, 255], so compressed equals the original.
  • Ratio: the truncated form stores u1u_1 (3 numbers), v1v_1 (3) and σ1\sigma_1 (1), i.e. k(m+n+1)=7k(m+n+1) = 7 values instead of mn=9mn = 9. So 9/7≈1.28579/7 \approx 1.2857, reported as 1.29.
  • Notice that compression only pays off when k(m+n+1)<mnk(m+n+1) < mn: a 2×22 \times 2 image with k=1k = 1 gives 4/5=0.84/5 = 0.8, a larger "compressed" form.

Constraints

  • image: 2D numpy array (grayscale, values 0-255)
  • k: Number of singular values to keep
  • Return: Dictionary with 'compressed' image and 'compression_ratio'
  • Clip output values to [0, 255] and round to integers

Learn this in

More from CV: Mathematical Foundations

solution.py

Test results

Sign in to run your code against the test cases.