This project implements automatic alignment of Prokudin-Gorskii glass plate photographs using computer vision techniques.
The Prokudin-Gorskii collection contains early color photographs taken by Sergei Mikhailovich Prokudin-Gorskii between 1907-1915. Each image consists of three separate exposures (Blue, Green, Red channels) that need to be aligned to create a single color photograph.
- Single-scale alignment for small JPEG images using exhaustive search
- Multi-scale pyramid alignment for large TIFF images using coarse-to-fine optimization
- Edge-based features using Sobel gradients for robust alignment
- Normalized Cross-Correlation (NCC) scoring metric
- Bells & Whistles enhancements:
- Automatic border cropping
- White balance correction
- Automatic contrast adjustment
pip install Pillow scipy numpyfrom main import ProkudinGorskiiAligner
# Create aligner instance
aligner = ProkudinGorskiiAligner()
# Process a single image
aligner.process("images/cathedral.jpg", "output/cathedral_restored.jpg")# Process all images in a directory
aligner.batch_process("images", "output")
# Process specific images
subset = ["cathedral.jpg", "monastery.jpg", "emir.tif"]
aligner.batch_process("images", "output", file_list=subset)python main.py- Used for small images (cathedral.jpg, monastery.jpg, tobolsk.jpg)
- Exhaustive search over displacement window [-15, 15] pixels
- Direct application of NCC metric on Sobel edge features
- Used for large images (emir.tif, harvesters.tif, etc.)
- Recursive coarse-to-fine alignment across 5 pyramid levels
- 2x downsampling at each level using scipy.ndimage.zoom
- Refines alignment with ±2 pixel search at each level
- Sobel gradient magnitude:
sqrt(dx² + dy²)using scipy.ndimage.sobel - Robust to brightness differences between channels
- Essential for problematic images like emir.tif
- Image I/O: PIL (Pillow) for reading and writing images
- Edge detection: scipy.ndimage.sobel for gradient computation
- Image resizing: scipy.ndimage.zoom for pyramid downsampling
- Normalization: numpy operations for 8-bit conversion
├── main.py # Main implementation
├── images/ # Input images directory
│ ├── cathedral.jpg
│ ├── monastery.jpg
│ ├── emir.tif
│ └── ...
├── output/ # Generated output directory
├── index.html # Results webpage
└── README.md # This file
search_range=15: Maximum displacement search windowpyramid_depth=5: Number of pyramid levels for multi-scale alignmentcrop_ratio=0.15: Border cropping ratio to avoid edge artifacts
See index.html for visual results and computed alignment offsets for all processed images.
Mohak Sharma (ms7306)