PDA

Ver la Versión Completa : Filtro contraste


schaka
13-02-2008, 18:15:35
hola que tal ,tengo un problemita con unos filtros de imagenes con contrsate logaritmico y exponencial, cuando aplico el filtro me pone toda la imagen en negro, ya revise mi codigo y no le encuentro el porque, aqui les pongo mi filtro, espero me puedan ayudar el motivo de pk la pone toda en negro, gracias.
Código SQL [-] (http://www.clubdelphi.com/foros/#)procedure TFMain.Contrastelog1Click(Sender: TObject);
var i,j,mayor, menor:integer;

begin mayor:=0; menor:=255; (*SE CALCULARA EL MAXIMO Y MINIMO PIXEL DE UNA IMAGEN Y SE LE ASIGNARA A PIXEL EL VALOR DE LA FORMULA DEL CONTRASTE*) for j := 0 to alto-1 do begin PLine := Bitmap.ScanLine[j]; i:=0; while i<=( (ancho*3)-1) do begin if ((PLine[i]+PLine[i+1]+PLine[i+2]) div 3) > mayor
then begin mayor:= ((PLine[i]+PLine[i+1]+PLine[i+2]) div 3) ; end; (*if mayor*)

if (PLine[i]+PLine[i+1]+PLine[i+2]div 3) < menor
then begin menor:= ((PLine[i]+PLine[i+1]+PLine[i+2]) div 3) ; end; (*if menor*)

if ( mayor+ menor )> 0
then begin pixel :=(mayor-menor)div( mayor+ menor ) ; end;

i:=i+3;
end; (*while*)
end; (*end for j*)



for j := 0 to alto-1 do begin PLine := Bitmap.ScanLine[j]; i:=0; while i<= (ancho*3)-1 do begin if PLine[i] <= 0 then PLine[i]:=1; PLine[i]:= 2*round(ln(pixel)+ln(PLine[i]))+5; if PLine[i] <= 0 then begin PLine[i]:=0; end;

if PLine[i] > 255 then begin PLine[i]:=255;end else begin PLine[i]:= 2*round(ln(pixel)+ln(PLine[i]))+5; end;

if PLine[i+1] <= 0 then PLine[i+1]:=1; PLine[i+1]:= 2*round(ln(pixel)+ln(PLine[i+1]))+5; if PLine[i+1] <= 0 then PLine[i+1]:=0; if PLine[i+1] > 255 then begin PLine[i+1]:=255;end else begin PLine[i+1]:= 2*round(ln(pixel)+ln(PLine[i+1]))+5; end;

if PLine[i+2] <= 0 then PLine[i+2]:=1; PLine[i+2]:= 2*round(ln(pixel)+ln(PLine[i+2]))+5; if PLine[i+2] <= 0 then PLine[i+2]:=0; if PLine[i+2] > 255 then begin PLine[i+2]:=255;end else begin PLine[i+2]:= 2*round(ln(pixel)+ln(PLine[i+2]))+5; end;

i:=i+3;
end;

end;

Image1.Picture.Assign(Bitmap);

end; (*begin metodo*)

Delphius
13-02-2008, 18:42:52
Hola schaka, podrías editar el mensaje e incluir las etiquetas DELPHI por favor (y tabularlo mejor)? Es ilegible el código que expones.

De esta manera podré comprender mejor el código y ver donde puede estar el fallo.

Saludos,

schaka
13-02-2008, 19:25:02
ok , disculpa, aki va de nuevo


procedure TFMain.Contrastelog1Click(Sender: TObject);
var i,j,mayor, menor:integer;

begin mayor:=0; menor:=255;

(*SE CALCULARA EL MAXIMO Y MINIMO PIXEL DE UNA IMAGEN Y
SE LE ASIGNARA A PIXEL EL VALOR DE LA FORMULA DEL CONTRASTE*)

for j := 0 to alto-1 do begin
PLine := Bitmap.ScanLine[j];
i:=0; while i<=( (ancho*3)-1) do
begin if ((PLine[i]+PLine[i+1]+PLine[i+2]) div 3) > mayor
then begin
mayor:= ((PLine[i]+PLine[i+1]+PLine[i+2]) div 3) ;
end; (*if mayor*)
if (PLine[i]+PLine[i+1]+PLine[i+2]div 3) < menor
then begin
menor:= ((PLine[i]+PLine[i+1]+PLine[i+2]) div 3) ;
end; (*if menor*)
if ( mayor+ menor )> 0
then begin pixel :=(mayor-menor)div( mayor+ menor ) ;
end;

i:=i+3;
end; (*while*)
end; (*end for j*)
for j := 0 to alto-1 do begin
PLine := Bitmap.ScanLine[j];
i:=0;
while i<= (ancho*3)-1 do begin
if PLine[i] <= 0 then
PLine[i]:=1; PLine[i]:= 2*round(ln(pixel)+ln(PLine[i]))+5;

if PLine[i] <= 0 then
begin PLine[i]:=0; end;

if PLine[i] > 255 then
begin PLine[i]:=255;end

else begin PLine[i]:= 2*round(ln(pixel)+ln(PLine[i]))+5; end;

if PLine[i+1] <= 0 then
PLine[i+1]:=1;
PLine[i+1]:= 2*round(ln(pixel)+ln(PLine[i+1]))+5;

if PLine[i+1] <= 0 then
PLine[i+1]:=0;

if PLine[i+1] > 255 then
begin PLine[i+1]:=255;end

else begin PLine[i+1]:= 2*round(ln(pixel)+ln(PLine[i+1]))+5;
end;

if PLine[i+2] <= 0 then
PLine[i+2]:=1; PLine[i+2]:= 2*round(ln(pixel)+ln(PLine[i+2]))+5;
if PLine[i+2] <= 0 then
PLine[i+2]:=0;
if PLine[i+2] > 255 then
begin PLine[i+2]:=255;end
else begin PLine[i+2]:= 2*round(ln(pixel)+ln(PLine[i+2]))+5; end;

i:=i+3;
end;

end;

Image1.Picture.Assign(Bitmap);

end; (*begin metodo*)

Delphius
13-02-2008, 20:00:44
Muchas gracias schaka,
Ahora se ve algo mejor.

Tengo que comparar al algoritmo que tienes con mis apuntes... si a ese algoritmo lo estudiaste o sacaste de algún lado puede que resulte de utilidad que nos cite la fuente.

Como no tengo muy a mano mis apuntes en estos momentos es probable que me demore. Supongo que no hay problema con ello...

Veo que haz colocado una variable pixel y no está declarada allí... ¿es global?
Noto además que no haces una comprobación del formato y de los bits que usa. Supongo que estás trabajando directamente con imagenes bmp y de 24 bits.

El problema del color a negro, a simple vista no le hallo causa... a menos que sea un error humano y hayas invertido el sentido de alguna operación.

Saludos,

schaka
13-02-2008, 20:19:06
Muchas gracias, bueno pues el metodo me lo he ideado, ya que la unica informacion que tengo para realizar un contraste por medio de logaritmo es una formula :


y=b*log(mx)+c , "b" y "c" son constantes , "X" el el valor de mi pixel o canal, "Y" es el canal o pixel al que le aplico el cambio

m=(a-b)/(a+b) a es el valor del pixel mas grande y b el mas chico

hojala puedas ayudarme proporcionandome un metodo para poder hacer este contraste

Delphius
13-02-2008, 20:43:33
Ummm.... La función que yo conozco es de la forma:

q = L x ln( 1 + p) / ln( 1 + L)

siendo L el máximo valor que toma un pixel en la imagen
p el valor actual
ln: la función logaritmo natural.

Aunque creo haber visto en algún lado la función que tu comentas.
Creo que por allí viene la mano.

Me tengo que retirar por ahora, si puedo en unas horas vuelvo.
Saludos,

seoane
13-02-2008, 20:47:06
A primera vista aquí hay un error:

while i<=( (ancho*3)-1) do

Cuando debería de ser:

while i<=( (ancho-1)*3) do


Luego me parece que esta comparación siempre es verdadera, al tratarse siempre de números positivos:

if ( mayor+ menor )> 0


Vete corrigiendo eso, y luego ya veremos ;)

Delphius
14-02-2008, 04:02:06
Bueno schaka,
Tu código fue resumido, parte del mismo se podía mejorar y eso hice. Tal como dices, tu código genera una imagen en negro. Creo que tienes mal la definición del filtro.

Tu código, que lo incorporé en un procedimiento llamado filtradoLogaritmicoA quedó así:

procedure TForm1.filtradoLogaritmicoA(Image: TPicture);
var Maxx, Minx, pixel: integer;
i, j, k: integer;
bmp: TBitmap;
RGB: ^TRGB;
begin
//Chequeamos que sea BMP
// sino la convertimos
if not (Image.Graphic is TBitmap)
then begin
bmp:= TBitmap.Create;
try
bmp.Width:= Image.Width;
bmp.Height:= Image.Height;
bmp.Canvas.Draw(0,0,Image.Graphic);
Image.Assign(Bmp);
finally
Bmp.Free;
end;
end;
// le damos formato a 24 bits
// esencial para poder trabajar con RGB
Image.Bitmap.PixelFormat := pf24bit;

// empezamos...
Maxx := 0; Minx := 255;
for j := 0 to Image.Bitmap.Height - 1 do
begin
RGB := Image.Bitmap.ScanLine[j];
for i := 0 to Image.Bitmap.Width - 1 do
begin
// buscamos al mayor
if ((RGB^[1] + RGB^[2] + RGB^[3]) div 3) > Maxx
then Maxx := ((RGB^[1] + RGB^[2] + RGB^[3]) div 3);
// buscamos al menor
if ((RGB^[1] + RGB^[2] + RGB^[3]) div 3) < Minx
then Minx := ((RGB^[1] + RGB^[2] + RGB^[3]) div 3);

pixel := (Maxx - Minx) div(Maxx + Minx);

inc(RGB);
end; //fin while
end; // fin j

// aqui comienza el filtro
for j := 0 to Image.Bitmap.Height - 1 do
begin
RGB := Image.Bitmap.ScanLine[j];
for i := 0 to Image.Bitmap.Height - 1 do
begin
for k := 1 to 3 do
begin
if RGB^[k] <= 0
then RGB^[k]:= 1;
RGB^[k]:= 2 * round(ln(pixel) + ln(RGB^[k])) + 5;

// que no era la formula así: a * log(m * x) + b?
//RGB^[k]:= 2 * round(log10(pixel * RGB^[k])) + 5;

// controlar el rago del valor
if RGB^[k] <= 0
then RGB^[k] := 0;

if RGB^[i + k] > 255
then RGB^[k] := 255;
end; // fin k
inc(RGB);
end; // fin i
end;
end;

Como dije... yo la formula me la conocía así: q = L x ln(1 + p) / ln(1 + L)
Por lo que hice la prueba... y que crees, parece que funciona... al menos con las imagenes que puse no las puso en blanco ni en negro.

Mi código es simple, "parecido" al tuyo mejorado. Lo llamé filtradoLogaritmicoB:

procedure TForm1.filtradoLogaritmicoB(Image: TPicture);
var
i, j, k: integer;
bmp: TBitmap;
RGB: ^TRGB;
begin
//Chequeamos que sea BMP
// sino la convertimos
if not (Image.Graphic is TBitmap)
then begin
bmp:= TBitmap.Create;
try
bmp.Width:= Image.Width;
bmp.Height:= Image.Height;
bmp.Canvas.Draw(0,0,Image.Graphic);
Image.Assign(Bmp);
finally
Bmp.Free;
end;
end;
// le damos formato a 24 bits
// esencial para poder trabajar con RGB
Image.Bitmap.PixelFormat := pf24bit;

// empezamos...
// aqui comienza el filtro
for j := 0 to Image.Bitmap.Height - 1 do
begin
RGB := Image.Bitmap.ScanLine[j];
for i := 0 to Image.Bitmap.Height - 1 do
begin
for k := 1 to 3 do
begin
RGB^[k]:= trunc(255 * ln(1 + RGB^[k]) / ln(1 + 255));
end; // fin k
inc(RGB);
end; // fin i
end;
end;



Siendo TRGB de esta forma:

TRGB = array [1..3] of byte;

No encontré ente mis apuntes, yo recordaba tener en algún lado algo sobre el filtrado logaritmico... y como no estaba seguro de la fórmula, busqué en internet un poco y salio un sitio (http://sabia.tic.udc.es/gc/Contenidos%20adicionales/trabajos/Imagenyvideo/Procesado%20Digital%20de%20la%20Imagen/pagina_superior5.htm) que la muestra como la recordaba.

Sin embargo, también recuerdo de algun lado, que vi una fórmula como la que tu indicas ( a * log(m * p) +b) pero entre mis apuntes no está...

Debe ser que lo he perdido durante la falla de mi disco y no lo tengo entre mis discos de respaldos.

Podríamos esperar a seoane para ver con que nos sale. Si es que el se acuerda de algo. Tengo que admitir que mucho de los filtros no recuerdo... como lo vi he hice lo necesario para continuar, no profundizé mis conocimientos.

Espero que esto te sea de ayuda.

Saludos,

schaka
14-02-2008, 19:25:56
Muchas Gracias , Por Tu Ayuda Me Ha Sido Muy Util , Aplicanco La Formula Que Tenia , No Me Salian Bien Las Cosas, Ahora Me Tengo Que Hacer Un Contrsate Exponencial Y Lineal , Espero Me Puedas Ayudar Con Tus Formulas Para Poder Realizar Estos Filtros, Muchisimas Gracias Por Tu Ayuda

Delphius
14-02-2008, 19:47:04
schaka,
Respeta la guia de estilo (http://www.clubdelphi.com/foros/guiaestilo.php) por favor. ¿Te resulta fácil escribir asi?:confused:

Te aclaro, que parte de lo que tengo no puedo cederlo. Estaría violando algunas condiciones de mi trabajo de tesis. Si yo ofrecí mi ayuda es porque vi que podía hacerlo y no afectaba a mi trabajo.

Tampoco espero que sientas que debo estar obligado a ayudarte. Los algoritmos de filtrado lineales y exponenciales obeceden a dicha distribución o ecuaciones... No creo que te resulte dificil programarlos teniendo como base lo que te expuse.

En forma general:
Lineal: obeceden una ecuación de la recta: ax + b
Exponencial: obedecen a una distribución exponecial: aExp(x)

No quiero que esperes a que te haga el algoritmo, primero tu hazlo y después si tienes mayores problemas nos informas. Si te mostré dicho algoritmo es para que comprendieras donde está tu error.

Espero que no tomes a mal lo que te he dicho. Pero al decirme "Espero me puedas ayudar con tus fórmulas", me pones en una situación de "compromiso". El compromiso tiene que venir de ti cuando expongas tus problemas. Como te he dicho antes, te pedía que citaras tu fuente para ver si estabas haciendo si comprendías bien... pero te limitaste a exponer una ecuación.

Mis fuentes o bibliografía pueden ser distintas a las tuyas. Y es por eso que prefiero, en lo que pueda, darte mi ayuda siguiendo tus apuntes.


Nuevamente disculpas si mi comentario te ha resultado agresivo, pero mejor aclararlo ahora.

Saludos,

schaka
14-02-2008, 21:29:39
No hay ningun problema amigo , mi intencion no era la que entendiste, simplemente me di cuenta que mi informacion podia estar mal con respecto a las formulas que aplicaba, en mi problema de logaritmo, que gracias a ti lo resolvi, y te lo agradesco, posiblemente el mayor error era en la formula logaritmica que estaba utilizando que era diferente a la que me planteaste en tu solucion .
Por este simple motivo inferi que talvez mis formulas estaban mal para aplicar mi algoritmo, y tu al darme una formula correcta para calcular mi contraste, posiblemente tendrias alguna formula para calcular mi contraste con un metodo exponencial y lineal , eso era todo, nunca te pedi codigo completo ni mucho menos, comprendo la naturaleza del foro.
Disculpa si te sentiste en algun comento comprometido, no fue mi intencion, reitero mis agradecimientos.
Saludos