As a newbie, I wrote a custom function in octave to perform a 2D image convolution using separable kernels. The results of this custom function were compared with conv2() and they were consistent. But that was where the joy ended.
conv2() works at the speed of light while my custom function is slower than a steam locomotive.
How can I speed up the loops below? As you can see, the number of MACs per pixel is 6 compared to 9 that would have been the case in 2D convolution. The function takes as inputs a row vector(3x1) and a column vector(1x3).
function OutputImage = Convolve3X3(InputImage, RowCount, ColCount, Kernel_x, Kernel_y) % Create a padded image PaddedImage = uint8(zeros(RowCount + 2, ColCount + 2)); % Create a staging area StagingImage = uint8(zeros(RowCount + 2, ColCount + 2)); % Create a Row Vector RowVector = uint8(zeros(1,3)); % Create a Col Vector ColVector = uint8(zeros(3,1)); % Copy the input image into the padded image PaddedImage(2:RowCount + 1, 2:ColCount + 1) = InputImage; % 1D convolution of necessary rows with Kernel_x for i = 2: RowCount + 1 for j = 1:ColCount RowVector = PaddedImage(i,j:j+2) .* Kernel_x; StagingImage(i,j) = RowVector(1) + RowVector(2) + RowVector(3); end end % 1D convolution of necessary columns with Kernel_y for i = 1: RowCount for j = 1:ColCount ColVector = StagingImage(i:i+2,j) .* Kernel_y; OutputImage(i,j) = ColVector(1) + ColVector(2) + ColVector(3); end end endfunction
How is conv2() so radically fast?