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 29-06-2008
madiazg madiazg is offline
Miembro
 
Registrado: sep 2005
Ubicación: Canarias
Posts: 120
Poder: 19
madiazg Va por buen camino
Histograma

Hola a todos,
estoy realizando una aplicación para la generación de imágenes en 3D:
http://imagen3d.site88.net/
Esta aplicación muestra un histograma donde se muestran los valores de los tres componentes de color primarios (Rojo, Azul y Verde).
http://imagen3d.site88.net/img/ayuda9.jpg
El código que utilizo para generar el histograma es el siguiente:
Código:
CONST
    MaxPixelCount   =  32768;
TYPE
    pRGBTripleArray  =  ^TRGBTripleArray;  // Use SysUtils.pByteArray for 8-bit color
    TRGBTripleArray  =  ARRAY[0..MaxPixelCount-1] OF TRGBTriple;

procedure TFormSide.Action1Execute(Sender: TObject);
var
  i,j : integer;
  Row: pRGBTripleArray;
  BmpSbS : TBitmap;
//Histograma
  HRa,HBa,HGa: array[1..256] of integer; //Componentes del histograma
  R,G,B,Color : integer;
begin
//Reinicia Histograma
  FillChar(HRa,Sizeof(HRa),#0);
  FillChar(HGa,Sizeof(HGa),#0);
  FillChar(HBa,Sizeof(HBa),#0);

  BmpSbS := TBitmap.Create;
  TRY
//Utilizo la librería gráficos LibGFL de XnView para cargar las imágenes
//gfl_bmpSbS contiene la imagen a mostrar en pantalla

    BmpSbS.PixelFormat := pf24bit;
    BmpSbS.Width  := gfl_bmpSbS.Width;// Ancho de la imagen
    BmpSbS.Height := gfl_bmpSbS.Height;//Alto de la imagen
    FOR j := 0 TO BmpSbS.Height-1 DO
    BEGIN
      Row := BmpSbS.Scanline[j];
      FOR i := 0 TO BmpSbS.Width-1 DO
      BEGIN
        gflGetColorAt(gfl_bmpSbS,i,j,Pgfl_colorSbS);//Obtiene el valor de las componentes RGB
        WITH Row[i] DO
        BEGIN
          rgbtRed   := pgfl_colorSbS.Red;
          rgbtBlue   := pgfl_colorSbS.Blue;
          rgbtGreen   := pgfl_colorSbS.Green;
        //Histrograma
          inc(HRa[rgbtRed]);
          inc(HGa[rgbtGreen]);
          inc(HBa[rgbtBlue]);
        END
      END
    END;
    FormSide.Image1.Picture.Graphic := BmpSbS; // Muestra la imagen
    PanelPImagen1.Width := BmpSbS.Width + 2;
    PanelPImagen1.Height := BmpSbS.Height + 2;
  FINALLY
    BmpSbS.Free; //Libera Memoria
  END;
//Histograma
//Hay que calcular el valor máximo siempre y cuando HmaxSideCal sea TRUE. Esto lo realizo para que sólo se realice el cálculo la primera vez que se muestra
//la imagen y no cada vez que variemos la saturación, el contraste, etc... de la imagen
  if HmaxSideCal then
  begin
    HMaxSideCal := False; //Para que no se vuelva a calcular el valor máximo del Histograma
    HmaxSide:= 1;
    for i:= 1 to 256 do
    begin
      if HRa[i] > HmaxSide then HmaxSide:= HRa[i];
      if HGa[i] > HmaxSide then HMaxSide:= HGa[i];
      if HBa[i] > HmaxSide then HmaxSide:= HBa[i];
    end;
  end;
  ImageHa.Canvas.FillRect(ImageHa.Canvas.ClipRect);
//Muestra el Histograma  
  for i:= 1 to 256 do
  begin
    HRa[i] := Trunc((HRa[i] / HmaxSide) * 100);
    HGa[i] := Trunc((HGa[i] / HmaxSide) * 100);
    HBa[i] := Trunc((HBa[i] / HmaxSide) * 100);
    for j  := 1 to 256 do
    begin
      if j > HRa[i] then R := 0 else R := 255;
      if j > HGa[i] then G := 0 else G := 255;
      if j > HBa[i] then B := 0 else B := 255;
      if (R = 0) and (G = 0) and (B = 0) then Color := RGB(64,64,64) //
      else Color := RGB(R,G,B);
      ImageHa.Canvas.Pixels[i-1,101-j] := Color;
    end;
  end;
end;
El problema que tengo es que este método de mostrar el histograma es muy lento lo que produce que me ralentice el programa cuando modifico el brillo, contraste, etc...
¿A alguien se le ocurre alguna fórmula para aumentar la velocidad al mostrar el histograma?

Última edición por madiazg fecha: 05-07-2008 a las 23:14:31.
Responder Con Cita
  #2  
Antiguo 05-07-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Es un poco dificil ayudar cuando no se "tiene" el código completo; "undeclared identifier; pRGBTripleArray" !!! y bueno tambien vale la pena comentar el mismo problema acerca de las variables globales!

Eh aqui una posible solucion... tiene alguna falla pero no la puedo probar con el "original", por lo anteriormente comentado!

Código Delphi [-]
function GetHistogram(Image: TImage; UseMax: LongBool = True): TBitmap;
type
 RGBStruct = packed record
  b, g, r: byte;
 end;
var
 Color: ^RGBStruct;
 Count, Max: Cardinal;
 Index, Position, r, g, b: Byte;
 Histogram: array [0..255] of record
  r, g, b: Cardinal;
 end;
 Value: TColor;
begin
 Max := 0;
 Result := TBitmap.Create;
 Result.Assign(Image.Picture.Graphic);
 Result.PixelFormat := pf24bit;
 Count := Result.Width * Result.Height;
 Color := Result.ScanLine[Result.Height - 1];
 FillChar(Histogram, SizeOf(Histogram), 0);
 while LongBool(Count) do
  begin
   Inc(Histogram[Color.r].r);
   Inc(Histogram[Color.g].g);
   Inc(Histogram[Color.b].b);
   if UseMax then
    begin
     if Color.r > Max then Max := Color.r;
     if Color.g > Max then Max := Color.g;
     if Color.b > Max then Max := Color.b;
    end;
   Inc(Color);
   Dec(Count);
  end;
 Result.Width := 256;
 Result.Height := 256;
 if not UseMax then Inc(Max);
 for Index := 0 to 255 do
  begin
   Histogram[Index].r := (Histogram[Index].r * 100) div Max;
   Histogram[Index].g := (Histogram[Index].g * 100) div Max;
   Histogram[Index].b := (Histogram[Index].b * 100) div Max;
   for Position := 0 to 255 do
    begin
     r := Byte(Position <= Histogram[Index].r) * 255;
     g := Byte(Position <= Histogram[Index].g) * 255;
     b := Byte(Position <= Histogram[Index].b) * 255;
     if (r > 0) and (g > 0) and (b > 0) then
      Value := RGB(r, g, b)
     else
      Value := clGray shr 1;
     Result.Canvas.Pixels[Index, Position] := Value;
    end;
  end;
end;

Toma una atencion principal en la cantidad de bucles; y en el uso del ScanLine.

Un Saludo
Responder Con Cita
  #3  
Antiguo 05-07-2008
madiazg madiazg is offline
Miembro
 
Registrado: sep 2005
Ubicación: Canarias
Posts: 120
Poder: 19
madiazg Va por buen camino
Hola,
gracias por el interés mostrado. He editado mi primer mensaje para añadir pRGBTripleArray y aclarar un poco más el código que utilizo para mostrar el histograma. Estudiaré el código que me han enviado para ver si saco algo en claro porque la verdad es que me supera un poco.

Saludos...
Miguel Angel
Responder Con Cita
  #4  
Antiguo 05-07-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Cita:
Empezado por madiazg Ver Mensaje
...He editado mi primer mensaje para añadir pRGBTripleArray y aclarar un poco más el código que utilizo para mostrar el histograma...
Pues como lo comentaba, tampoco conozco la declaración de las variables ni funciones globales;
  • gflGetColorAt
  • pgfl_colorSbS
  • HmaxSideCal
  • HmaxSide

La idea es poder reproducir dicha funcion en un proyecto en limpio para rehacerlo (como ya lo habras notado en mi anterior post).

Si te continua dando mucha "lata", aclarame lo anterior a ver que se puede hacer

PD; el histograma solo se puede sacar de dos imagenes? las dos imagenes se deben entrelazar?

Saludos
Responder Con Cita
  #5  
Antiguo 06-07-2008
madiazg madiazg is offline
Miembro
 
Registrado: sep 2005
Ubicación: Canarias
Posts: 120
Poder: 19
madiazg Va por buen camino
Hola,
para el desarrollo del programa estoy utilizando la librería gráfica GFL SDK. En esta librería se define la función gflGetColorAt:

Cita:
gflGetColorAt: The gflGetColorAt function gets the color at a position of the picture.
GFL_ERROR gflGetColorAt(
GFL_BITMAP * src,
GFL_INT32 x,
GFL_INT32 y,
GFL_COLOR * color
);

Parameters
  • src: Pointer to a GFL_BITMAP structure.
  • x: X position.
  • y:Y position.
  • color: Pointer to a GFL_COLOR structure to obtain the result.
Return value
  • The function returns GFL_NO_ERROR if it is successful or a value of GFL_ERROR.
pgfl_colorSBS es, por tanto, una estructura del tipo GFL_COLOR:

Cita:
GFL_COLOR: The GFL_COLOR structure allow to define a color.
typedef struct (
GFL_UINT16
Red,
GFL_UINT16 Green,
GFL_UINT16 Blue,
GFL_UINT16 Alpha
} GFL_COLOR

Members
  • Red: Define the red component.
  • Green: Define the green component.
  • Blue: Define the blue component.
  • Alpha: Define the alpha component.
GFL_BITMAP:

Cita:
GFL_BITMAP: The GFL_BITMAP structure contains all informations about picture in memory.
typedef struct (
GFL_BITMAP_TYPE
Type,
GFL_ORIGIN Origin,
GFL_INT32 Width,
GFL_INT32 Height,
GFL_UINT32 BytesPerLine,
GFL_INT16 LinePadding,
GFL_UINT16 BitsPerComponent,
GFL_UINT16 ComponentsPerPixel,
GFL_UINT16 BytesPerPixel,
GFL_UINT16 Xdpi,
GFL_UINT16 Ydpi,
GFL_INT16 TransparentIndex,
GFL_INT32 ColorUsed,
GFL_COLORMAP * ColorMap,
GFL_UINT8 * Data,
char * Comment,
void * MetaData
} GFL_BITMAP

Members
  • Type Type of the picture
    • GFL_BINARY 0x0001 Binary
    • GFL_GREY 0x0002 Grey scale
    • GFL_COLORS 0x0004 Colors with colormap
    • GFL_RGB 0x00010 TrueColors - Red/Green/Blue
    • GFL_RGBA 0x0020 TrueColors - Red/Green/Blue/Alpha
    • GFL_BGR 0x0040 TrueColors - Blue/Green/Red
    • GFL_ABGR 0x0080 TrueColors - Alpha/Blue/Green/Red
    • GFL_BGRA 0x0100 TrueColors - Blue/Green/Red/Alpha
    • GFL_ARGB 0x0200 TrueColors - Alpha/Red/Green/Blue
    • GFL_CMYK 0x0400 TrueColors - Cyan/Magenta/Yellow/Black
  • Origin Origin of the picture.
    • GFL_TOP_LEFT 0 Top left (default)
    • GFL_BOTTOM_LEFT 2 Bottom left GFL_TOP_RIGHT 1 Top right
    • GFL_BOTTOM_RIGHT 3 Bottom right
  • Width Width in pixels of the picture.
  • Height Height in pixels of the picture.
  • BytesPerLine Bytes per line of pixels.
  • LinePadding Internal use, do not modify.
  • BitsPerComponent Bits per component, can be 1, 8, 16
  • ComponentsPerPixel Component per pixel, can be 1, 3 or 4
  • BytesPerPixel Bytes per pixel (For example: 1, 3 or 4).
  • Xdpi Pixels per inch in X axis.
  • Ydpi Pixels per inch in Y axis.
  • TransparentIndex Index of transparency (only for GFL_COLORS & GFL_GREY type).
  • ColorUsed Number of color used in the picture (only for GFL_COLORS & GFL_GREY type).
  • ColorMap Address of a GFL_COLORMAP structure for the colormap (only for GFL_COLORS type).
  • Data Pointer of the picture data.
  • Comment Address of a string used by the comment. You must use gflSetComment to change the comment.
  • MetaData Pointer of Metadata. You must use gflBitmapGetIPTC & gflBitmapGetEXIF to obtain readable data.
HMaxSideCal es una variable del tipo Boolean que utilizo para determinar si realizo el cálculo del valor máximo del histograma. Este cálculo sólo lo realizo cuando se carga incialmente la imagen y no lo vuelvo a realizar cuando dicha imagen se refrezca al cambiar el brillo, contraste, saturación, etc...
HMaxSide es el valor máximo del histograma, y es del tipo integer.

GFL_SDK es una librería desarrollada en C y me da algunos quebraderos de cabeza que todavía no he podido resolver (como la obtención de los datos EXIF de una fotografía, lo Metadatos, etc...). Aún así, es muy potente a la hora de 'gestionar' fotografías, tal y como queda demostrado en la aplicación XnView.

Saludos y gracias por el interés...
Miguel Angel
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
Histograma en Delphi Cesar Junior Gráficos 10 05-07-2012 12:36:42
Histograma. Obtener máximos y mínimos relativos Delphius Varios 7 16-04-2007 12:12:46
Histograma javikanin Varios 16 02-01-2006 23:40:17
Graph Meter (histograma) cadena Gráficos 0 01-12-2004 19:29:23


La franja horaria es GMT +2. Ahora son las 00:04:17.


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