function J = ajustaHisto( I )
%AJUSTAHISTO(I) Ajusta niveles gris en imagen desplazando y estirando el
%histograma. Funciona solo con imagenes de 256 niveles de gris
%   Devuelve la imagen J con el histog extendido a todo el rango dinamico
%   Contempla un 1% de outliers (colas del histograma)

%______________________________________________________________________%
% NOMBRE DEL FICHERO:      ajustaHisto.m                               %
% RECIBE: Imagen de 256 niveles de gris                                %
% DEVUELVE: Una imagen con el histograma extendido a todo rango dinam  %
% ALGORITMO EMPLEADO: Calcula niveles de gris max y min en imagen      %
%                     A partir de ellos desplaza y estira histograma   %
%                     Considera un 1% de outliers que estarán          %
%                     saturados en bajas y altas intensidades          %
% VARIABLES:   I = imagen introducida                                  %
%              H = vector que contiene el histograma                   %
%              Iaux = imag. con el histog deslizado al origen          % 
%              J = imag. con el histog extendido a todo el rango dinami% 
% SUPOSICIONES :  Se supone imagen de 256 niveles de gris              %
%                 y 1% de outliers                                     %
% LIBRO: VISION ARTIFICIAL INDUSTRIAL. UNIVERSIDAD DE VALLADOLID 2012  %   
% TEMA 2 LA IMAGEN DIGITAL pág.31                                      %
% AUTORES: Eusebio de la Fuente y Félix Miguel Trespaderne             %
%______________________________________________________________________%
%  Ejemplo de ejecucion:                                               %
% >> I=imread('pout.tif');
% >> J=ajustaHisto(I);
% >> imshow(J);
%______________________________________________________________________%
% Con funciones de matlab
% >> I=imread('pout.tif');
% >> J=imadjust(I);
% >> imshow(J);
%______________________________________________________________________%
[filas,columnas]=size(I);
H=histo(I);                                                %histograma en H
numPixels=filas*columnas;
numOutliers=0.01*numPixels;                       %Toleramos 1% de outliers

[ngMin,ngMax] = extremosHisto(H,numOutliers);   %busca nivel gris min y max
Iaux = deslizaHisto(I, ngMin);      %imagen resultante de deslizar el histo
rangoDin=ngMax - ngMin;                   %rango dinamico imagen de entrada
J=estiraHisto(Iaux,rangoDin); %imagen resultante de estirar histo hasta 255

end

function [min,max] = extremosHisto(H,numOutliers)
%EXTREMOSHISTO() Busca el nivel de gris más bajo y mas alto presente en la
%imagen. Lo hace recorriendo el histograma. Tolera numOutliers por debajo
%y por encima de estos niveles minimo min y máximo max                   

%-------- buscamos n.de gris MINIMO en la img.  --------------------------%
%Toleraremos numOutliers
suma=0;
ng=0;                    %empezamos por el nivel de gris 0 y vamos subiendo
while(suma < numOutliers)
    suma=suma+H(ng+1);
    ng=ng+1;
end
min=ng-1;               %n.de gris minimo en la img.(considerando outliers)

%-------- buscamos n.de gris MAXIMO en la img.   -------------------------%
%Toleraremos numOutliers
suma=0;
ng=255;                 %empezamos por el nivel de gris 255 y vamos bajando
while(suma < numOutliers)
    suma=suma+H(ng+1);
    ng=ng-1;
end
max=ng+1;%n.de gris maximo en la img.(considerando outliers)
end

function J = deslizaHisto(I, ngMin)
%DESLIZAHISTO() Desliza el histograma de la imagen I ngMin niveles de gris
%la imagen resultante será más oscura. Considera que puede haber outliers
[filas,columnas]=size(I);
J = zeros(filas,columnas);      %imagen auxiliar result deslizamiento histo
for i=1:filas
    for j=1:columnas
        nvoNG = I(i,j) - ngMin;
        if nvoNG < 0     %Si es un outlier
            J(i,j)=0;    %estara saturado
        else
            J(i,j)=nvoNG;
        end
    end
end
J=uint8(J);    %devolvemos imagen uint8. Lo teníamos como double de 0 a 255
end

function J = estiraHisto(I, rangoDin)
%DESLIZAHISTO() Estira el histograma de la imagen I hasta el valor 255
%Considera que puede haber outliers
factorNG = 255.0 / rangoDin;
[filas,columnas]=size(I);
J = zeros(filas,columnas); %imagen result tras deslizamiento y extens histo
for i=1:filas
    for j=1:columnas
        nvoNG = factorNG * I(i,j);
        if nvoNG > 255     % Si es un outlier
            J(i,j)=255;    % estara saturado
        else
            J(i,j)=nvoNG;
        end
    end
end
J=uint8(J);    %devolvemos imagen uint8. Lo teníamos como double de 0 a 255
end

