viernes, 1 de junio de 2012

Lógica Difusa y Mejoramiento de Imagenes

clear all
clc
A=imread('c:\moon.jpg');
B=histeq(A);
minimo=min(min(B));
maximo=max(max(B));
dinamica=maximo-minimo;
rango=dinamica/6;
[fila,columna]=size(B);
Z=zeros(fila,columna);
for y=1:fila
    for x=1:columna
        pixel=B(y,x);
        if pixel<=(minimo+rango)
            Z(y,x)=B(y,x)*.15;
        elseif pixel<=(minimo+(rango*2))
            Z(y,x)=B(y,x)*.30;
              elseif pixel<=(minimo+(rango*3))
            Z(y,x)=B(y,x)*.45;
              elseif pixel<=(minimo+(rango*4))
            Z(y,x)=B(y,x)*.60;
              elseif pixel<=(minimo+(rango*5))
            Z(y,x)=B(y,x)*.75;
              elseif pixel<=(minimo+(rango*6))
            Z(y,x)=B(y,x)*.90;
        else
            Z(y,x)=B(y,x);
        end
    end
end
Z=uint8(Z);
imshow(Z)
figure
imshow(A)


El procesamiento digital de imágenes es un área de investigación y de aplicación en el cual convergen muchas áreas de conocimiento como lo son la física, las matemáticas, las ciencias de la computación, la inteligencia artificial y muchas mas; por ese motivo es necesario conocer y aplicar muchas de las técnicas que nos proveen estas áreas de investigación. En la realización de este trabajo, se aplico una técnica de inteligencia artificial muy utilizada en la actualidad para control de procesos, dicha técnica se denomina lógica difusa o lógica borrosa (fuzzy logic).


El objetivo de este Blog es mostrar una aplicación de la lógica difusa al procesamiento de imágenes, no vamos a entrar en detalles teóricos ya que esto extendería mucho el blog, los detalles prácticos serán realizados en Matlab la metodología utilizada para aplicar técnicas de procesamiento de imágenes utilizando lógica difusa fue la siguiente:

  1. Fase 1: Análisis de la imagen para determinar las características útiles para el sistema de lógica difusa.
  2. Fase 2: Diseño del sistema de lógica difusa.
  3. Fase 3: Implementación del sistema de procesamiento de imágenes basado en lógica difusa.
Primera Fase
En esta fase se trabajo con la imagen que se quería mejorar, obteniendo de ella características relevantes para el sistema de lógica difusa. Las características que se tuvieron en cuenta fueron las siguientes:
  • Histograma de la imagen
  • Valores máximo y mínimo de los niveles de gris de la imagen.

    Imagen desmejorada


    Histograma de la Imagen desmejorada
    Primero: Planteamiento de las variables de entrada y de salida. Se definen los siguientes términos:
  • Conjunto Soportado, son todos aquellos píxeles pertenecientes a la imagen de entrada con valores máximo y mínimo en [0, 255].
  • Subconjuntos Borrosos: Para el conjunto de los píxeles de entrada y salida se definen los siguiente subconjuntos borrosos:
          • Oscuro
          • Gris
          • Claro
          • Mas Oscuro
          • Mas Claro
          • Mas Gris
  • Definición de las funciones de pertenencia o inclusión: Estas funciones indican en que grado un valor u de la variable U esta incluida en un subconjunto F, ej: en que grado el pixel de entrada con valor 135 esta incluido en el conjunto Claro.Para este ejemplo se emplean las siguientes funciones:
          • Uoscuro()
          • Ugris()
          • Uclaro
          • UmasOsuro()
          • UmasGris()
          • UmasClaro()
  • Por ultimo, se plantea el proceso de mejoramiento de la imagen en escala de grises como reglas en términos de lógica difusa tal como se muestra a continuación:

  • IF un Pixel IS THEN Hacerlo mas Oscuro.
  • IF un Pixel IS Gris, THEN Hacerlo mas Gris.
  • IF un Pixel IS Claro, THEN Hacerlo mas Claro.

    Tercera Fase
    A continuación se muestra el proceso gráfico realizado en Matlab para implementar los conceptos planteados anteriormente:
    Para iniciar la definición de un sistema de lógica difusa en Matlab se teclea en el interprete de comandos la siguiente orden:
    >> fuzzy;
    Este comando se utiliza para llamar al toolbox de lógica difusa de Matlab, el cual se muestra a continuación:
    A continuación se procede a definir las variables de entrada y de salida: En el campo de texto Name se escribe el nombre de la variable, para nuestro caso, las 2 variables se denominara pixel. Aahora se definen los rangos de las variable y las funciones de pertenencia, esto se logra haciendo doble clic sobre la variable que se quiere definir, esto nos lleva a la siguiente ventana:
    En esta ventana se pueden definir los rangos de las variables y de las funciones miembro, así como los nombres y los tipos de las funciones miembro.
    En la siguiente imagen se ven definidas las variables de entrada con sus respectivos nombres y rangos, estos rangos se pueden ajustar en el campo denominado Params o gráficamente haciendo clic sobre los cuadros pequeños en los pliegues de las gráficas de las funciones de inclusión. En la siguiente gráfica se muestra la misma ventana pero con las definiciones de las funciones de inclusión de salida. Los rangos se seleccionaron teniendo en cuenta el histograma de la imagen de la siguiente manera: Se definió el rango de la variable de entrada entre 200 y 255 ya que la mayoria de los pixeles de la imagen tienen su valor en este rango, posteriormente se ajustaron graficamente los valores de las funciones de pertenencia para que quedaran dentro de este rango tal y como lo muestra la imagen de abajo. Para la funcion de salida se definieron solo 3 valores que serian los que se maneja como masOscuro, masGris y mas Claro.
    Después de definir las variables de entrada y de salida con sus respectivos rangos y funciones de inclusión, se procede a definir las reglas sistema, esto se logra haciendo doble clic sobre el cuadro central de la ventana principal o en el menú edit->rules:
    En esta ventana se procede a crear las reglas de la siguiente manera:
  • Se da clic sobre el botón Add Rule, se selecciona a la derecha la función de inclusión de entrada, a la izquierda la de salida, este procedimiento se repite para todas las reglas que se quieran declarar.
Por ultimo procedemos a probar el sistema diseñado, para esto utilizamos el menú View->Rules el cual nos lleva a la ventana de prueba de las reglas
En esta ventana se puede apreciar la activación de las reglas de acuerdo a un determinado valor de entrada

Este sistema diseñado con el toolbox de Matlab también se puede probar desde el interprete de comandos de la siguiente manera:
  • Se exporta el sistema diseñado al espacio de trabajo
  • Se lee el sistema diseñado para que pueda ser utilizado, para esto se utilizan los siguientes comandos:
>> variable = readfis('nombre_sistema_logica_difusa');
Donde variable es el nombre de la variable que vamos a utilizar y nombre_sistema_logica_difusa es el nombre que se le dio al sistema cuando lo exportamos.
  • Por ultimo, la evaluación del sistema se hace con los comandos:
>> evalfis(230, variable)
ans = 48.4500
>>
donde evalfis es la función de evaluación, 230 es el valor que queremos evaluar y variable es el nombre de nuestros sistema de lógica difusa.
Por ultimo, para evaluar la imagen completa, se debe organizar un subprograma que recorra cada pixel de la imagen y lo evalué con la funcion evalfis, el resultado de esta evaluacion se puede guardar en una nueva imagen o remplazar el pixel de la imagen origianl.
Resultados Obtenidos
El resultado de la experiencia fue satisfactorio ya que se cumplió el objetivo que era lograr el mejoramiento de la imagen utilizando lógica difusa. Por otro lado fue muy frustrante el hecho de que el sistema implementado en Matlab nos diera problemas en cuanto al tiempo que toma para evaluar la imagen completa no sabemos el porque ocurre este problema pero tenemos serios indicios de que tiene algo que ver con un mal funcionamiento del disco duro de la maquina donde lo probamos (no lo hemos probado en otro computador), para evitar este problema se opto por hacer una implementación del sistema en C, dicha implementación nos dio unos tiempos de respuesta muy superiores a los de Matlab, por otro lado, se adquirio conocimiento en el uso del motor de lógica difusa de Matlab.
A continuación se muestra la imagen obtenida como resultado de la ejecucion del sistema de lógica difusa implementado en C.


 Algoritmo mejorado por Mario D G
clear all
clc
A=imread('c:\hoja.jpg');
A=rgb2gray(A); %Si se necesita Ecualizar la imagen
B=double(A);
%B=histeq(A);
minimo=min(min(B));
maximo=max(max(B));
dinamica=maximo-minimo;
cambio=255/dinamica;
posicion=minimo-1;
[fila,columna]=size(B);
Z=zeros(fila,columna);
for y=1:fila
    for x=1:columna
          Z(y,x)=((B(y,x)-posicion)*cambio);
    end
end
Z=uint8(Z);
imshow(Z)
figure
imhist(Z)
figure
imshow(A)
figure
imhist(A)
minimoZ=min(min(Z));
maximoZ=max(max(Z));
dinamicaZ=maximoZ-minimoZ;