The last example for testing speed in Julia will be a 5×5 mean filter. A mean filter is simply a way of smoothing an image, ie. suppressing irregularities in the intensities, and is common used for noise suppression. It basically works by working through each pixel in an image, obtaining the mean of the 5×5 region around that pixel, and using this value as the pixel in the filtered image. As such it is an intensive algorithm.
In this particular example, we shall apply a mean filter to a 2144×6640 pixel, 8-bit image: effectively 14 megapixels. The algorithm is analyzed using code written in C, Fortran, Python and Julia.
The image is processed using the following Julia code:
function process(img) dx,dy = size(img) imgN = copy(img) e = div(5,2) for i=e+1:dx-e, j=e+1:dy-e block = img[i-e:i+e,j-e:j+e] mn = mean(block) imgN[i,j] = round(UInt8,mn) end return imgN end img = readdlm("pano.txt",Int16::Type) @time imgN = process(img) writedlm("panoJ.txt",imgN)
Since Julia provides efficient means of reading an entire block of integers in from an ASCII file, the code is much shorter than it would be in C. In addition, Python, Julia and Fortran provide facilities to slice arrays, making extraction of the 5×5 neighbourhood easy.
The code has been timed based just on the process of performing the mean filtering, and avoiding extras such as file I/O. In most cases this involves a nested loop to process each pixel in the image. In the case of C, it includes a second set of nested loops to extract the 5×5 neighbourhood.
As the results show, C was able to process the image in less than a second, with Fortran in second place marginally over a second. At just over 3 seconds, the Julia code could be considered to be exceptionally fast as well. The loser in this instance is again Python which is invariably slow, even with only one pair of nested loops. In a future post, I will explore this algorithm in each of the languages cited in the context of image processing.