FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
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 |
#2
|
||||
|
||||
Cita:
Si nos puede indicar de que manera estas tratando de acoplar al sistema te podemos ser más útil. Cita:
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, |
#3
|
||||
|
||||
Hola.
Cita:
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 |
#4
|
||||
|
||||
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:
Siendo P, el puntero de la linea:
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, |
#5
|
||||
|
||||
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, |
#6
|
||||
|
||||
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. |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
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 |
|