matlabimage-processinggamma

Gamma correction implementation in MATLAB


I'm trying to do a gamma correction function in MATLAB, and to say the least, I'm getting some mixed results. Where using a gamma constant below 1 (such as 0.5) gives me a brighter image, and using a constant above 1 gives me a darker image, which is wrong since it should give me opposite results (constant lower than 1 should be darker and constant higher than 1 should be brighter).

Here's the code I've been working on based on the following formula that I found while looking at an image processing book:

f(v):= 255·(v/255) 1/GAMMA

Where (If I understood it correctly) v is the input image and GAMMA is a constant.

And here's the code in MATLAB:

%%Fucnion de gamma
%%Entradas
%% I = imagen original
%% gamma = constante de gamma
%%Salidas 
%% G = imagen transformada

function [G] = FuncionGamma(I,gamma)
G=zeros(size(I));
for i=1: size(I, 1)
    for j=1: size(I, 2)
        G(i,j) = double(255 * (I(i,j)/255)).^(1/gamma);
    end
end
G=uint8(G); 
end

And here's the script to call it:

clc;
clear;
close all;

gamma = 0.5;
gamma2 = 1.5;
I = imread("mantis.jpg");

[IMG1] = FuncionGamma(I,gamma); 
[IMG2] = FuncionGamma(I,gamma2); 

figure;
imshow(IMG1);

figure; 
imshow(IMG2);

Here are the results:

Original image: enter image description here

Gamma = 0.5 Gamma = 0.5

And gamma = 1.5 enter image description here

What am I doing wrong?


Solution

  • Pay attention to your brackets:

    G(i,j) = double(255 * (I(i,j)/255)).^(1/gamma);
    
    G(i,j) = double( 255 * (I(i,j)/255) ) .^ (1/gamma);
                     ^^^^^^^^^^^^^^^^^^
    

    The highlighted section is elevated to 1/gamma. You need to place your brackets differently so that the power is computed first, then the multiplication. Note that double is not needed there, but you likely want to cast I to double before the division (dividing a uint8 by a double produces a uint8 in MATLAB).

    Furthermore, you don't need to loop at all. MATLAB is good at processing whole matrices in one go. You can simplify your function to this:

    function G = FuncionGamma(I,gamma)
    G = uint8( 255 * (double(I)/255).^(1/gamma) );
    end