IV – Logarithmic Transformation

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, $x$ different possible pixel values, and produce an output image with $y$ 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 $1$ to prevent a $log(0)$ 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 $imagesc$ 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.

Original Grayscale Image

Segmented Image

```%==========================================================================
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;
```