Project 1: Image Filtering and Hybrid Images

The goal of this project is to demonstrate the creation of hybrid images as explained in this paper. An example of such an image is given above. The novel effect of these hybrid images is that one image is easier to see when the image is closeup/large and the other becomes clearer when the image is far away/small. Watch as the fish becomes a submarine at smaller dimensions.

Procedure

This effect is achieved by taking two images, applying a low-pass (blur) filter to one, and a high-pass (subtracting the lowpass) filter to the other. Then adding the two images point-wise to create a hybrid image using the low-frequencies of one image and the high frequencies of another. Since low frequencies are more visible at a distance, the low-passed image becomes clearer as the image gets smaller while the high frequencies attenuate at farther distances. The distance you view the image at changes which one of the two input pictures is most visible!

Filtering

The core piece needed to do these hybrid images is to create the lowpass and highpass filters. For this project I implemented a generic my_imfilter() function to apply any filter to an input image.

Source code


function output = my_imfilter(image, filter)
output = zeros(size(image));

% filter dims must be odd, calculate the distance from the center
[fh, fw] = size(filter);
fh = floor(fh/2);
fw = floor(fw/2);
% pad the input image so the convolution works at the borders
padded = padarray(image,[fh,fw],'symmetric');
% iterate through each pixel and color in the input image
[rows, cols, colors] = size(image);
for r = 1:rows
    for c = 1:cols
        for rgb = 1:colors
            target = padded(r:r+2*fh,c:c+2*fw,rgb);
            o = sum(sum(target.*filter));
            output(r,c,rgb) = o;
        end
    end
end

The idea here is that every image filter is a matrix, and gets computed the same way. So the low-pass Gaussian filter that gets used to blur the images is no different than an edge detector or sharpening filter as far as my image filtering function is concerned.

The filter goes row-by-row down the input image, multiplying pixels on each RGB channel point-wise by the filter kernel, then summing them to make a single point in the output image.

In order to keep the input and output the same size, I padded the input image by mirroring itself along the edges so that the filter along the edges of the image does not go out of bounds. I chose this particular solution instead of padding with zeros so that there is no weird black-border around the output image. Most of the input images have a uniform color background and the padding is relatively small (half the kernel size), so it actually works to approximate what a true "un-cropped" version of the picture might look like.

Filter gallery

Identity Box blur High pass Sharpen
Gaussian blur Motion blur Laplacian high pass Sobel

Example filter kernels


identity_filter =

     0     0     0
     0     1     0
     0     0     0

blur_filter =

    0.1111    0.1111    0.1111
    0.1111    0.1111    0.1111
    0.1111    0.1111    0.1111

high_pass_image = test_image - blur_image; %simply subtract the low frequency content

sharpen_filter =

   -0.1250   -0.1250   -0.1250   -0.1250   -0.1250
   -0.1250    0.2500    0.2500    0.2500   -0.1250
   -0.1250    0.2500    1.0000    0.2500   -0.1250
   -0.1250    0.2500    0.2500    0.2500   -0.1250
   -0.1250   -0.1250   -0.1250   -0.1250   -0.1250

gaussian_filter = fspecial('Gaussian', [25 25], 10)

motion_blur_filter = diag(ones(1,21)/21);

laplacian_filter =

     0     1     0
     1    -4     1
     0     1     0

sobel_filter =

    -1     0     1
    -2     0     2
    -1     0     1

The results above show some examples of image filters applied using my function. Note that I added the motion blur and sharpening filters which were not part of the sample code.

Hybrid Image Gallery

Below are example hybrid images used by combining low frequencies with high frequencies in two pairs of images. As the images get smaller, the low frequences should stand out. As the images get larger, the high frequencies should stand out. The particular high/low cutoff was determined experimentally, as there is no really objective way to decide what cutoff looks the best, and it varies for each pair of images.

Images that are already relatively similar work the best. Here I also demonstrate a landscape ocean/mountain hybrid that is not one of the provided sample images.

Mountain and Beach

Low FrequenciesHigh Frequencies
Hybrid Result

Bike and Motorcycle

Low FrequenciesHigh Frequencies
Hybrid Result

Cat and Dog

Low FrequenciesHigh Frequencies
Hybrid Result

Marilyn and Einstein

Low FrequenciesHigh Frequencies
Hybrid Result

Plane and Bird

Low FrequenciesHigh Frequencies
Hybrid Result

Submarine and Fish

Low FrequenciesHigh Frequencies
Hybrid Result