Skip to main content

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.

CI Python 3.10+ License: MIT


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:

Open 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


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polyfit_image_compress-0.1.0.tar.gz (2.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

polyfit_image_compress-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

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

Hashes for polyfit_image_compress-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b32c73a6445f63be967d7d9d94ec4cde0a4d926dd601bfd45eb270a003d2a96b
MD5 3ac5a9aaac95d03f3c39ac2b2c2cae42
BLAKE2b-256 6effdd5ca5eb2f23fd53801798f589291d26c2c50b2f09a311510dbd2da60fe5

See more details on using hashes here.

Provenance

The following attestation bundles were made for polyfit_image_compress-0.1.0.tar.gz:

Publisher: publish.yml on Jelsin29/polyfit-image-compress

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file polyfit_image_compress-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for polyfit_image_compress-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6582364fa85417039f6252592a2090698676a7b032ddf2bd1872ca8b39aec2c0
MD5 04940b96d15cc4836bc677e3695e0515
BLAKE2b-256 bdb70ee03fa914ef8d7646b6fd61c801c3d3ed7cc94328e99b6f0995f86d35e6

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page