Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-02-2007
Avatar de bosterito
bosterito bosterito is offline
Miembro
 
Registrado: nov 2006
Ubicación: Tucumán, Argentina
Posts: 39
Poder: 0
bosterito Va por buen camino
Smile Binarización de una imagen

Hola amigos foristas.
Les cuento que estoy desarrollando un sistema que trata sobre imagenes digitales. En el mismo consta de una sección en la cual maneja imagenes en escala de grises y la transforma a blanco y negro (binarización). Investigando en la web, di que el mejor método es el que trata el umbral de Otsu. Esta binarización también emplea una interpolación bilineal, la cual no se como acoplarla al sistema. A continuación les envío el código que desarrollé:

Código:
Type TmatrizB = array[1..16, 1..16] of Integer;
Type VectorReal = array[0..256] of Real;
Type VectorEntero = array[0..256] of Integer;
 
 
function DistribucionProbabilidad( Histograma : VectorEntero; Ancho, Alto : Integer ) : VectorReal;
Var
Probabilidad : VectorReal;
i : Integer;
begin
for i := 1 to 256 do
Probabilidad[i] := (Histograma[i]/(Ancho*Alto));
Result := Probabilidad;
end;
procedure MomentoAcumulado( Probabilidad : VectorReal; var Omega : VectorReal; var Mu : VectorReal );
Var
i : Integer;
begin
Omega[1] := Probabilidad[1];
Mu[1] := Probabilidad[1];
for i := 2 to 256 do
begin
Omega[i] := Omega[i-1] + Probabilidad[i];
Mu[i] := Mu[i-1] + ((i-1)*Probabilidad[i]){i * Probabilidad[i]};
end;
end;
function UmbralOptimo( Omega, Mu : VectorReal ) : Integer;
Var
Sigma, SigmaMax, MuTotal, Omega1, Omega2, Mu1, Mu2 : Real;
Umbral, i : Integer;
begin
Sigma := 0; SigmaMax := 0; MuTotal := Mu[256]; Umbral := 0;
for i := 1 to 256 do
begin
Omega1 := Omega[i];
Omega2 := 1 - Omega1;
if ( ( Omega1 <> 0 ) and ( Omega2 <> 0 ) ) then
begin
Mu1 := Mu[i]/Omega1;
Mu2 := (( MuTotal - Mu[i] )/Omega2);
Sigma := ((Omega1 * sqr( Mu1 - MuTotal )) + (Omega2 * sqr( Mu2 - MuTotal )));
if ( Sigma > SigmaMax ) then
begin
SigmaMax := Sigma;
Umbral := i - 1;
end;
end;
end;
Result := Umbral;
end;
function Segmentacion( Bloque : Integer; Imagen : TImage ) : TMatrizB;
var
i, j, Alto, Ancho, Umbral : Integer;
Histograma : VectorEntero;
Omega, Mu, DP : VectorReal;
Matriz : TMatrizB;
begin
FillChar(Matriz, sizeof(Matriz), 0);
Alto := 0;
While( Alto <= Form1.Image1.Picture.Bitmap.Height -1 ) do
begin
Ancho := 0;
While( Ancho <= Form1.Image1.Picture.Bitmap.Width -1 ) do
begin
FillChar(Histograma, sizeof(Histograma), 0);
for j:= Alto to Alto + (Bloque - 1) do
begin
for i:= Ancho to Ancho + (Bloque - 1) do
begin
inc (Histograma[Imagen.Canvas.Pixels[i,j] and $FF + 1]);
end;
end;
Ancho := Ancho + Bloque;
FillChar(DP, sizeof(DP), 0);
DP := DistribucionProbabilidad( Histograma, 16, 16 );
FillChar(Omega, sizeof(Omega), 0); FillChar(Mu, sizeof(Mu), 0);
MomentoAcumulado( DP, Omega, Mu );
Umbral := UmbralOptimo( Omega, Mu );
Matriz[(((Alto+Bloque)) div Bloque), ((Ancho) div Bloque)] := Umbral;
end;
Alto := Alto + Bloque;
end;
Result := Matriz;
end;
 
procedure Bina( M : TMatrizB; Imagen : TImage; Bloque : Integer );
var
i, j, Alto, Ancho, Fila, Columna : Integer;
begin
Alto := 0;
Fila := 1;
While( Alto <= Form1.Image1.Picture.Bitmap.Height -1 ) do
begin
Ancho := 0;
Columna := 1;
While( Ancho <= Form1.Image1.Picture.Bitmap.Width -1 ) do
begin
for j:= Alto to Alto + (Bloque - 1) do
begin
for i:= Ancho to Ancho + (Bloque - 1) do
begin
if ( Form1.Image1.Canvas.Pixels[i,j] and $FF >= M[Fila, Columna] ) then
Imagen.Canvas.Pixels[i,j] := RGB(255,255,255)
else
Imagen.Canvas.Pixels[i,j] := RGB(0,0,0);
end;
end;
Ancho := Ancho + Bloque ;
inc(Columna);
end;
Alto := Alto + Bloque;
inc(Fila);
end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
Var
M : TMatrizB;
begin
M := Segmentacion( 16, Image1 );
Bina( M, Image1, 16 );
end;


Saludos
Responder Con Cita
  #2  
Antiguo 23-02-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por bosterito
Esta binarización también emplea una interpolación bilineal, la cual no se como acoplarla al sistema
En estos momentos no tengo abierto el Delphi... y el código la verdad no lo entiendo bien. Deberías encerrar el código entre etiquetas DELPHI en vez de CODE

Si nos puede indicar de que manera estas tratando de acoplar al sistema te podemos ser más útil.

Cita:
Empezado por bosterito
Investigando en la web, di que el mejor método es el que trata el umbral de Otsu
¿Podrías indicarnos el enlace? A muchos les pueda servir. Además, es una buena manera de entender el código que expones.

Me voy a poner a ver el código... pero como te dije anteriormente: explicate bien a que te refieres cuando tratas de acoplarlo a tu sistema... ¿Te da un error?

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #3  
Antiguo 23-02-2007
Avatar de bosterito
bosterito bosterito is offline
Miembro
 
Registrado: nov 2006
Ubicación: Tucumán, Argentina
Posts: 39
Poder: 0
bosterito Va por buen camino
Hola.

Cita:
Originalmente Escrito por Delphius
Si nos puede indicar de que manera estas tratando de acoplar al sistema te podemos ser más útil.
El umbral calculado se lo asigna a cada región de la imagen y se lo extiende a través de una interpolación bilineal. El problema es que no consigo interpretar bien la interpolación bilineal para aplicarla al código. A continuación estan las referencias en las que más me guié:

http://www.gpi.tsc.uvigo.es/research-theses.html, cápitulo 1 y 2.
iaci.unq.edu.ar/.../archivos/apuntes/Segmentación%20por%20umbralización%20-%20Método%20de%20Otsu.pdf
www.freewebs.com/pdi2005/field_rectificacion.pdf



Saludos
Responder Con Cita
  #4  
Antiguo 24-02-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
bosterito, en mi tiempo libre voy a ver los pdf que indicas. No te prometo nada, pero voy a hacer lo posible (en lo que mis tiempos y ritmos me lo permitan) para ayudarte.

El tema me gusta, y yo también estoy metiendome en el tema de tratamiento de imagenes. Tengo que admitir que es la primera vez que escucho de este método para generar imagenes binarias.

Yo empleo otra técnica:

1. Transformar la imagen a escala de grises (si es necesario) ya sea mediante el método de la intensidad o el método de brillo.
2. A dicha imagen se la escanea linea a linea (con Scanline):
2.1. Por cada línea, se cambia el valor del pixel apuntado, de acuerdo a una simple ecuación:

Código Delphi [-]
if P^[k] >= umbral
  then P^[k] := 1
  else P^[k] := 0

Siendo P, el puntero de la linea:
Código Delphi [-]
P := Image.Bitmap.Scanline(j);

Claro está... que para que funcione apropiadamente, a cada canal (rojo: k = 3, verde: k = 2, y azul: k = 1) se le deba pasar el valor 1 o 0 según la condición.

Y ¡Listo! se obtiene una imagen binaria. Guardandola mejor con un formato de pf8bit.

No se cual será mejor... pero si te sirve, puede ser como una alternativa.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 24-02-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
bosterito, los dos ultimos enlaces no funcionan.

He visto un poco lo que pretendes, pero todavia no he logrado entenderlo del todo. Si hay una mente más cultivada en este tema a lo mejor puede ayudarte...

En los unicos pdf que me permite bajar (los que indicaste del enlace 1) No habla nada de un algoritmo de interpolación bilineal.

A manera simple, y por analogía al método de interpolación lineal... lo que trata de hacer la interpolación es predecir (léase calcular) un/os valor/es medio o promedio entre dos puntos A y B. Por ejemplo, si quieres calcular un sólo valor entre dos pixeles puedes hacer: (A+B)/2

Si quieres calcular dos valores:
x1 = (2A + B)/3
x2 = (A + 2B)/3

Ahora, al tratarse de un método bilineal... la cosa se complica. Pues (si nom me equivoco), el valor a calcular no se realiza mediante una función lineal sino polimonial con un grado 2. Una forma, parecida a, por poner ejemplo: A^2 + B.

No se mucho, yo ando investigando a la par tuya, espero que con esta info puedas seguir avanzando.
Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #6  
Antiguo 06-03-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Respuesta

Bueno, he visto los pdf de todos los links y no encuentro algo como para decir que el algoritmo necesita de una interpolación bilineal.

Ha decir verdad entiendo lo que dice el método del umbral de Otsu, y de lo que pude ver en tu código está bien. Funciona.

Solo puedo decirte que te conviene emplear la función scanline() en vez de acceder por pixeles. Es mucho más rápido.

Disculpa pero no más no puedo ayudarte. Yo he investigado acerca de esto también debido a que en mi tesis se trata un poquito del tema... y me ando poniendo al corriente en diferentes técnicas. Reconozco que es la primera vez que leo algo de Otsu... y lo que leí me parece interesante como para continuar.

Lo que me parece raro es que no te hayas dado una vuelta por aqui para ver si las otras cosas que te puse te sirven.

Saludos,

PD: si llego a saber de otras investigaciones y métodos sobre el asunto te aviso.
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Mover Imagen jorgito.crazy Gráficos 15 05-07-2006 15:34:29
Imagen en BDA majosf Conexión con bases de datos 1 13-12-2005 16:17:25
Imagen y Memo Sayuri Varios 3 07-12-2005 13:38:45
la imagen se ve mal.... User_baja1 Gráficos 0 10-06-2005 16:08:41
Imagen en SQL ramonibk Varios 2 18-02-2005 17:07:50


La franja horaria es GMT +2. Ahora son las 10:17:01.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi