% APRENDIZAJE AUTOMÁTICO: UN ENFOQUE PRÁCTICO
% Autores: Gonzalo Pajares, María Guijarro, P. Javier Herrera y Jesús M. de la Cruz
% Copyright RA-MA, 2010
% Capítulo 2: APRENDIZAJE ESTADÍSTICO

% Fase de Clasificación
close all; clear all

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% Paso 1: carga de parámetros desde la Base de Conocimiento %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%cargar los datos existentes en la Base de Conocimiento
if exist('ParamAprendizaje.mat') ~= 0 
  load ParamAprendizaje

  options.Resize='on';
  options.WindowStyle='modal';
  options.Interpreter='tex';

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%% Paso 2: Generación del Mapa de Colores para representar clases %%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  colores = MapaColores(DATOS_CLASES);

  % c es el número de clases
  [a,c] = size(DATOS_CLASES);

  m = 2;

  %%%%%%%%%%%%%%%Fase de clasificación de imagenes %%%%%%%%%%%%%%%%%%%%%%
 
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%% Paso 3: se pide un factor de submuestreo de la imagen, para evitar%%
  %%%%%%         procesar la imagen completa                               %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  prompt = {'Factor de submuestreo'};
  dlg_title = 'Factor reducción imagen original';
  num_lines = 1;
  def = {'2'};
  answer = inputdlg(prompt,dlg_title,num_lines,def,options);
  step = str2num(answer{1});

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%% Paso 4: proceso iterativo de clasificación                       %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  n = 's';
  num_img = 0;
  while(strcmp(n,'s') ~= 0) % pregunta de más imágenes
    % numero de imágenes
    num_img = num_img + 1;
    
    if (num_img < 10) 
      IO = imread(strcat('IClasificacion_0',num2str(num_img),'.bmp')); 
    else
      IO = imread(strcat('IClasificacion_',num2str(num_img),'.bmp')); 
    end 

    [M,N,s] = size(IO);
   
    I = IO(1:step:M,1:step:N,:);
    [M,N,s] = size(I);
    figure; imshow(I);

    pixel = double([0 0 0]);
    %crear una matriz vacía sobre la que se van a dibujar las clases
    ClasesFuzzy  = zeros(M,N,s);
    ClasesBayes  = ClasesFuzzy;
    ClasesParzen = ClasesFuzzy;
   
    % clasificador Fuzzy Clustering
    for i=1:1:c
      v(i,:) = DATOS_CLASES(i).vFuzzy;
      U(i,:) = DATOS_CLASES(i).UFuzzy;
    end

    prompt = {'Parámetro h de Parzen'};
    dlg_title = 'Parámetro h de la ventana de Parzen';
    num_lines = 1;
    def = {'4'};
    answer = inputdlg(prompt,dlg_title,num_lines,def,options);
    h = str2num(answer{1});
   
    barraprogreso % Crea la figura y determina el progreso
    for ii=1:1:M
      for jj=1:1:N
        pixel(:) = I(ii,jj,:);
 
        %%%%%%%%%%%%%%%%%%%%%% Fuzzy %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %Clasificador Fuzzy 
        % calculo de los grados de pertenencia a cada una de las clases
        for i=1:1:c
          dd(i) = (1/sum((pixel - v(i,:)).^2))^(2/(m-1));
        end

        SUMA = sum(dd);
        for i=1:1:c
           mu(i) = dd(i)/SUMA;
           FUZZY(ii,jj,i) = mu(i);  %matriz con los valores de las clases
        end

        [fila, col, valor] = find(mu == max(mu));
        if size(col,2) ~= 1
            columna = col(1,1);
        else
            columna = col;
        end
        ClasesFuzzy(ii,jj,:) = colores(columna,:);
        %%%%%%%%%%%%%%%%%%%%%% fin Fuzzy %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        %%%%%%%%%%%%%%%%%%%%%% Bayesiano %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %Clasificador Bayesiano
        % calculo de la distancia de Mahalonobis (dM)
        d = s; %dimensión de los datos
        for i=1:1:c
          dM(i) = (DATOS_CLASES(i).mediaBayes - pixel)*pinv(DATOS_CLASES(i).covarianzaBayes)*(DATOS_CLASES(i).mediaBayes - pixel)';
          pBayes(i) = 1/((2*pi)^(d/2)*abs(det(DATOS_CLASES(i).covarianzaBayes)))*exp(-0.5*dM(i));
          BAYES(ii,jj,i) = pBayes(i);  %matriz con los valores de las clases
        end

        SUMA = sum(pBayes);
        pBayes = pBayes/(SUMA+eps);  %normalización al rango [0,1]
        
        for i=1:1:c
          BAYES(ii,jj,i) = pBayes(i);  %matriz con los valores de las clases
        end

        
        [fila, col, valor] = find(pBayes == max(pBayes));
        if size(col,2) ~= 1
            columna = col(1,1);
        else
            columna = col;
        end
        ClasesBayes(ii,jj,:) = colores(columna,:);
        %%%%%%%%%%%%%%%%%%%%%% fin Bayesiano %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        %%%%%%%%%%%%%%%%%%%%%% Parzen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %Clasificador de Parzen
        % calculo de las probabilidades
        for i=1:1:c
          n = DATOS_CLASES(i).numero_muestras;  
          d = size(DATOS_CLASES(1).muestras,2); %dimensión de las muestras 
          %K = (1/n)*(1/((2*pi)^d/2)*abs(det(DATOS_CLASES(i).covarianzaBayes))^(1/2)*h^d);
          K = 1;
          SumaExp = 0;
          for j=1:1:n
            p1 = K*exp(-1/(2*h^2)*(pixel-DATOS_CLASES(i).muestras(j,:))*pinv(DATOS_CLASES(i).covarianzaBayes)*(pixel - DATOS_CLASES(i).muestras(j,:))');
            SumaExp = SumaExp + p1;
          end
          Parzen(i) = SumaExp;
        end

        Sp = sum(Parzen);
        pParzen = Parzen/Sp;  %probabilidad restringida al rango [0,1]

        for i=1:1:c
          PARZEN(ii,jj,i) = pParzen(i);  %matriz con los valores de las clases
        end

        [fila, col, valor] = find(pParzen == max(pParzen));
        if size(col,2) ~= 1
            columna = col(1,1);
        else
            columna = col;
        end
        ClasesParzen(ii,jj,:) = colores(columna,:);
        %%%%%%%%%%%%%%%%%%%%%% fin Parzen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      end
      barraprogreso(ii/M) % actualiza figura
    end
      
    figure; imshow(ClasesFuzzy);    title('Resultados Clasificador Borroso');
    figure; imshow(ClasesBayes);    title('Resultados Clasificador paramétrico máxima verosimilitud');
    figure; imshow(ClasesParzen);   title('Resultados Clasificador no paramétrico ventana de Parzen');
    
    prompt = {'s/n'};
    dlg_title = '¿Más imágenes de clasificación?';
    num_lines = 1;
    def = {'s'};
    answer = inputdlg(prompt,dlg_title,num_lines,def,options);
    n = answer{1};
   
    if num_img == 5
      % se ha alcanzado el número máximo de imágenes disponibles
      disp('Se ha alcanzado el número máximo de imágenes a clasificar disponibles');
      n = 'n';
    end
 end %while(strcmp(n,'s') ~= 0) % pregunta de más imágenes de clasificacion

else
  disp('No se ha realizado proceso de Aprendizaje previo');  
end


