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:
To create a hybrid image of two given images(image1, and image2), we follow the following steps:
low_frequencies = my_imfilter(image1, filter);
high_frequencies = image2 - my_imfilter(image2, filter);
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: