A logarithmic transformation of an image is actually a simple one. We simply take the logarithm of each pixel value, and we’re done. Well, if that were the only interesting piece of information with respect to this topic, we’d be done now. There is an interesting operation we can carry out using some simple mathematics and a logarithmic transform: segmentation. This basically allows you to take an input image, with, for example, different possible pixel values, and produce an output image with possible pixel values. Although segmentation is a topic all on its own, this special case deserves a section for itself, if for no other reason than its simplicity.
In the case of the following images, I simply take an input image, calculate the base-2 logarithm of each pixel value, round it to the nearest integer (note the addition of a scalar to prevent a calculation, which is NaN so far as MATLAB is concerned), and then normalize the image. While you don’t need to normalize the image (after all, the MATLAB command does this for you easily enough), I figured it would be a good idea anyways.
The end result is shown below, along with the (simple) code used to generate it.
%========================================================================== function output_image = loglevel( input_image ) % IMNORM - Logarithmic normalization of input image over [0,255] % output_image - The normalized image % input_image - The source image data % (C) 2010 Matthew Giassa, <teo@giassa.net> www.giassa.net %========================================================================== %Make a grayscale copy of our input image I = double(rgb2gray(input_image)); %Determine input image dimensions [j k] = size(I); %Calculate the base-2 logarithm of each input pixel value, and round to the %nearest whole integer I=round(log2(double(I+1))); %Determine the extreme intensity values for our input image in_min = double(min(min(I))); in_max = double(max(max(I))); %Determine the extreme intensity values for the output image out_min = double(intmin('uint8')); out_max = double(intmax('uint8')); %Determine the amount to "shift/move" pixel intensity values by shift_val = in_min - out_min; %Determine the value to "scale" pixel intensity values by scale_val = (out_max)/(in_max-in_min); %Perform the shift and scale (in that order) for counter1 = 1:j for counter2 = 1:k I(counter1,counter2)=(I(counter1,counter2)-double(shift_val))*double(scale_val); end end %Done output_image = I;