martes, 17 de febrero de 2009

ECUALIZACIÓN

la ecualización de un histograma permite que se eliminen sombras de la imagen y se aumente la visibilidad. La ecualización del histograma permite mejorar imágenes de forma muy puntual y especifica.

Para lograr una buena ecualización en las imágenes se realiza el histograma a todas las imágenes en escala de grises, encontrando los valores del rango donde se debe aumentar el contraste para ampliar la visibilidad de la imagen

ECUALIZACION PARA ESCALA DE GRISES

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 [] H= ip.getHistogram();//declaro un arreglo para almacenar el histograma
int K1=255;
for (int k=1; k< H.length; k++)
{
H[k]=H[k-1]+H[k];
}

int w=ip.getWidth();//asigno a una variable el ancho de la imagen
int n=ip.getHeight(); //asigno a una variable el largo de la imagen
for(int i =0; i < w;i++)
{
for(int j= 0; j < n;j++)
{
//int p = (int)(ip.getPixel(i,j)*0.5+1.5);
int p =(int)(ip.getPixel(i, j));
p=H[p]*((K1-1)/(i*j));
ip.putPixel(i,j,p);
}
}
}

}


ECUALIZACION PARA IMAGEN A COLOR

import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class eqHist extends Applet //CLASE ECUALIZACIÓN
{
// Declaración de variables globales

Choice imagenes = new Choice(); // lista desplegable con las imagenes originales
Button cargar; // botón para cargar la imagen
Button aplicar; // botón para aplicar ecualización y representar histogramas

Image art; // imagen original
int w = 284; // anchura de la imagen original (fija)
int h = 129; // altura de la imagen original (fija)
int[] pixels; // vector para contener los pixels de la imagen original
PixelGrabber m_pixelgrabber; // objeto para guardar los pixels
int pixel; // valor (instantaneo) del pixel (al recorrer la imagen)

int[] histogram = new int[256]; // histograma de la imagen original
int maxFrequency = 0; // máxima frecuencia del histograma de la imagen original
int maxFrequencyIndx = 1; // índice de dicha máxima frecuencia

int[] histogram2=new int[256]; // histograma de la imagen ecualizada
int maxFrequency2 = 0; // máx. freq. del hist. de la imagen ecualizada
int maxFrequencyIndx2 = 1; // índice de dicha máxima frecuencia

double area; // tamaño de la imagen (w*h)

double cumNormHist [] = new double [256] ; // histograma normalizado acumulado
double min; // valor minimo del histograma normalizado acumulado
int[] dest = new int[256]; // niveles de gris transformados
int destino; // nuevo valor del pixel (imagen ecualizada)
int[] pixelsdestino; // vector para contener los pixels de la img ecualizada
Image m_ImageNew; // imagen ecualizada
boolean ecualizar = false; // vble. booleana para controlar la representacion
// si (ecualizar) entonces
// pintar histogramas e imagen ecualizada


public void init()
{
cargar = new Button ("Cargar imagen");

imagenes.addItem("img0");
imagenes.addItem("img1");
imagenes.addItem("img2");
imagenes.addItem("img3");
imagenes.addItem("img4");

add(imagenes);
add(cargar);

aplicar = new Button ("Ecualizar imagen");
add(aplicar);

// Inicializacion del histograma
for (int i = 0 ; i < 256 ; i ++) {
histogram[i] = 0;
}

maxFrequencyIndx = 1 ;
maxFrequency = 1 ;

// Inicializacion del histograma de la imagen ecualizada
for (int i = 0 ; i < 256 ; i ++) {
histogram2[i] = 0;
}

maxFrequencyIndx2 = 1;
maxFrequency2 = 1;

}

public boolean action ( Event e, Object o )
{
String parametro; // parametro que hay que obtener de la pagina web
int indice; // indice de imagen seleccionado

if ( e.target == cargar ) // si pulsamos el boton cargar
{
indice=imagenes.getSelectedIndex();
parametro="img" + Integer.toString(indice);
art=getImage(getDocumentBase(), getParameter(parametro));
ecualizar=false; // solo pintar la imagen a cargar

repaint();
return true;
}

if ( e.target == aplicar ) // si pulsamos el boton aplicar
{

// Obtenemos una matriz con los pixels de la imagen original

pixels = new int[w * h];
m_pixelgrabber = new PixelGrabber (art, 0, 0, w, h, pixels, 0, w) ;
try {
m_pixelgrabber.grabPixels();
}
catch (InterruptedException e2) {
System.err.println("interrupted waiting for pixels!");
//return;
}


// Inicializacion del histograma

for (int i = 0 ; i < 256 ; i ++) {
histogram[i] = 0;
}


// Creamos el histograma

for (int r = 0 ; r < h ; r++) { // recorremos todo el vector
for (int c = 0 ; c < w ; c++) { // de enteros (4 bytes/entero)
pixel = pixels[r * w + c] & 0xff; //nos quedamos con el
// ultimo byte (Blue,pq R=G=B)
histogram [pixel]++; // aumentamos el nº apariciones del
// nivel de gris en cuestión
}
}


// Buscamos la maxima frecuencia de aparicion

maxFrequencyIndx=0;
maxFrequency=0;

for (int i = 0 ; i < 256 ; i++) {
if (histogram[i] > maxFrequency) {
maxFrequencyIndx = i ;
maxFrequency = histogram[i] ;
}
}


//Histograma normalizado acumulado

area = w * h ;

for (int i = 0 ; i < 256 ; i++) {
cumNormHist [i] = 0 ; // inicializacion
}

cumNormHist[0] = (double)histogram[0] / area ;

if (cumNormHist[0]!=0) {
min=cumNormHist[0];
}
else {
min=1; // el valor minimo del Cumulative Norm. Histogram siempre sera < 1
}

for (int i = 1 ; i < 256 ; i++) {
cumNormHist[i] = cumNormHist[i - 1] + ((double)histogram[i] / area) ;

if ((cumNormHist[i]!=0) & (cumNormHist[i] min=cumNormHist[i];
}

}


// Creacion imagen ecualizada

pixelsdestino=new int[w*h];
for (int i = 0 ; i < 256 ; i++) {
dest [i] =(int) (((cumNormHist[i]-min)/(1-min))*255 + 0.5) ; // nuevos niveles de gris
}

for (int r = 0 ; r < h ; r++) {
for (int c = 0 ; c < w ; c++) {
pixel = pixels[r * w + c] & 0xff; // nivel del gris del pixel
// en la imagen original
destino = dest[pixel]; // nuevo nivel de gris (transformado)

int origen = destino;
int suma = 0;
int[] b = new int[33] ;

// Calculo del valor a almacenar en el vector de pixels

// Hemos de crear un valor entero (4 bytes) que contenga: FF XY XY XY, a partir de XY en decimal
// pasamos el número en decimal (origen) a binario, lo negamos y lo replicamos

for (int i = 1 ; i < 9 ; i ++) {
b[i] = origen % 2;

if (b[i]==1) {
b[i]=0;
}
else {
b[i]=1;
}

b[i]=b[i] & 1;

b[i+8] = b[i];
b[i+16] = b[i];
b[i+24]= 0;
origen = origen / 2;
}

// pasamos el valor binario obtenido a decimal

for (int j = 1 ; j <= 24 ; j ++) {
suma=suma+(b[j]*(int)(Math.pow(2,(double)(j-1))));
}

// si a este número le sumamos 1 y lo cambiamos de signo obtendremos el valor deseado
// (es decir, habremos deshecho el complemento a 2)

suma=suma+1;
suma=0-suma;

pixelsdestino[r * w + c]= suma;
}
}

MemoryImageSource mis = new MemoryImageSource(w, h, pixelsdestino, 0, w) ;
m_ImageNew = createImage (mis) ;

// Inicializacion del histograma de la imagen ecualizada

for (int i = 0 ; i < 256 ; i ++) {
histogram2[i] = 0;
}


// Creamos el histograma de la imagen ecualizada

for (int r = 0 ; r < h ; r++) {
for (int c = 0 ; c < w ; c++) {
pixel = pixelsdestino[r * w + c] & 0xff;
histogram2 [pixel]++;
}
}


// Buscamos la maxima frecuencia de aparicion

maxFrequencyIndx2=0;
maxFrequency2=0;

for (int i = 0 ; i < 256 ; i++) {
if (histogram2[i] > maxFrequency2) {
maxFrequencyIndx2 = i ;
maxFrequency2 = histogram2[i] ;
}
}

ecualizar=true; // pintar img original y ecualizada, pintar histogramas
repaint();
return true;
}
return false;
}

public void paint(Graphics g) {
g.drawString("ECUALIZACION DE HISTOGRAMA",10,25);

g.drawLine(0,40,700,40); // 1ª linea horizontal (completa, debajo de botones)
g.drawLine(205,0,205,40); // 1ª linea vertical (separa titulo de botones)

g.drawString("IMAGEN ORIGINAL",20,60);
g.drawString("IMAGEN ECUALIZADA",550,60);

g.drawLine(0,67,700,67); // 2ª linea horizontal (debajo del texto anterior)
g.drawLine(350,40,350,425); // 2ª linea vertical (separando los textos)

g.drawLine(0,230,700,230); // 3ª linea horizontal (completa, antes texto histogramas)

g.drawString("HISTOGRAMA IMAGEN ORIGINAL",20,250);
g.drawString("HISTOGRAMA IMAGEN ECUALIZADA",475,250);

g.drawLine(0,257,700,257); // 4ª linea horizontal (completa, despues texto hist.)


g.drawImage(art,33,84,this); // imagen original

if (ecualizar) { // pintar tb. imagen ecualizada e histogramas

g.drawImage(m_ImageNew,383,84,this); // imagen ecualizada

// Representacion grafica del histograma de la imagen original

int offset=15;

int desplaza=33; // desplazamiento horizontal
int baja=275; // desplazamiento vertical

g.setColor (new Color (255, 255, 255)) ;
g.fillRect(desplaza+0, baja+0, 255 + offset * 2 - 1, 100 + offset * 2 - 1) ;

g.setColor (new Color (0, 0, 0)) ;
g.drawRect(desplaza+0, baja+0, 255 + offset * 2, 100 + offset * 2) ;

g.setColor (new Color (0, 0, 0)) ;
g.drawString ("0", desplaza+offset / 2, baja+100 + offset * 2 - 2) ;
g.drawString ("255", desplaza+255, baja+100 + offset * 2 - 2) ;
g.drawString (String.valueOf(maxFrequency), desplaza+2, baja+offset) ;

for (int i = 0 ; i < 256 ; i++){
g.drawLine (desplaza+i + offset, baja+100 + offset - ((int)(((float)histogram[i] / (float)maxFrequency2) * 100.0)), desplaza+i + offset, baja+100 + offset);
}

// Representacion grafica del histograma de la imagen ecualizada

int desplaza2=383; // desplazamiento horizontal
int baja2=275; // desplazamiento vertical

g.setColor (new Color (255, 255, 255)) ;
g.fillRect(desplaza2+0, baja2+0, 255 + offset * 2 - 1, 100 + offset * 2 - 1) ;

g.setColor (new Color (0, 0, 0)) ;
g.drawRect(desplaza2+0, baja2+0, 255 + offset * 2, 100 + offset * 2) ;

g.setColor (new Color (0, 0, 0)) ;
g.drawString ("0", desplaza2+offset / 2, baja2+100 + offset * 2 - 2) ;
g.drawString ("255", desplaza2+255, baja2+100 + offset * 2 - 2) ;
g.drawString (String.valueOf(maxFrequency2), desplaza2+2, baja2+offset) ;

for (int i = 0 ; i < 256 ; i++){
g.drawLine (desplaza2+i + offset, baja2+100 + offset - ((int)(((float)histogram2[i] / (float)maxFrequency2) * 100.0)), desplaza2+i + offset, baja2+100 + offset);
}
}

}

}

1 comentario:

Gaby Morocho dijo...

Tu aporte es bastante completo pero te recomiendo simplificar un poco el codigo ya que esta demasiado extenso