Convolution

Image convolution is mainly used to apply filters to 2D images to produce sharpening, noise reduction etc. Convolution basically consists of applying a fixed size filter(a 2D weighted array) to each pixel in a 2D image, wherein the weight applied to the pixel and it's surrounding pixels defines the purpose of the filter. The pixel and it's surrounding pixels are then multiplied with the filter to obtain the new value of the pixel.

For pixels located at the edge of an array, the missing pixels are either filled with zeros or a fixed value. In this example, the original array (size: x * y) would need to be extended by 1 in each dimension leading to the dimensions becoming (x+2) * (y+2) or (x + filter size - 1) * (y + filter size - 1)

Source code snippet

//Number of Rows(or Columns) in the filter
#define SIZE_FILTER 5

//Excess image padding to be applied at each row(or column) boundary
#define EXCESS_PADDING_PER_DIM_BY_2(size)  ((size - 1) / 2)

//Number of rows(or columns) in the image after padding
#define PADDED_IMAGE_ROWS_COLS(n) (n + SIZE_FILTER - 1)

//Index of next image pixel to be fetched from memory
#define INDEX2D(i,j,n,size) ((i - EXCESS_PADDING_PER_DIM_BY_2(size)) + (n * (j - EXCESS_PADDING_PER_DIM_BY_2(size))))

#define WINDOW_SIZE 256
int ny = 512;
int nx = 512;
for( j = EXCESS_PADDING_PER_DIM_BY_2(SIZE_FILTER); j < ny + EXCESS_PADDING_PER_DIM_BY_2(SIZE_FILTER); j++, window1++ ){
   already_div1 = 0;
   for( i = EXCESS_PADDING_PER_DIM_BY_2(SIZE_FILTER); i < nx + EXCESS_PADDING_PER_DIM_BY_2(SIZE_FILTER); i++, window2++ ){
      already_div2 = 0;
      s = i + (PADDED_IMAGE_ROWS_COLS(nx)*j);
      sum = 0.0;
      //Perform convolution
      //Iterate through all filter rows and corresponding image pixels
      for( k = 0; k < SIZE_FILTER; k++, window3++){
         already_div3 = 0;
         //Compute image pixel index corresponding to current filter row
         index = INDEX2D(i,j+k,PADDED_IMAGE_ROWS_COLS(nx),SIZE_FILTER);

         for( l = 0; l < SIZE_FILTER; l++, window4++ ){
	    already_div4 = 0;
            temp_flt[l] = *(filter + (k*SIZE_FILTER) + l);
	 }

         for( l = 0; l < SIZE_FILTER; l++ )
            temp_img[l] =  *(inputImage + index + l);

         for( l = 0; l < SIZE_FILTER; l++, window5++ ){
	    already_div5 = 0;
            sum += ( temp_flt[l] * temp_img[l]  );
         }
      }

      //Store to output image
      *(outputImage + s) = sum;
   }
}