NiranjanSathish's picture
Upload 41 files
f647a80 verified

A newer version of the Gradio SDK is available: 6.13.0

Upgrade
metadata
title: Advanced Mosaic Generator
emoji: 🎨
colorFrom: blue
colorTo: purple
sdk: gradio
sdk_version: 4.7.1
app_file: app.py
pinned: false
license: mit

Advanced Contextual Mosaic Generator (Numba-Optimized)

An AI-powered mosaic generation system with Numba JIT compilation for 20-30x performance speedup, contextual awareness, and advanced computer vision techniques. Creates high-quality photo mosaics using intelligent tile selection and parallel processing.

🎯 Key Highlights

  • ⚑ 20-30x Faster: Numba JIT compilation on computational bottlenecks
  • 🧠 Context-Aware: Scene classification for intelligent tile placement
  • 🎨 High Quality: Global SSIM and color similarity metrics
  • πŸ“Š Professional: Production-ready Gradio deployment
  • πŸ”§ Optimized Pipeline: Parallel processing and vectorized operations

Features

Performance Optimizations

  • Numba JIT Compilation: 3-15x speedup on core algorithms
    • extract_cell_colors_numba: 5-10x faster cell color extraction
    • compute_squared_distances_numba: 3-5x faster distance calculations
    • assemble_mosaic_numba: 2-4x faster mosaic assembly
  • Parallel Processing: Multi-threaded tile matching for large grids
  • Smart Caching: Global cache system to avoid redundant computations
  • Optimized Preprocessing: Aggressive sampling for color quantization
  • Lazy Loading: On-demand resource initialization

Core Capabilities

  • Contextual Awareness: Scene classification for intelligent processing
  • Multi-Scale Processing: Support for various grid sizes (16Γ—16 to 128Γ—128)
  • Rotation Variants: 4-way tile rotation for increased diversity
  • Color Optimization: Mini-Batch K-means clustering with color subgrouping
  • Enhanced Metrics: Global SSIM, color similarity, histogram matching
  • Web Interface: Fast, responsive Gradio deployment with async metrics

Advanced Features

  • Smart Preprocessing: Automatic image resizing with grid-perfect alignment
  • Color Quantization: Optional color reduction for artistic effects
  • Diversity Control: Anti-repetition algorithms for natural-looking results
  • Cache System: Pre-built tile caches for instant deployment
  • Grid Visualization: Visual feedback showing image segmentation
  • Async Metrics: Images displayed immediately, metrics calculated after

Performance Benchmarks

Speedup Comparison (Unoptimized vs Numba-Optimized)

Grid Size Unoptimized Numba-Optimized Speedup Time Saved
16Γ—16 (256 tiles) 0.203s 0.008s 9.64x 89.6%
32Γ—32 (1,024 tiles) 0.739s 0.024 30.53x 96.7%
64Γ—64 (4,096 tiles) 2.636s 0.088s 77.92x 98.7%

Average Speedup: 39.36x faster | Maximum Speedup: 77.92x

Memory Requirements

  • Base System: ~500MB
  • With Caches: ~2-4GB (depending on tile count and rotation)
  • Processing Peak: ~3-6GB (for 128Γ—128 grids)

Installation

Quick Setup

# Clone the repository
git clone https://github.com/NiranjanSathish/advanced-mosaic-generator
cd advanced-mosaic-generator

# Install dependencies
pip install -r requirements.txt

# Create tile folder and add your tile images
mkdir extracted_images
# Add your 32Γ—32 tile images to this folder

Dependencies

numpy>=1.24.0
opencv-python-headless>=4.8.0
scikit-learn>=1.3.0
scipy>=1.11.0
numba>=0.58.0          # Critical for performance!
gradio>=4.0.0
scikit-image>=0.21.0
tqdm>=4.66.0
Pillow>=10.0.0

System Requirements

  • Python: 3.9 or higher
  • Numba: Requires compatible CPU (most modern x86-64 CPUs supported)
  • RAM: 8GB minimum, 16GB recommended for large grids
  • Storage: 100MB-5GB depending on tile dataset size

Usage

1. Web Interface (Recommended)

python app.py

Access the interface at http://localhost:7860

Features:

  • πŸ–ΌοΈ Drag-and-drop image upload
  • βš™οΈ Real-time parameter adjustment
  • πŸ“Š Grid visualization preview
  • πŸ“ˆ Performance metrics display
  • ⚑ One-click presets (Fast/Quality)
  • πŸ”₯ Numba JIT status indicator

2. Command Line Interface

python main.py

Example configuration:

from main import create_advanced_mosaic

mosaic, metrics, context = create_advanced_mosaic(
    image_path="Images/EmmaPotrait.jpg",
    grid_size=(64, 64),
    tile_size=(32, 32),
    diversity_factor=0.15,
    enable_rotation=True,
    use_numba=True,           # Enable Numba (default)
    use_parallel=True,        # Enable parallel processing (default)
    evaluate_quality=True,
    show_visualizations=False
)

3. Building Custom Caches

# Build optimized tile caches with rotation
python -c "from Numba_Scripts.Cache_Builder import TileCacheBuilder; \
builder = TileCacheBuilder('extracted_images', (32, 32), 8, True); \
builder.build_cache('cache_32x32_bins8_rot.pkl', force_rebuild=True)"

Project Structure

advanced-mosaic-generator/
β”œβ”€β”€ app.py                         # Gradio web interface 
β”œβ”€β”€ Numba_Scripts/                  # Optimized 
β”‚   β”œβ”€β”€ main.py                     # CLI mosaic generator
β”‚   β”œβ”€β”€ Cache_Builder.py            # Tile cache builder
β”‚   β”œβ”€β”€ contextual_Mosaic_Builder.py # Numba-optimized
β”‚   β”œβ”€β”€ ImagePreprocessor.py    
β”‚   β”œβ”€β”€ Performance_metrics.py      # Quality metrics
β”‚   β”œβ”€β”€ numba_optimizations.py      # Numba JIT functions
β”‚   └── ColourClassification.py     # Grid analysis
β”œβ”€β”€ Images/                         # Example images
β”œβ”€β”€ extracted_images/               # Tile dataset 
β”œβ”€β”€ cache_*.pkl                     # Pre-built caches
β”œβ”€β”€ requirements.txt                # Python dependencies
└── README.md                       # This file

Configuration Options

Grid Settings

  • Grid Size: 16Γ—16 to 128Γ—128 tiles (controls detail level)
  • Tile Size: 16Γ—16, 32Γ—32, or 64Γ—64 pixels (must match cache)
  • Diversity Factor: 0.0-0.5 (0.0 = exact color match, 0.5 = maximum variety)

Optimization Settings

  • Use Numba: Enable JIT compilation (recommended: True)
  • Use Parallel: Enable parallel processing (recommended: True)
  • Enable Rotation: Use rotation variants (requires rotated cache)

Quality Settings

  • Color Bins: 4-24 color categories for tile grouping
  • Quantization: Optional color reduction (0 = off, 4-24 colors)
  • Face Detection: Can be enabled for portrait photos (adds overhead)

Performance Modes

⚑ Fast Mode

grid_size = (24, 24)
tile_size = (32, 32)
diversity_factor = 0.1
use_numba = True
use_parallel = True

Result: ~0.05-0.15s generation time

πŸ’Ž Quality Mode

grid_size = (128, 128)
tile_size = (16, 16)
diversity_factor = 0.0
use_numba = True
use_parallel = True

Result: ~2-5s generation time, maximum detail

Algorithm Pipeline

  1. Preprocessing (0.05-0.2s)

    • Smart resize with aspect ratio preservation
    • Grid-perfect cropping
    • Optional color quantization
  2. Context Analysis (0.01-0.05s)

    • Scene classification (portrait/landscape)
    • Dominant color extraction
    • Content complexity estimation
  3. Mosaic Generation (0.05-3s depending on grid)

    • Numba-compiled cell color extraction
    • Parallel distance computation
    • Optimized tile assembly
  4. Quality Metrics (0.5-2s, calculated async)

    • Global SSIM calculation
    • Color similarity analysis
    • Histogram matching

Color Subgrouping Optimization

Instead of searching through all tiles (~800 with rotation):

  1. Cluster tile colors into 8 bins using K-means
  2. For each grid cell, find nearest color bin (~8 comparisons)
  3. Search only within that bin (~100 tiles)
  4. Use KD-tree for nearest neighbor search

Result: 10x faster tile matching!

Quality Metrics

Global SSIM (Structural Similarity):

  • Treats entire image as single entity
  • Computes global statistics (mean, variance, covariance)
  • More meaningful than windowed SSIM for mosaics
  • Range: -1 to 1 (>0.8 = excellent)

Global Color Similarity:

  • Compares global color distributions
  • Mean color distance + variance similarity
  • Range: 0 to 1 (>0.9 = excellent)

Deployment

Hugging Face Spaces

  1. Create a new Space

    • SDK: Gradio
    • Hardware: CPU Basic (free tier works!)
  2. Upload files:

    app.py
    requirements.txt
    packages.txt
    README.md
    Numba_Scripts/ (entire folder)
    extracted_images/ (entire folder)
    Images/ (example images)
    cache_*.pkl (pre-built caches)
    
  3. The app will auto-deploy and be live in 2-3 minutes!

Local Deployment with Share Link

python app.py
# Gradio will provide a public share link valid for 72 hours

Troubleshooting

Common Issues

"Numba not available"

pip install numba
# If on Apple Silicon Mac:
conda install numba

"No cache available"

# Build cache for 32Γ—32 tiles
cd Numba_Scripts
python Cache_Builder.py

"Module not found: numba_optimizations"

  • Ensure Numba_Scripts/numba_optimizations.py exists
  • Check Python path in app.py points to correct folder

"Images loading slowly in Gradio"

  • Images are resized to 1024px max for display
  • Metrics calculated after images are shown
  • This is normal behavior for large grids

Cache Rebuilding

# Rebuild cache with rotation
python -c "
import sys; 
sys.path.insert(0, 'Numba_Scripts');
from Cache_Builder import TileCacheBuilder;
builder = TileCacheBuilder('extracted_images', (32, 32), 8, True);
builder.build_cache('cache_32x32_bins8_rot.pkl', force_rebuild=True)
"

Technical Innovations

1. Numba JIT Compilation

Optimized Functions:

@jit(nopython=True, parallel=True, fastmath=True, cache=True)
def extract_cell_colors_numba(image, grid_rows, grid_cols):
    # 5-10x faster than NumPy for grid operations
    # Parallel execution across grid cells
    # Direct mean calculation with minimal allocations

Benefits:

  • Compiled to native machine code
  • Parallel execution with prange
  • No Python interpreter overhead
  • Automatic CPU optimization

2. Color Subgrouping Optimization

Without Optimization:

  • Search through 792 tiles (with rotation) for each cell
  • 64Γ—64 grid = 4,096 cells Γ— 792 comparisons = 3.2M operations

With Optimization:

  • Cluster tiles into 8 color bins
  • Search only ~100 tiles per bin
  • 4,096 cells Γ— ~100 comparisons = 410K operations
  • ~8x reduction in comparisons

3. Parallel Processing

For grids with multiple color bins:

  • Process color bins in parallel using ThreadPoolExecutor
  • 4 concurrent workers for tile matching
  • Significant speedup for diverse images

4. Global Quality Metrics

Why Global SSIM?

  • Traditional SSIM uses sliding windows (not meaningful for mosaics)
  • Global SSIM treats image as single entity
  • Computes global statistics (mean, variance, covariance)
  • More accurate for mosaic quality assessment

Metrics Calculated:

  • MSE (Mean Squared Error)
  • PSNR (Peak Signal-to-Noise Ratio)
  • Global SSIM (Structural Similarity)
  • Global Color Similarity
  • Histogram Correlation
  • Composite Quality Score (0-100)

### Gradio Integration

```python
from app import create_mosaic_interface

# Process through Gradio interface
mosaic, comparison, grid_viz, metrics, status = create_mosaic_interface(
    image=image_array,
    grid_size=64,
    tile_size=32,
    diversity_factor=0.15,
    enable_rotation=False,
    apply_quantization=False,
    n_colors=12
)

File Descriptions

Core Files

  • app.py: Gradio web interface with Numba support, async metrics
  • requirements.txt: Python dependencies including Numba
  • packages.txt: System dependencies for HF Spaces deployment

Numba_Scripts/ (Optimized Implementation)

  • main.py: CLI entry point with full control
  • Cache_Builder.py: Builds tile caches with rotation variants
  • contextual_Mosaic_Builder.py: Numba-optimized mosaic engine
  • numba_optimizations.py: JIT-compiled performance functions
  • ImagePreprocessor.py: Optimized preprocessing pipeline
  • Performance_metrics.py: Quality evaluation system
  • ColourClassification.py: Grid analysis and classification

Unoptimized_Scripts/ (Baseline)

  • Same structure as Numba_Scripts but without optimizations
  • Used for performance benchmarking
  • Demonstrates 10-15x speedup from optimizations

Configuration Guide

For Speed (⚑ Fast Mode)

grid_size = (24, 24)      # Fewer tiles
tile_size = (32, 32)      # Standard size
diversity_factor = 0.1    # Low diversity
use_numba = True          # Enable JIT
use_parallel = True       # Enable threading
apply_quantization = False # Skip quantization

Result: 0.05-0.15s generation

For Quality (πŸ’Ž Quality Mode)

grid_size = (128, 128)    # Maximum detail
tile_size = (16, 16)      # Smaller tiles
diversity_factor = 0.0    # Exact color matching
use_numba = True          # Still fast with Numba!
use_parallel = True       # Parallel processing
apply_quantization = False # Preserve colors

Result: 1-3s generation (vs 30-40s unoptimized!)

Custom Tile Dataset

  1. Prepare 32Γ—32 pixel images
  2. Place in extracted_images/ folder
  3. Build cache:
from Numba_Scripts.Cache_Builder import TileCacheBuilder

builder = TileCacheBuilder(
    tile_folder="extracted_images",
    tile_size=(32, 32),
    colour_bins=8,
    enable_rotation=True
)

builder.build_cache("cache_32x32_bins8_rot.pkl", force_rebuild=True)

Disable Numba (for debugging)

# In main.py or when calling functions
mosaic, metrics, context = create_advanced_mosaic(
    ...,
    use_numba=False  # Use NumPy fallback
)

Development Setup

# Install dev dependencies
pip install -r requirements.txt
pip install pytest black flake8

# Run tests
pytest tests/

# Format code
black .

Performance Tips

  1. Start Small: Test with 32Γ—32 grid first
  2. Use Numba: 10-15x speedup is worth it!
  3. Pre-build Caches: Don't rebuild during production
  4. Limit Grid Size: 128Γ—128 max for web deployment
  5. Disable Face Detection: Unless needed for portraits
  6. Skip Quantization: Usually not needed for good results