Image compression using least squares polynomial surface fitting with optional quantum computing module
Project description
polyfit-image-compress
Image compression using Least Squares Polynomial Surface Fitting — a novel approach that approximates image blocks with polynomial surfaces instead of traditional frequency-domain transforms (DCT/JPEG).
Includes an optional quantum computing module (PennyLane) that replaces the classical solver with a Variational Quantum Linear Solver (VQLS) for educational purposes.
How It Works
Original Image (H x W)
|
v
Split into B x B blocks (e.g., 8x8)
|
v
For each block: solve Ax = b via pseudoinverse
A = polynomial design matrix (precomputed once)
b = pixel intensities (flattened block)
x = polynomial coefficients (3 for linear, 6 for quadratic)
|
v
Store only the coefficients --> compression!
|
v
Reconstruct: evaluate polynomial at each pixel coordinate
Supported Models
| Model | Surface Type | Terms | Coefficients | 8x8 Ratio |
|---|---|---|---|---|
| Linear | Plane | 1, x, y |
3 | 5.3:1 |
| Quadratic | Paraboloid | 1, x, y, xy, x², y² |
6 | 2.7:1 |
Installation
# From PyPI (when published)
pip install polyfit-image-compress
# From source (development)
git clone https://github.com/Jelsin29/polyfit-image-compress.git
cd polyfit-image-compress
pip install -e ".[dev]"
# With quantum module
pip install -e ".[dev,quantum]"
# With interactive demo
pip install -e ".[dev,demo]"
# Everything
pip install -e ".[dev,quantum,demo,docs]"
Quick Start
CLI
# Compress an image to .pfic format
polyfit compress photo.png compressed.pfic --model quadratic --block-size 8
# Decompress back to an image
polyfit decompress compressed.pfic restored.png
# View file metadata
polyfit info compressed.pfic
# Output:
# PFIC File: compressed.pfic
# Version: 1
# Dimensions: 512x512
# Channels: 1
# Block size: 8
# Model: quadratic
# Run benchmarks comparing models and block sizes
polyfit benchmark photo.png
polyfit benchmark photo.png --model linear
Python API
import numpy as np
from skimage import data
from polyfit_compress import LeastSquaresCompressor, LinearModel, QuadraticModel
from polyfit_compress.metrics import psnr, ssim, mse
from polyfit_compress.io import save_pfic, load_pfic
# Load an image
image = data.camera() # 512x512 grayscale
# --- Compress ---
compressor = LeastSquaresCompressor(model=QuadraticModel(), block_size=8)
result = compressor.compress(image)
print(f"Compression ratio: {result.compression_ratio:.2f}x")
print(f"PSNR: {psnr(image, result.reconstructed):.2f} dB")
print(f"SSIM: {ssim(image, result.reconstructed):.4f}")
# --- Save to .pfic file ---
save_pfic("output.pfic", result)
# --- Load and decompress ---
header, coefficients = load_pfic("output.pfic")
reconstructed = compressor.decompress(
coefficients,
original_shape=(header.height, header.width),
padded_shape=(header.padding_height, header.padding_width),
)
# --- Visualization ---
from polyfit_compress.visualization import compare_images, error_heatmap
fig = compare_images(image, result.reconstructed)
fig.savefig("comparison.png")
fig = error_heatmap(image, result.reconstructed)
fig.savefig("error_map.png")
RGB Images
from skimage import data
# RGB works out of the box — each channel is compressed independently
rgb_image = data.astronaut() # 512x512x3
result = compressor.compress(rgb_image)
print(f"Shape preserved: {result.reconstructed.shape}") # (512, 512, 3)
Quantum Module
The quantum module is educational — it demonstrates how the classical least-squares solver maps to a quantum circuit. Simulators are slower than NumPy, not faster.
from polyfit_compress.quantum import HybridCompressor, VQLSConfig, VQLSSolver
# Hybrid compression: VQLS per block, classical fallback on non-convergence
config = VQLSConfig(n_layers=4, max_iterations=100, stepsize=0.1)
hybrid = HybridCompressor(
model=LinearModel(),
block_size=4, # Small blocks for quantum demos
vqls_config=config,
progress_callback=lambda i, total, ok: print(f"Block {i}/{total}: {'VQLS' if ok else 'fallback'}"),
)
result = hybrid.compress(small_image)
# Or solve a single system directly
solver = VQLSSolver(config)
coefficients, converged = solver.solve(design_matrix, pixel_block)
See the quantum tutorial notebook for a full walkthrough.
.pfic File Format
The .pfic (PolyFit Image Compressed) format stores compressed images:
[Header: 31 bytes] [Payload: float32 coefficients]
magic(4) | version(1) coefficients array
height(4) | width(4) shape: (channels, num_coeffs, num_blocks)
channels(1) | block_size(2)
model_type(1) | padding(8)
reserved(6)
Project Structure
polyfit-image-compress/
├── src/polyfit_compress/ # Core package
│ ├── compressor.py # LeastSquaresCompressor
│ ├── models.py # LinearModel, QuadraticModel (Strategy pattern)
│ ├── metrics.py # PSNR, SSIM, MSE
│ ├── io.py # .pfic save/load
│ ├── cli.py # Typer CLI
│ ├── visualization.py # Comparison plots, error heatmaps
│ ├── exceptions.py # Custom exceptions
│ └── quantum/ # Optional quantum module
│ ├── vqls.py # Variational Quantum Linear Solver
│ ├── feature_maps.py # Quantum feature maps
│ ├── hybrid.py # HybridCompressor
│ └── utils.py # State preparation utilities
├── tests/ # Test suite (48+ tests)
├── benchmarks/ # Benchmark runner + dataset download
├── notebooks/ # Jupyter notebooks (demo + quantum tutorial)
├── demo/ # Gradio interactive demo
├── docs/ # MkDocs documentation site
├── DOCS/ # Project documentation (10 documents)
└── examples/ # Example gallery generator
Example Results
| Method | Block Size | PSNR (dB) | SSIM | Compression Ratio |
|---|---|---|---|---|
| Linear | 4x4 | ~28 | 0.89 | 1.3:1 |
| Linear | 8x8 | ~22 | 0.71 | 5.3:1 |
| Linear | 16x16 | ~18 | 0.55 | 21.3:1 |
| Quadratic | 4x4 | ~35 | 0.96 | 0.7:1 |
| Quadratic | 8x8 | ~25 | 0.82 | 2.7:1 |
| Quadratic | 16x16 | ~20 | 0.68 | 10.7:1 |
JPEG at quality 50 typically achieves ~32-35 dB at ~15:1. This project trades quality for algorithmic simplicity and educational value.
Interactive Demo
Run the Gradio demo locally:
pip install -e ".[demo]"
python demo/app.py
Or try the notebook in Colab:
Running Benchmarks
# Download the Kodak dataset
python benchmarks/download_datasets.py --dataset kodak
# Run benchmarks
python benchmarks/run_benchmark.py --dataset benchmarks/datasets/kodak --output benchmarks/results
Development
# Run tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=polyfit_compress --cov-report=term-missing
# Lint + format
ruff check --fix src/ tests/
ruff format src/ tests/
# Type checking
mypy src/polyfit_compress/
# Build docs locally
mkdocs serve
See CONTRIBUTING.md for full development guidelines.
Documentation
- Development Guide — Project overview and implementation details
- Architecture — Design patterns, data flow, file format
- Algorithm Theory — Mathematical foundations
- Quantum Integration — VQLS, feature maps, honest assessment
- Developer Workflow — Conventions, commits, PRs
- Benchmarks Strategy — Reproducible benchmark protocol
- Roadmap — Project phases and milestones
- API Reference — Auto-generated from docstrings (MkDocs)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file polyfit_image_compress-0.1.0.tar.gz.
File metadata
- Download URL: polyfit_image_compress-0.1.0.tar.gz
- Upload date:
- Size: 2.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b32c73a6445f63be967d7d9d94ec4cde0a4d926dd601bfd45eb270a003d2a96b
|
|
| MD5 |
3ac5a9aaac95d03f3c39ac2b2c2cae42
|
|
| BLAKE2b-256 |
6effdd5ca5eb2f23fd53801798f589291d26c2c50b2f09a311510dbd2da60fe5
|
Provenance
The following attestation bundles were made for polyfit_image_compress-0.1.0.tar.gz:
Publisher:
publish.yml on Jelsin29/polyfit-image-compress
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polyfit_image_compress-0.1.0.tar.gz -
Subject digest:
b32c73a6445f63be967d7d9d94ec4cde0a4d926dd601bfd45eb270a003d2a96b - Sigstore transparency entry: 1154684230
- Sigstore integration time:
-
Permalink:
Jelsin29/polyfit-image-compress@de2a860e3f0a19ee534964da0fcbd0d2e6596a03 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Jelsin29
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@de2a860e3f0a19ee534964da0fcbd0d2e6596a03 -
Trigger Event:
push
-
Statement type:
File details
Details for the file polyfit_image_compress-0.1.0-py3-none-any.whl.
File metadata
- Download URL: polyfit_image_compress-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6582364fa85417039f6252592a2090698676a7b032ddf2bd1872ca8b39aec2c0
|
|
| MD5 |
04940b96d15cc4836bc677e3695e0515
|
|
| BLAKE2b-256 |
bdb70ee03fa914ef8d7646b6fd61c801c3d3ed7cc94328e99b6f0995f86d35e6
|
Provenance
The following attestation bundles were made for polyfit_image_compress-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Jelsin29/polyfit-image-compress
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polyfit_image_compress-0.1.0-py3-none-any.whl -
Subject digest:
6582364fa85417039f6252592a2090698676a7b032ddf2bd1872ca8b39aec2c0 - Sigstore transparency entry: 1154684237
- Sigstore integration time:
-
Permalink:
Jelsin29/polyfit-image-compress@de2a860e3f0a19ee534964da0fcbd0d2e6596a03 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Jelsin29
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@de2a860e3f0a19ee534964da0fcbd0d2e6596a03 -
Trigger Event:
push
-
Statement type: