Project 1: Image Filtering and Hybrid Images

Dogs and cats together, oh my!

This project explores the world of hybrid images. A hybrid image is an image composed of two different images combined so that one can been seen when viewing the image up close, one image is seen, and when viewing the image from afar, a different image is seen. These images can be crafted by filter the two images with a low and a high pass filter. When combined, the low pass filtered image is the one seen from afar, and the high pass filtered image is the one seen from up close. In order to get a low pass filter, a simple Gaussian blur can be applied. And for the high pass filter, a Gaussian blur can be subtracted. Applying these two filters two our images and combining the filtered image gives us our hybrid image, such as the dog and cat bybrid image shown to the right.

My Implementation of my_imfilter

Below is my implementation of my_imfilter. It is a fairly straightforward implementation of the fitlering algorithm given in the book, simply using for loops to loop over the whole image. For each pixel, the section corresponding to that pixel and matching the size of the filter is retrieved from the image. Then, both are multiplied together element wise and summed up to get the final pixel value. Finally, the value is set in the array. Before the filtering is done though, the image must be padded so that the filter can be applied to every pixel. For my implementation, I chose to simply add extra '0's the the border in order to add enough spacing for the filter. This gave pretty good results with borders being seen on the intermediate images, but since one is subtracted, the final image looks pretty good.


% If our filter dimensions are not odd, don't filter and just return the original image
% as the output
if (mod(size(filter, 1), 2) == 0) || (mod(size(filter, 2), 2) == 0)
    output = image;
else
    % Add padding so that the filter works on all elements of the image
    xPad = floor(size(filter, 2) / 2);
    yPad = floor(size(filter, 1) / 2);
    padded = padarray(image, [yPad xPad]);
    output = padded;
    
    % Iterate over every color channel of the image
    for colorChannel=1:size(padded, 3)
        % Iterate over every row of the image
        for row=1+yPad:size(padded, 1)-yPad
            % Iterate over every column of the image
            for col=1+xPad:size(padded, 2)-xPad
                % For each pixel in the image to be filtered, first grab the section that
                % needs to be filtered from the image currently
                filterSection = padded(row-yPad:row+yPad, col-xPad:col+xPad, colorChannel);
                % Then multiply that section by the filter
                filteredPixels =  filterSection .* filter;
                % Sum the values to get the final pixel value
                pixelValue = sum(filteredPixels(:));
                % Set that value in our output image
                output(row, col, colorChannel) = pixelValue;
            end
        end
    end
    
    % Crop the padding out of the image and return it
    outputRowStart = yPad + 1;
    outputRowEnd = size(output, 1) - yPad;
    outputColStart = xPad + 1;
    outputColEnd = size(output, 2) - xPad;
    output = output(outputRowStart:outputRowEnd, outputColStart:outputColEnd, :);
end

Sample Hybrid Images

Above are samples of some of my hybrid images. Personally, I think that the hybrid cat/dog image looks the best, and the hybrid bicycle/motorcycle image looks the worst. This is most likely due to the fact that the dog and cat are fairly similar in color and position within the image. They both have somewhat similar features, and even when switching between the two, the change is not very extreme. However, with the bicycle and motorcycle, the changes are a bit more extreme, with the center of the bicycle being white and the center of the motorcycle being black. The bicycle and motorcycle also have a number of sharp features such as the handle bars and tires which don't match up quite as well as the dog and cat. The following cutoff frequencies where used to produce each image: