Project 1: Image Filtering and Hybrid Images

A copy of the cat/dog merger from the original paper made with my code

This project approached image filtering and merging with the goal of creating hybrid images that look different when viewed from close up vs. far away. The image on the right is an example of such a hybrid image. When viewed from up close, it looks like a kitten, but from far away it appears to be a cute pupper instead.

Implementation

There were two main components in implementing this form of image merging: generalized image filtering and the compositing of seperate images given low and high pass filters. The first part of this was very straighforward in matlab, simply loop through the channels, and then for each location in the resulting image, filter the source image and place the result in the correct place in the output matrix, as in the code below.


    [filter_width, filter_height] = size(filter);
    dx = (filter_width-1)/2;
    dy = (filter_height-1)/2;
    [image_width, image_height, color_channels] = size(image);
    output = zeros(image_width, image_height, color_channels);
    padded = padarray(image, [dx, dy]);

    for c = 1:color_channels
        for x = 1: image_width
            for y = 1: image_height
                output(x, y, c) = sum(sum(filter.*double(padded(x:x+dx*2,y:y+dy*2,c))));
            end
        end
    end

Merging the two images was even simpler: a gaussian blur and some matrix addition.


filter = fspecial('Gaussian', cutoff_frequency*4+1, cutoff_frequency);
low_frequencies = my_imfilter(image1, filter);
high_frequencies = image2 - my_imfilter(image2, filter);
hybrid_image = (low_frequencies + high_frequencies);

Here is the output image at various scales to help visualize the change as you pull away.

For another example, I've taken a picture of a friend of mine and her father, and merged them, but used some additional code to loop through and pick good values for the high and low passes automatically.


for i = 1:10
    cutoff_frequency = 2*i + 1;
    filter = fspecial('Gaussian', cutoff_frequency*4+1, cutoff_frequency);
    low_frequencies = my_imfilter(image1, filter);
    high_frequencies = image2 - my_imfilter(image2, filter);
    hybrid_image = (low_frequencies + high_frequencies);

    %% Visualize and save outputs
    figure(1); imshow(low_frequencies)
    figure(2); imshow(high_frequencies + 0.5);
    vis = vis_hybrid_image(hybrid_image);
    figure(3); imshow(vis);
    imwrite(hybrid_image, strcat('image_', i,'.jpg'), 'quality', 95);
end;

Using more or less that code and the following two images, I created a series of images to pick the best merger

Here are those resulting images, they range from less to more of the father as the gaussian filter used gets larger and larger. image_2 gives, in my opinion, the best result.

And here is the full pyramid for image2

This image shows a good blending, and while not as good as the others, the alignment works well enough that the image resmebles her father at close ranges, but the girl when far away.