Colorizing the Prokudin-Gorskii photo collection




Fun with Filters

Finite Difference Operator

In order to find the gradient (directional change in intensity) of the cameraman, I approximated the partial derivatives of the image, through convolution with the Dx and Dy kernels. I calculated the gradient magnitude (edge strength), by squaring each of the partial derivatives of the image, then square rooting their sum. This results in a relatively decent edge-detected image, but in order to clean and suppress the noise, I binarized the image at a threshold of magnitude < 0.34.

Dx
Dy
Magnitude
Thresholded Edge

While I was able to clean/suppress noise via thresholding with the previous method, in order to create a smoother edge-detected image, I utilized the Gaussian filter.

First, I created a blurred version of the original image by convolving it with a gaussian, then repeated the previous method, with the threshold at magnitude < 0.2.

Blurred (Convolved with Gaussian)
Dx
Dy
Magnitude
Thresholded Edge

This resulted in a much smoother edge-detected image.

In order to reduce the number of steps/convolutions needed to find an image's smoothed edges, I created a derivative of gaussian filters by convolving the gaussian with the Dx and Dy kernels.

Gaussian x Dx
Gaussian x Dy

With these new DoG filters, I can apply them directly to the original image, without first blurring it with a gaussian convolution.

Dx
Dy
Magnitude
Thresholded Edge

Save for floating point precision errors, the results are nearly identical.

Two Convolutions
One Convolution



Fun with Frequencies

Image Sharpening

Here, I derive the unsharp masking technique in order to sharpen images.

An image looks sharper if it has stronger high frequencies. So, to start, I aimed to find the high frequencies of the image, via subtraction of its low frequencies. First, I use the Gaussian filter to blur the original image (retaining only the low frequencies), then I subtracted this blurred image from the original, resulting in an isolation of its high frequencies. By adding these high frequencies (scaled by an alpha value) back to the original image, we can produce a sharper image.

Original image
Blurred image
High frequencies (orig - blurred)
Sharpened Image (alpha = 5)

Sharpened Image (alpha = 1)
Sharpened Image (alpha = 5)
Sharpened Image (alpha = 10)

From here, we can derive the unsharp mask filter, which will allow us to simplify this method and sharpen images through a single convolution operation. This series of subtractions/additions, f + alpha(f - f * g), where f is the original image, and g is the gaussian, simplifies to (1 + alpha)f - alpha(f * g), which further simplifies down to our unsharp mask filter, defined as f * ((1 + alpha)e - alpha * g), where e is the unit impulse (identify). With this newly derived unsharp mask filter, we only need to perform one convolution in order to sharpen the image for identical results.

Unsharp Filtered Image (alpha = 1)
Unsharp Filtered Image (alpha = 5)
Unsharp Filtered Image (alpha = 10)

For evaluation, I blurred a sharp image, then tried to sharpen it again.

Sharp original image
Blurred image
Re-sharpened Image at alpha = 5

Here's another example, where I sharpen a photo of my dog, Toby.

Original Image of Toby
Toby sharpened at alpha = 5



Hybrid Images

Hybrid images are static images that change in interpretation as a function of the viewing distance. At close proximity, high frequencies tend to dominate perception, but at a distance, only the low frequencies are seen. In order to get a hybrid image that leads to different interpretations at different distances, I follow the approach described by Olivia, Torralba, and Schyns in their SIGGRAPH 2006 paper, by blending the high frequency portion of one image with the low frequency portion of another.

Here, I align images of Derek and Nutmeg, then combine the low-pass frequencies of Derek (found by applying a gaussian filter) with the high frequencies of Nutmeg (by subtracting its low frequencies found via the Guassian).

Derek, low frequencies
Nutmeg, high frequencies
Hybrid

Log magnitude of Fourier transforms:

Derek (orig)
Nutmeg (orig)
Derek (low frequencies)
Nutmeg (high frequencies)
Hybrid image


I also tried using the high frequencies of Derek with the low frequencies of Nutmeg.

Nutmeg, low frequencies
Derek, high frequencies
Hybrid

More Examples

Lucky
Toby
Hybrid
Toby
Lucky
Hybrid

Unfortunately, this method only works well for images that have similar positioning/shapes. As much as I wanted to hybridize a picture of Toby dressed as a pumpkin with a real pumpkin, a dog shape is unfortunately pretty different from a pumpkin shape, and they don't share very many features. So, it was hard to align in a way works well.

Toby
Pumpkin
Hybrid



Multi-resolution blending

Here, I attempted to blend two images seamlessly using multi-resolution blending, as described in Burt and Adelson's 1983 paper. In multi-resolution blending, a gentle seam between two images is separately computed at each band of image frequencies, resulting in a much smoother seam.

To start, I created and visualized Gaussian (GA and GB, for images A and B respectively) and Laplacian stacks (LA and LB, for images A and B respectively), demonstrating the image at different levels of frequency.


Gaussian stacks (GA and GB), levels 0-5 (low to lowest frequency):

Stack 0
Stack 1
Stack 2
Stack 3
Stack 4
Stack 0
Stack 1
Stack 2
Stack 3
Stack 4

Laplacian stacks (LA and LB), levels 0-5 (high to highest frequency):

Stack 0
Stack 1
Stack 2
Stack 3
Stack 4
Stack 0
Stack 1
Stack 2
Stack 3
Stack 4

I also built a Gaussian stack (GR) for the mask. Then, using all of the created stacks, I formed a combined stack LS from LA and LB, using nodes of GR as weights:

LS = GR * LA + (1 - GR) * LB

Finally, to obtain a combined splined image, I summed each level of LS, creating the following image:

More Examples

Toby
Clouds
Irregular Mask
Toby in Clouds
Jellyfish
Night Sky
Irregular Mask
Giant Jellyfish in Sky

Stacks with Binary Masks applied for Giant Sky Jellyfish:

Stack 0
Stack 2
Stack 2
Stack 3
Stack 4
Stack 0
Stack 2
Stack 2
Stack 3
Stack 4
Stack 0
Stack 2
Stack 2
Stack 3
Stack 4
Stack 0
Stack 2
Stack 2
Stack 3
Stack 4