Search code examples
imagematlabimage-processinglookupcontrast

Increase image contrast using look up table in MATLAB


I am trying to do some image processing for which I am given an 8-bit grayscale image. I am supposed to change the contrast of the image by generating a lookup table that increases the contrast for pixel values between 50 and 205. I have generated a look up table using the following MATLAB code.

a = 2;
x = 0:255;
lut = 255 ./ (1+exp(-a*(x-127)/32));

When I plot lut, I get a graph shown below:

enter image description here

So far so good, but how do I go about increasing the contrast for pixel values between 50 and 205? Final plot of the transform mapping should be something like:

enter image description here


Solution

  • Judging from your comments, you simply want a linear map where intensities that are < 50 get mapped to 0, intensities that are > 205 get mapped to 255, and everything else is a linear mapping in between. You can simply do this by:

    slope = 255 / (205 - 50); % // Generate equation of the line - 
                              % // y = mx + b - Solve for m
    intercept = -50*slope; %// Solve for b --> b = y - m*x, y = 0, x = 50
    LUT = uint8(slope*(0:255) + intercept); %// Generate points
    LUT(1:51) = 0; %// Anything < intensity 50 set to 0
    LUT(206:end) = 255; %// Anything > intensity 205 set to 255
    

    The LUT now looks like:

    plot(0:255, LUT);
    axis tight;
    grid;
    

    enter image description here

    Take note at how I truncated the intensities when they're < 50 and > 205. MATLAB starts indexing at index 1, and so we need to offset the intensities by 1 so that they correctly map to pixel intensities which start at 0.

    To finally apply this to your image, all you have to do is:

    out = LUT(img + 1); 
    

    This is assuming that img is your input image. Again, take note that we had to offset the input by +1 as MATLAB starts indexing at location 1, while intensities start at 0.


    Minor Note

    You can easily do this by using imadjust, which basically does this for you under the hood. You call it like so:

    outAdjust = imadjust(in, [low_in; high_in], [low_out; high_out]);
    

    low_in and high_in represent the minimum and maximum input intensities that exist in your image. Note that these are normalized between [0,1]. low_out and high_out adjust the intensities of your image so that low_in maps to low_out, high_in maps to high_out, and everything else is contrast stretched in between. For your case, you would do:

    outAdjust = imadjust(img, [0; 1], [50/255; 205/255]);
    

    This should stretch the contrast such that the input intensity 50 maps to the output intensity 0 and the input intensity 205 maps to the output intensity 255. Any intensities < 50 and > 205 get automatically saturated to 0 and 255 respectively.