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.
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.
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.
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
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