Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Gráficos (https://www.clubdelphi.com/foros/forumdisplay.php?f=8)
-   -   Filtro contraste (https://www.clubdelphi.com/foros/showthread.php?t=53194)

schaka 13-02-2008 18:15:35

Filtro contraste
 
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 [-]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

Disculpa
 
ok , disculpa, aki va de nuevo

Código Delphi [-]
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:
Código Delphi [-]
while i<=( (ancho*3)-1) do
Cuando debería de ser:
Código Delphi [-]
while i<=( (ancho-1)*3) do

Luego me parece que esta comparación siempre es verdadera, al tratarse siempre de números positivos:
Código Delphi [-]
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í:

Código Delphi [-]
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:

Código Delphi [-]
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:

Código Delphi [-]
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 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 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


La franja horaria es GMT +2. Ahora son las 08:36:12.

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