• Sábado 18 de Mayo de 2024, 20:20

Autor Tema:  Convertir Una Imagen Rgb A Escala De Grises  (Leído 17450 veces)

KAYSS

  • Nuevo Miembro
  • *
  • Mensajes: 19
    • Ver Perfil
Convertir Una Imagen Rgb A Escala De Grises
« en: Sábado 8 de Septiembre de 2007, 20:00 »
0
He encontrado una solución pero es muy lenta (3, 4 seg en procesarla), a ver si me podéis decir otra o una modificación de esta más rápida:

double bn;
Color color, ColorBN;

for(int i=0; i<Imagen->Width; i++){
    for (int j=0; j<Imagen->Height; j++){
         color=Imagen->GetPixel(i,j);
         bn=(double) ((color.R*30)+(color.G*59)+ (color.B*11));
         ColorBN=Color::FromArgb(bn,bn,bn);
         ImagenBN->SetPixel(i,j,ColorBN);
    }
}


this->PictureBoxImagen->Image=this->ImagenBN;

Saludos, kayss

gatiori

  • Nuevo Miembro
  • *
  • Mensajes: 6
    • Ver Perfil
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #1 en: Miércoles 7 de Noviembre de 2007, 00:24 »
0
Bueno, yo no conosco mucho de programación, pero segun entiendo que para la escala de grises se deben promediar los valores de R, G y B o sea ( R + G + B ) / 3

Esta linea no la entiendo: bn=(double) ((color.R*30)+(color.G*59)+ (color.B*11));

... es decir por qué multiplicar por 30 para el rojo, 59 para el verde y 11 para el azul?

creo que sería así:

bn = ( color.R + color.G + color.B ) / 3

... pero mejor dejemos que alguien que sepa másn nos explique... no?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #2 en: Miércoles 7 de Noviembre de 2007, 10:26 »
0
Se hicieron estudios y se demostro que: To convert any color to its most approximate level of gray, first one must obtain the values of its red, green and blue (RGB) primaries.

Then it is sufficient to add 30% of the red value plus 59% of that of the green plus 11% of that of the blue, no matter whatever scale is employed. The resultant level is the desired gray value. These percentages are chosen due to the different relative sensitivity of the normal human eye to each of the primary colors (higher to the green, lower to the blue).

Desde Wikipedia.

Igual NO es blanco y negro, son 256 (de 0 a 255) colores (grises) diferentes y en realidad el codigo deberia ser asi:

Código: Text
  1. bn=(double) ((color.R*0.3)+(color.G*0.59)+ (color.B*0.11));
  2.  

O deberias dividir por 100 el resultado final en tu codigo ya que sino el valor de bn nunca estara entre 0 y 255, y sera invalido:
Color.FromArgb (Int32, Int32, Int32): Creates a Color structure from the specified 8-bit color values (red, green, and blue). The alpha value is implicitly 255 (fully opaque). Although this method allows a 32-bit value to be passed for each color component, the value of each component is limited to 8 bits.

De la MSDN.

Es muy probable que el cuello de botella este en GetPixel y SetPixel.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

drd

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #3 en: Miércoles 7 de Noviembre de 2007, 12:03 »
0
No has pensado en usar alguna biblioteca de tratamiento de imágenes, como openCV, CImage y cosas así, esas operaciones las hacen muy rápido, aunque claro, tienes que usar en memoria su formato de imagen, supongo que a lo mejor te puedes meter en las tripas a ver que hacen, aunque yo no me atrevería.

Un saludo.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #4 en: Miércoles 7 de Noviembre de 2007, 14:21 »
0
Cita de: "drd"
No has pensado en usar alguna biblioteca de tratamiento de imágenes, como openCV, CImage y cosas así, esas operaciones las hacen muy rápido, aunque claro, tienes que usar en memoria su formato de imagen, supongo que a lo mejor te puedes meter en las tripas a ver que hacen, aunque yo no me atrevería.
Pasar una imagen de RGB a escala de grises es algo muy simple, incluso usando el promedio (como dijo gatiori) se obtiene un resultado cercano al esperado.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

drd

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #5 en: Jueves 8 de Noviembre de 2007, 10:23 »
0
Yo lo decía más que nada porque se quejaba del tiempo que tardaba, yo las uso para otras cosas y en eso no se pierde nada de tiempo, pero vosotros sabéis mucho más que yo, desde luego  :D

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #6 en: Jueves 8 de Noviembre de 2007, 10:29 »
0
Cita de: "drd"
Yo lo decía más que nada porque se quejaba del tiempo que tardaba, yo las uso para otras cosas y en eso no se pierde nada de tiempo, pero vosotros sabéis mucho más que yo, desde luego  :D
Bueno, en lo que tarda es en mostrarla en pantalla en realidad.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #7 en: Jueves 6 de Diciembre de 2007, 19:40 »
0
Puede ya ser muy tarde ....
pero ahi va.
Código: Text
  1.  
  2. double bn;
  3.  

Realmente debe ser de tipo double? ... muy sospechoso...
<!--xc1--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>XCODE </td></tr><tr><td id='XCODE'><!--exc1-->
for(int i=0; i<Imagen->Width; i++){
    for (int j=0; j<Imagen->Height; j++){
         color=Imagen->GetPixel(i,j);

         bn=(double) ((color.R*30)+(color.G*59)+ (color.B*11));
        ColorBN=Color::FromArgb(bn,bn,bn);
         ImagenBN->SetPixel(i,j,ColorBN);

    }
}<!--xc2--></td></tr></table><div class='postcolor'><!--exc2-->

con esto ya te estas matando solito....

si te interesa la precisión del gris.. ok hazlo , pero lo mas rápido aunque no tan preciso es simplemente volver iguales al r al g y al b, toma como referencia el valor medio (o el promedio) entre los tres y sale.

Usando GetPixel y SetPixel siempre sera lento, lo mejor es que (ya presumo que estas usando CLR) es que del objeto Bitmap hagas un lockbits y luego recorras toda esta info (ojo con los bytes de padding) para hacer las operaciones de modificación que te señalé para convertir el color, o incluso la de los porcentajes... ahí ya habrás ganado MUCHO...
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Geo

  • Miembro de PLATA
  • *****
  • Mensajes: 1011
  • Nacionalidad: mx
    • Ver Perfil
    • http://hsblog.mexchip.com
Re: Convertir Una Imagen Rgb A Escala De Grises
« Respuesta #8 en: Jueves 6 de Diciembre de 2007, 21:13 »
0
También voy por la idea de que el cuello de botella son GetPixel y SetPixel.
La imaginación es el límite.
Hardware & Software | Mexchip