CS180 Proj1 · Colorizing the Prokudin-Gorskii Photo Collection

Split BGR plates → align G/R to B using ZNCC on Sobel-grad features with ratio-based border cropping → compose RGB. Coarse-to-fine pyramid for .tif.

Sep 12, 2025 · Weiyi Zhang

Overview

Each input plate stacks B-G-R vertically. I split channels, then translate-align G/R to B by maximizing ZNCC on Sobel gradient magnitude with interior-only comparison (ratio-based border crop). For large .tif plates, a coarse-to-fine image pyramid yields accurate and fast alignment.

Original BGR plate
Input · BGR plate (top→bottom: B, G, R)
Colorized output
Output · Aligned & composed RGB

Methodology

Single-scale alignment (baseline, small JPGs)

  1. Split: split_bgr_plate() slices the vertical plate into B, G, R.
  2. Feature: optionally convert to Sobel gradient magnitude (feature_grad() / grad_mag()).
  3. Interior-only metric: crop_interior() supports pixel or ratio borders.
  4. Search: exhaustive translations within [-R, R] (default ±15 px).
  5. Score: ZNCC (zncc()) on the cropped interior; pick the max.
  6. Compose: stack aligned [R, G, B] to RGB and save.
Implementation notes: crop_interior() accepts int (pixels) or float (ratio); ZNCC is “higher is better”.

Coarse-to-fine pyramid (large TIFs)

  1. Downsample: build pyramids from coarse → fine with factor scale = 0.5.
  2. Coarsest init: run local search at coarsest level using Sobel + ZNCC.
  3. Propagate: rescale offsets by ×2 at each finer level.
  4. Refine: refine with a small-radius local search.
  5. Ratio crop: use ratio borders (e.g., 0.08).
Key routines: build_pyramid(), align_local_search(), align_pyramid().

Results (with Offsets)

Colorized outputs with corresponding offsets (G,R relative to B).

cathedral
cathedral.jpg
G:(+2,+5), R:(+3,+12)
single · NCC
monastery
monastery.jpg
G:(+2,-3), R:(+2,+3)
single · NCC
tobolsk
tobolsk.jpg
G:(+2,+3), R:(+3,+6)
single · NCC
church
church.tif
G:(+4,+25), R:(-4,+58)
pyramid · edges+ZNCC
emir
emir.tif
G:(+23,+49), R:(+40,+107)
pyramid · edges+ZNCC
harvesters
harvesters.tif
G:(+17,+60), R:(+14,+124)
pyramid · edges+ZNCC
icon
icon.tif
G:(+17,+42), R:(+23,+90)
pyramid · edges+ZNCC
italil
italil.tif
G:(+22,+38), R:(+36,+77)
pyramid · edges+ZNCC
lastochikino
lastochikino.tif
G:(-2,-3), R:(-8,+76)
pyramid · edges+ZNCC
lugano
lugano.tif
G:(-17,+41), R:(-29,+92)
pyramid · edges+ZNCC
melons
melons.tif
G:(+10,+80), R:(+13,+177)
pyramid · edges+ZNCC
self_portrait
self_portrait.tif
G:(+29,+78), R:(+37,+176)
pyramid · edges+ZNCC
siren
siren.tif
G:(-7,+49), R:(-24,+96)
pyramid · edges+ZNCC
three_generations
three_generations.tif
G:(+12,+54), R:(+9,+111)
pyramid · edges+ZNCC

LoC Extras

Additional images from the Library of Congress collection. Only colorized outputs are shown. Offsets are (G,R) relative to B, format (dx, dy), right/down positive.

test1
test1.tif
G:(+34,+56), R:(+60,+125)
pyramid · edges+ZNCC
test2
test2.tif
G:(+4,+63), R:(-1,+132)
pyramid · edges+ZNCC
test3
test3.tif
G:(-7,+15), R:(-17,+83)
pyramid · edges+ZNCC
test4
test4.tif
G:(+15,+41), R:(+25,+91)
pyramid · edges+ZNCC
Tip: outputs are saved to ./out/ as testX_color.jpg. Offsets filled from console logs. Input plates are intentionally omitted.

Discussion

Failures, lessons, runtime