Image Filtering

Method

The idea behind linear image filtering is pretty simple: Given as input two images (matrices): image, and filter. For each pixel in image, we then take the submatrix surrounding that pixel (which has the same size as filter), multiply each element in submatrix with filter, add them up, and the resulting number will be the corresponding value in the output image(matrix)

One edge case we have to handle is that for pixels near the edges of image, there won't be a big enough submatrix surrounding them, so we can't perform the computation above. There are several ways to work around this and in this assignment, I chose to pad image with surrounding zeroes

Since the code will have to handle both gray-scale and color images, I first created a helper function that handles gray-scale images (those having only one color channel)


function one_channel_output = one_channel_filter(image, filter)
    img_height = size(image, 1);
    img_width = size(image, 2);
    filter_height = size(filter, 1);
    filter_width = size(filter, 2);
    pad_height = (filter_height - 1)/2;
    pad_width = (filter_width - 1)/2;

    one_channel_output = zeros(img_height, img_width);
    padded = zeros(img_height + 2 * pad_height, img_width + 2 * pad_width); % add zero-padding
    padded(1 + pad_height: img_height + pad_height, 1 + pad_width: img_width + pad_width) = image;
    for ii = 1 : img_height
        for jj = 1 : img_width
            square = padded(ii : ii + 2 * pad_height, jj : jj + 2 * pad_width);       
            one_channel_output(ii, jj) = sum(sum(square .* filter));
        end
    end
end

Then in the main function, I use one_channel_filter() on gray-scale images, or use one_channel_filter() on each of the R/G/B channels on color images


output = zeros(size(image));
dim = length(size(image)); %1 if gray scale, 3 if colored
if (dim == 1)
    output = one_channel_filter(image, filter);
elseif (dim == 3)
    for d = 1: 3
        output(:, :, d) = one_channel_filter(image(:, :, d), filter);
    end
end
end

proj1_test_filtering will then test my filter function with several different filters. The results are included below:

Results

Hybrid Images

Method

To create a hybrid image of two given images(image1, and image2), we follow the following steps:

  1. Remove the high frequencies from image2 by filtering it with a Gaussian blur
    low_frequencies = my_imfilter(image1, filter);
  2. Remove the low frequencies from image1 by substract the low frequencies of it from the original image
    high_frequencies = image2 - my_imfilter(image2, filter);
  3. Add the low frequencies version of image1 and the high frequencies of image2 together
    hybrid_image = low_frequencies + high_frequencies;

One parameter that we need to tune to get the best result is cutoff_frequency. It's the standard deviation of the Gaussian blur filter. The results along with the corresponding cutoff_frequency are included below: