miércoles, 18 de febrero de 2009

Ecualización del histograma de una imagen


La ecualización del histograma consiste, en una expansión del histograma de la imagen, dotando al mismo de mayor linealidad y haciendo que éste ocupe el ancho del espectro de tonalidades grises por completo


Ventajas


- Al ecualizar el histograma, vemos como los tonos que antes estaban más agrupados, ahora se han separado, ocupando todo el rango de grises, por lo que la imagen se está enriqueciendo al tener niveles de gris más distintos entre sí, mejorando, por tanto, la apariencia visual de la imagen.


- Un aumento del contraste: esta ventaja es consecuencia del punto anterior, ya que si hacemos que el histograma de la imagen ocupe todo el rango de grises, estamos aumentando la distancia entre el tono más claro y el más oscuro, convirtiendo a éstos, en blanco y negro y consecuentemente aumentando el contraste de la imagen.


- Constituye una regulación óptima y automática del contraste de la imagen. Evitando ajustes manuales que no llegan a localizar el equilibrio exacto en una imagen del blanco y el negro.


Desventajas


-Pérdida de información: puede ocurrir que a algunos pixeles que en la imagen original tenían distintos niveles de gris se les asigne, tras la ecualización global, al mismo nivel de gris. Por otro lado, hay casos en los que dos niveles de gris muy próximos se separen, dejando huecos en el histograma.


-Las bandas horizontales debido a una deficiente digitalización pueden resultar intensificadas, resaltando aún más este error indeseado.



A continuacion el codigo fuente en Java:

import ij.*;

import ij.process.*;

import ij.gui.*;

import java.awt.*;

import ij.plugin.filter.*;

public class Filtro_Equalizacion implements PlugInFilter

{ ImagePlus imp;
public int setup(String arg, ImagePlus imp)

{ this.imp = imp;

return DOES_ALL;

}
public void run(ImageProcessor ip)

{ int [] vec= ip.getHistogram();

int I=255;

for (int k=1; k<>

{

vec[k]=vec[k-1]+vec[k];

}
int w=ip.getWidth();

int h=ip.getHeight();

for(int i =0; i

for(int j= 0; j<=h;j++)

{

int img =(int)(ip.getPixel(i, j));

img=vec[img]*((I-1)/(i*j));

ip.putPixel(i,j,i,img);

}

}

}
}

Definicion de Contraste y Brillo

El contraste incrementa el cambio de luminosidad entre las zonas más oscuras o más claras de una fotografía, simulando a su vez, un mejor enfoque y claridad de imagen.El retoque del contraste es muy adecuado en fotografías un poco claras.

El contraste se define como la diferencia relativa en intensidad entre un punto de una imagen y sus alrededores.

Un ejemplo simple es el contraste entre un objeto de brillo constante sobre un fondo de un brillo constante. Si ambas superficies tienen el mismo brillo, el contraste será nulo, y el objeto tanto física como perceptivamente será indistinguible del fondo. Según se incrementa la diferencia en brillo el objeto será perceptivamente distinguible del fondo una vez alcanzado el umbral de contraste, que se sitúa alrededor del 0.3% de diferencia en brillo.

Calculo de contraste segun Michelson en imagenes periodicas simples



Donde CM es el contraste de Michelson, Lmax es el mayor valor de brillo de la imagen, y Lmin es el menor valor de brillo de la imagen.


A continuacion el codigo fuente en Java:

import ij.*;

import ij.process.*;

import ij.gui.*;

import java.awt.*;

import ij.plugin.filter.*;
public class Filter_Contraste implements PlugInFilter{

ImagePlus imp;
public int setup(String arg, ImagePlus imp)

{ this.imp = imp;

return DOES_8G;

}
public void run(ImageProcessor ip)

{ int w=ip.getWidth();

int n=ip.getHeight();

for(int i =0; i

for(int j= 0; j<=n;j++)

{

int p =ip.getPixel(i,j);

p = (int)(p*2+50);

if (p >255){

p=255;

}

ip.putPixel(i,j,p);

}

}

}
}


UMBRALIZACIÓN

Umbralizacion o binarizacion de Imagenes


Una imagen binaria es una imagen en la cual cada píxel puede tener solo uno de dos valores posibles 1 o 0. Cuando una imagen esta en esas condiciones es mucho mas fácil encontrar y distinguir características estructurales.


La forma mas común de generar imágenes binarias es mediante la utilización del valor umbral de una imagen a escala de grises; es decir se elige un valor limite (o bien un intervalo) a partir del cual todos los valores de intensidades mayores serán codificados como 1 mientras que los que estén por debajo serán codificados a cero.


Por ejemplo si de la imagen que se muestra a continuacion quisiera realizarse este tipo de operación de tal forma que los píxeles mayores a 128 sean considerados como 1 y los que son menores o iguales a 128 como cero




A continuacion el codigo fuente en Java:


import ij.*;

import ij.process.*;

import ij.gui.*;

import java.awt.*;

import ij.plugin.filter.*;
public class Filter_Umbralizacion1 implements PlugInFilter

{ ImagePlus imp;
public int setup(String arg, ImagePlus imp)

{ this.imp = imp;

return DOES_8G;

}
public void run(ImageProcessor ip) {

int w=ip.getWidth();

int n=ip.getHeight();

for(int i =0; i

for(int j= 0; j

int p =ip.getPixel(i,j);

//p = (int)(p*2+50);

if (p <50){

p=0;

}else if(p>=50){

p=255; }

ip.putPixel(i,j,p);

}

}

}
}


martes, 10 de febrero de 2009

UMBRALIZACIÓN

Técnica de segmentación (partición de la imagen en áreas con significado)
en imágenes con fondo uniforme y objetos a extraer



Tipos de Umbralización utilizando el histograma

–P-tile
–Modales
–Iterativos
–Adaptativos
–Variables

Codigo Fuente de funcion java:

import java.applet.*;
import java.awt.*;
import java.awt.Image.*;
import java.awt.event.*;
import java.awt.image.renderable.ParameterBlock;
import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
import javax.media.jai.*;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.Histogram;
import javax.media.jai.operator.HistogramDescriptor;
import javax.media.jai.RenderedOp;
import javax.media.jai.ROI;
import javax.media.jai.widget.ScrollingImagePanel;


public class umbralizacion extends Applet implements ItemListener, ActionListener{
//declaramos como variables globales todas las que deban ser accedidas por más de un método
public Choice menu;
private Button boton;
Image foto;
String fotoelegida;
int marcador,max1,max2,media1,media2 ;
int opciones[]=new int[7];
int cadena[]=new int[256];
//en el método init inicializamos la varible opciones y el entorno gráfico inicial
public void init() {
String eleccion;
for (int i=0; i<7; marcador="0;" eleccion="llaves" menu="new" fotoelegida="eleccion+" foto="getImage(getDocumentBase(),fotoelegida);" boton="new" fotoelegida="menu.getSelectedItem()+" foto="getImage(getDocumentBase(),fotoelegida);" marcador="menu.getSelectedIndex();//marcador" image1 =" JAI.create(" bins =" {256};" low =" {0.0D};" high =" {256.0D};" hist =" new" pb =" new" region =" null;" dst =" JAI.create(" hist =" (Histogram)" cadena =" hist.getBins(0);" max1="cadena[0];" media1="0;" media2="256;" max2="cadena[128];" i="0;">=max1) {
max1=cadena[i];
media1=i;
}

}

for (int j=128; j<>=max2) {
max2=cadena[j];
media2=j;
}

}

repaint(); //dibujamos en pantalla,la imagen elegida junto con su histograma

}

}

public void actionPerformed(ActionEvent e) {
//si se pulsa el botón Procesar imagen,realizamos la umbralización
RenderedOp image1 = JAI.create("fileload",fotoelegida);
int valor=opciones[marcador];//sólo realizamos el proceso si no lo hemos hecho antes
if (valor==0){
//declaramos las variables necesarias,teniendo en cuenta que el cambio de tipos
//numéricos en Java pasa por la creación de objetos numericos.
Integer mx1 = new Integer(max1);
Integer mx2 = new Integer(max2);
Integer m1 = new Integer(media1);
Integer m2 = new Integer(media2);
double vari1=0;
double vari2=0;
double vartemp1=0;
double vartemp2=0;
double f1;
double num;
double den1;
double f2;
double den2;
for ( int k=5; k<10;k++) ent =" new" f1="ent.doubleValue();" cad1 =" new" num=" Math.pow(f1,2.0F)/(-2.0F);" den1=" Math.log(cad1.doubleValue()/mx1.doubleValue());" vartemp1=" num/den1;" vari1="vari1+" cad2 =" new" den2=" Math.log(cad2.doubleValue()/mx2.doubleValue());" vartemp2=" num/den2;" vari2="vari2+" vari1="vari1/5;" vari2="vari2/5;" a="(0.5D/vari1-0.5D/vari2);" b="(m2.doubleValue()/vari2)-(m1.doubleValue()/vari1);" c="0.5D*(Math.pow(m1.doubleValue(),2.0F)/vari1)-0.5D*(Math.pow(m2.doubleValue(),2.0F)/vari2)+Math.log(mx2.doubleValue()/mx1.doubleValue());" u="(-1.0D*b" umbral=" new" bp =" new" procesada =" JAI.create(" ancho =" procesada.getWidth();" alto =" procesada.getHeight();" panel =" new" window =" new" max="1;//Para">max2) {
max=max1;
}
else {
max=max2;
}
g.drawRect( 349,49,2*257,402);
g.setColor(Color.white);
g.fillRect( 350,50,2*256,400 );
g.setColor(Color.black);
g.drawString("Histograma de "+ fotoelegida,370,440);
for ( int n=0; n<255;n++) {//representamos el histograma normalizado a su máximo
if (max!=0){
g.setColor( Color.black );
g.drawRect(350+n*2,400-(cadena[n]*350)/max,2,(cadena[n]*350)/max);
g.setColor(Color.blue);
g.fillRect(350+n*2,400-(cadena[n]*350)/max,1,(cadena[n]*350)/max-1);
}
}
}
}