A Python implementation of image compression using Singular Value Decomposition (SVD) built from scratch. This project demonstrates how linear algebra techniques can be applied to compress grayscale images while maintaining visual quality.
- About
- How It Works
- Features
- Installation
- Usage
- Example Output
- Customization
- Technical Details
- Project Structure
- Contributing
- License
- Author
This program compresses grayscale images using Singular Value Decomposition (SVD), a matrix factorization technique that decomposes an image matrix into three components: U, Σ (singular values), and V^T. By retaining only the most significant singular values, we can reconstruct an approximation of the original image with significantly reduced storage requirements.
The visualization includes:
- Original image
- Compressed versions at different compression levels (k=10, 20, 50, 100)
- Compression ratio for each level
- Singular value decay plot showing the importance distribution
The image matrix A is decomposed as:
A = U @ Σ @ V^T
Where:
- U contains the left singular vectors (image patterns in row space)
- Σ is a diagonal matrix of singular values (importance weights)
- V^T contains the right singular vectors (image patterns in column space)
By keeping only the top k singular values and their corresponding vectors:
A_compressed = U_k @ Σ_k @ V^T_k
This reduces storage from m × n to (m × k + k + n × k) values.
ratio = (m × n) / (m × k + k + n × k)
Higher ratio = more compression (but potentially lower quality)
- Custom SVD implementation: Built from eigenvalue decomposition rather than using NumPy's built-in SVD
- Multiple compression levels: Compare different k values side-by-side
- Compression ratio calculation: See exactly how much space you're saving
- Singular value visualization: Understand which components contribute most to image quality
- Educational code: Well-commented implementation for learning purposes
- Python 3.7 or higher
- pip package manager
- Clone this repository:
git clone https://github.com/yourusername/svd-image-compression.git
cd svd-image-compression- (Optional) Create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install required packages:
pip install -r requirements.txtOr install packages individually:
pip install numpy pillow matplotlib-
Place your test image in the
Imagesfolder and name ittest.jpg(or modify the path in the script) -
Run the script:
python svd_compression.py- The program will display a 2×3 grid showing:
- Top left: Original image
- Top middle through bottom middle: Compressed versions with k=10, 20, 50, 100
- Bottom right: Singular value decay plot
For a typical image, you'll observe:
| k Value | Compression Ratio | Quality Description |
|---|---|---|
| k=10 | ~30-40× | High compression, somewhat blurry |
| k=20 | ~15-20× | Good compression, recognizable details |
| k=50 | ~6-8× | Moderate compression, good quality |
| k=100 | ~3-4× | Low compression, nearly identical to original |
The singular value plot helps identify the "elbow point" where additional components provide diminishing returns.
kVals = [10, 20, 50, 100] # Modify these values as neededimg = Image.open('Images/your_image.jpg').convert('L')rank = np.sum(singularValue > 1e-10) # Change 1e-10 for different noise tolerancefig, axes = plt.subplots(2, 3, figsize=(15, 10)) # Adjust grid size and figure dimensionsSVD is optimal for:
- Finding the best low-rank approximation of a matrix (Eckart-Young theorem)
- Separating signal from noise
- Understanding the intrinsic dimensionality of data
- Grayscale only: Color images are converted automatically (extend to RGB by applying SVD to each channel)
- Computational cost: Custom implementation is O(n³); production use should leverage optimized libraries
- Not lossy like JPEG: Different compression paradigm; better for understanding linear algebra than practical use
The custom SVD implementation is educational. For production use:
U, s, Vt = np.linalg.svd(image_matrix, full_matrices=False)svd-image-compression/
├── svd_compression.py # Main script
├── Images/ # Image folder
│ └── test.jpg # Your test image
├── README.md # This file
├── requirements.txt # Python dependencies
└── .gitignore # Git ignore file
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Extend to RGB images (apply SVD to each color channel)
- Add interactive slider to adjust k value in real-time
- Compare with other compression techniques (DCT, wavelets)
- Implement progressive loading (send low-k first, then refine)
- Add PSNR/SSIM quality metrics
This project is licensed under the MIT License - see the LICENSE file for details.
Created as a learning project to understand SVD and its applications in image compression and dimensionality reduction.
Connect with me:
- GitHub: @binary69
- LinkedIn: Reema Hanim Hanass
⭐ If you found this project helpful, please consider giving it a star!
- Inspired by the mathematical elegance of linear algebra
- Built as part of learning numerical methods and matrix decomposition
- Thanks to the NumPy and Matplotlib communities for excellent documentation