Project 1: Image Filtering and Hybrid Images

The implementation of my image filtering algorithm consisted of three main challenging portions, which were: Setting up the dimensions of the loop iterations correctly (until what row/column do we iterate), partitioning sections of the image matrix appropriately as per the respective filter, and then padding the output matrix. I figured that I should iterate through the image matrix in a way in which I will always have enough room to be able to grab a subsection that is of equal size to the filter given. Due to that intuition, I also quickly found out that the resulting image should have equivalent (unpadded) dimensions to the dimensions iterated through the loop. I expressed this idea as IMGdim(k) - FILTdim(k) + 1 in my loop. I thought of my pointer as being on the top left side of the matrix each time. Partitioning came next, for which I simply added the dimensions of the filter to the index at which i was it in my image matrix and subtracted one. I subtracted one because otherwise it'd be one row or column too large. Then I did the element-wise multiplication and stored the result in the resulting matrix. I padded the array after the two loops ended.

Array Padding Tweak

I felt that the way that I ended up doing the entire project was more than likely conventional, as I didn't implement a FFT or anything like that. However, I did notice an interesting property that allowed me to pad my array in a fairly convenient manner. I was able to to pad my array by simply feeding in a vector with the difference of the dimension of the output of the loop and the old image divided by two as the difference will almost always be an even number. I divided it by two because it'll pad the matrix on both sides of the given dimension.

My Code


filtDimensions = size(filter);
filtRows = filtDimensions(1);
filtCols = filtDimensions(2);

imgDimensions = size(image);
imgRows = imgDimensions(1);
imgCols = imgDimensions(2);
imgChannels = imgDimensions(3);

returner = zeros(imgRows - filtRows + 1, imgCols - filtCols + 1, imgChannels);
difference = imgDimensions - size(returner);

for row=1:imgRows - filtRows + 1
   for col=1:imgCols - filtCols + 1
      for channel=1: imgChannels
          partition = image(row: row + filtRows - 1, col: col + filtCols - 1, channel);
          temp = (partition .* filter);
          returner(row, col, channel) = sum(temp(:));
      end
   end
end

returner = padarray(returner, [difference(1)/2, difference(2)/2], 'replicate');
output = returner;

Results

All of the above images used a cutoff frequency between 2.5 and 7, with the motorcycle/bicycle hybrid being the highest. I think that the hardest image combination to tune correctly was the submarine and fish combination, because even with a large amount of blur, the submarine still looks like a submarine. That's pretty much why I chose to have the fish as the image that you can see close up.