CS 143 / Project 1 / Image Filtering and Hybrid Images


The goal of this assignment is to write an image filtering function and use it to create hybrid images using a simplified version of the SIGGRAPH 2006 paper by Oliva, Torralba, and Schyns. Hybrid images are static images that change in interpretation as a function of the viewing distance. The basic idea is that high frequency tends to dominate perception when it is available, but, at a distance, only the low frequency (smooth) part of the signal can be seen. By blending the high frequency portion of one image with the low-frequency portion of another, you get a hybrid image that leads to different interpretations at different distances.

Example of a right floating element.

Summary


The assignment required that we implement a discrete convolution function that is suited for images. This meant getting 'filter size' windows of the image and applying a weighted sum of the filter and the image window. Additionally, the border of the image needed to be padded so that the border windows would have all the elements defined. In the end, padding using a reflection of the image over the border provided the best results.

The Code


I tried as best I could to favor Matlab built in functions over loops. I was able to achieve this except for the im2col function which apparently doesn't play nice with multiple channels.

My first implementation had a loop over image windows. By switching from that to a matrix multiplication my filtering operation had a speed up factor of 10.9472 (from 2.787225 seconds to .254607 seconds) on a Gaussian blur of size [25 1]. Here is a comparsion of the code.

Slow code


for channel = 1:size(image,3) 
   cols = im2col(pad_image(:,:,channel), size(filter)); %get image windows
   out = zeros(1, size(cols, 2));
   for i = 1:size(cols,2)
       out(i) = sum(sum(filter.* reshape(cols(:,i), size(filter)))); %Apply filter to window
   end
   output(:,:,channel) = col2im(out, [1 1], [size(image, 1), size(image,2)]);
end

Improved code


 for channel = 1:size(image,3) 
   cols = im2col(pad_image(:,:,channel), size(filter)); %get image windows
   output(:,:,channel) = col2im(filter_reshaped * cols, [1 1], [size(image, 1), size(image,2)]); %apply filter 
end

Results


Cat and Dog

Source Images:

Intermediary Images:

Hybrid:


Submarine and Fish

Source Images:

Intermediary Images:

Hybrid:


Marilyn and Einstein

Source Images:

Intermediary Images:

Hybrid: