Project 1: Image Filtering and Hybrid Images

Example of a hybrid image.

The goal of this project is to create hybrid images through combining the low frequencies of one image with the high frequencies of another image. The result is a hybrid image which appears to be one image when viewed close up and another image when viewed from far away or at a lower resolution. This effect is achieved because high frequencies are more visible when then image is viewed from a short distance, while only low frequencies are visible at far distances. This writeup will describe the filtering process and the resulting hybrid images.

Image Filtering

I implemented my_imfilter.m which takes in an RGB image and a filter with odd width and height and returns the filtered image. The behavior is similar to that of the matlab function imfilter(). The function first checks to make sure that the inputted filter has an odd width and height:

%check that width and height are odd
if ( mod(size(filter,1),2)~=1 || mod(size(filter,2),2)~=1 )
    output=0;
    disp('Error: input filter must have odd width and height.')
    return;
end

Next, the image is padded on the sides with zeros. The padding has a size of half of the filter width/height rounded down, as follows:

%pad input image on sides with zeros
padsize=[0 0 0];
padsize(1)=floor(size(filter,1)/2);
padsize(2)=floor(size(filter,2)/2);
padimage=padarray(image,padsize,0);

The image can also be padded instead by mirrored pixels at its edges. This may create a better result when filtering, since using padding consisting of zeros can result in decreasing the overall magnitude of the filtered result at the edge. The Matlab function padarray() has an option to pad with mirrored pixels, as follows:

padimage=padarray(image,padsize,'symmetric');

Finally, the correlation is performed on the padded image with the filter. This process is done using a simple for loop and Matlab's dot product operator .*:

%do correlation
newimage=image*0;
for k=1:size(image,3)
    for n=1:size(image,1)
        for m=1:size(image,2)
             newimage(n,m,k)=sum(sum(padimage(n:n+size(filter,1)-1,m:m+size(filter,2)-1,k).*filter));
        end
    end
end

Results for Image Filtering

Shown here are results for 7 different filters. These were created using the mirrored padding scheme to handle filtering at the edges. The first image is the original image. The next image is a filter which should return the original image if everything was done correctly. The next two images are blurring images with a gaussian kernel. In the bottom row, the first two images are Sobel filters which highlight horizontal and vertical gradients, respectively. The last two images are different high pass filters. The second to last image is a discrete laplacian filter while the last image is obtained by simply subtracting out the blurred image.

Creating Hybrid Images

Now that we have the code to filter an image, creating hybrid images is easy. We simply take two images, blur one and remove the blur from another, then add them up. We may need to adjust the frequency cutoff at which we set the blur depending on the two images we choose. We can then view the hybrid image at various resolutions to see how they might look as we vary the viewing distance. We show the the process step by step in the following table of images:

The first image in the table is the original image. This image gets blurred, to extract the low frequency content. Next, we take the cat image from above and subtract its blurred image to extract the high frequency content of the image. Finally, we add the two images. When we downsample the hybrid image we can see that it appears to transform from a cat into a dog:

Hybrid image being downsampled to show the transformation from a cat into a dog.

More transformations are below:

EXTRA: Custom Hybrid Image

I combine an image of a dandelion and an image of the earth in a hybrid image, as seen below:

The original images are thus:

EXTRA: Edge-Handling Comparison

Handling edges when performing a correlation filter can be tricky. Here we compare three methods for handling edges: Zero-padding, Mirrored-padding, and Extended-padding. These methods are built into Matlab's padarray() function. The code for these three methods, respectively, are:

padimage=padarray(image,padsize,0);
padimage=padarray(image,padsize,'symmetric');
padimage=padarray(image,padsize,'replicate');

The first method pads with zeros alone. This may result in the overall magnitude of the filtered image getting lowered to zero at the edges, which may be a fairly obvious unwanted artifact. The second method takes the nearby pixels and mirrors them. In some cases this may also create an unwanted artifact, especially when the pixels being mirrored have a high contrast with the edge pixel. Finally, the third method simply takes the egde pixel and pads the image with those pixels. This may also create unwanted artifacts depending on the situation. Here is a comparison of the three methods using a blurring filter:

Clearly, the zero-padding does not do well, while the mirrored and extended padding seems to perform similarly. Taking the squared difference between the mirrored and extended padding images and multiplying by 100 to highlight differences, we get the following image:

100*difference between mirrored-padding and extended-padding images from above.

So we can see that while there are differences between the mirrored-padded and extended-padded filtering schemes, the difference may not be noticable except in some specific cases.