Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Duda importante C++

Estas en el tema de Duda importante C++ en el foro de C/C++ en Foros del Web. Hola, soy nuevo en el foro y también bastante nuevo en el mundo de C++. Mi problema es que tengo que hacer un programa que ...
  #1 (permalink)  
Antiguo 22/11/2011, 12:52
 
Fecha de Ingreso: noviembre-2011
Mensajes: 2
Antigüedad: 12 años, 5 meses
Puntos: 0
Duda importante C++

Hola, soy nuevo en el foro y también bastante nuevo en el mundo de C++. Mi problema es que tengo que hacer un programa que lea una foto (.jpg) y al final me diga si esa foto es de día o de noche(las fotos solo son de exteriores, y ya están escogidas por el profesor). Vayamos por partes, primero me gustaría que me ayudaseis a como hacer para leer una imagen con C++ que sea .jpg (tamaño 640x480 por si es importante).

En lo demás también estoy bastante perdido porque nuestro profesor no nos ha dado muchas pistas. Muchas gracias y a ver si algunos me podría ayudar.

Un saludo.
  #2 (permalink)  
Antiguo 22/11/2011, 15:47
(Desactivado)
 
Fecha de Ingreso: septiembre-2011
Ubicación: Casupá, Florida, Uruguay
Mensajes: 70
Antigüedad: 12 años, 6 meses
Puntos: 4
Respuesta: Duda importante C++

tu profesor te dio una pista, te dijo que la imagen es de 640x480 pixeles,
has un programa que haga un promedio del color de todos los pixeles
tipo mirando si la foto en promedio tiene mas pixeles oscuros que pixeles claros sera una foto de noche, si tiene mas pixeles claros sera de dia,
  #3 (permalink)  
Antiguo 22/11/2011, 23:57
 
Fecha de Ingreso: abril-2011
Ubicación: Distrito Federal
Mensajes: 112
Antigüedad: 13 años
Puntos: 17
Respuesta: Duda importante C++

Este tipo de ejercicios es para explotar tu creatividad, así que debes analizar e imaginarte una solución.

Yo partiría de contar todos los pixeles que tienen un color azul compatible con el color azul del cielo cuando es de día. Si hay una gran cantidad de puntos azules determinas que es de día, de lo contrario dices que es de noche.

Cómo es eso de detectar un color azul?

Los pixeles de una imagen se descomponen en tres partes: los componentes RGB que son Red, Green y Blue, o sea Rojo, Verde y Azul. Generalmente cada componente se mide desde el 0 hasta el 255. Se usa 0 cuando un color no tiene determinado componente y 255 cuando tiene un componente completo en ese rango de color.

Bajo esta nomenclatura, el color de un pixel se representa con tres números, por ejemplo el (0, 0, 0) es el negro, el (255, 255, 255) es el blanco, el (127, 0, 0) es un rojo obscuro, el (0, 200, 0) es un verde algo brillante, el (0, 0, 255) el el azul más claro que hay, (255, 255, 0) es un morado, etc. etc.

Sabiendo eso, debes buscar los tres números que representan al color azul cielo típico en una foto. Luego debes determinar una manera de decir que un punto de color azul de una foto es similar a tu color azul típico y cuáles no.

Digamos que tu color azul típico es (0, 128, 255). Para saber que si se parece a otro punto de color (100, 150, 100) haces la resta entre cada componente y los resultados serían (-100, -22, 155), imaginemos que tu tolerancia es de (+-)15, este punto no pasaría como un punto similar. Si hacemos los mismo con un punto de color (5, 130, 250) el resultado sería (-5, -2, 5), en este caso los tres resultados están dentro de la tolerancia de (+-)15 y con eso determinas que el punto es parecido.

Bajo este método sería fácil ubicar todos los puntos que representan el color azul cielo dentro de tu foto. Si sobrepasan determinada cantidad, por ejemplo unos 5 mil puntos, puedes decir que esa foto tiene una gran cantidad de puntos azul cielo (de día).

Espero que te inspires.
  #4 (permalink)  
Antiguo 23/11/2011, 17:29
 
Fecha de Ingreso: noviembre-2011
Mensajes: 2
Antigüedad: 12 años, 5 meses
Puntos: 0
Respuesta: Duda importante C++

Muchas gracias a los dos.

"jevangelista", me habian dicho algo ya de dividirlo en pixeles y separarlo en RGB, pero no tengo muy claro como hacer eso en C++, como puedo hacer para analizar un pixel y saber que valores RGB tiene y poder operar con ellos?

gracias de verdad :)
  #5 (permalink)  
Antiguo 23/11/2011, 17:41
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Duda importante C++

Nunca lo he usado pero parece una buena libreria:

http://freeimage.sourceforge.net/
  #6 (permalink)  
Antiguo 25/11/2011, 02:54
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 10 meses
Puntos: 73
Respuesta: Duda importante C++

Un archivo de imagen, en formato BMP, tiene una cabecera que contiene la información acerca de la imagen (tamaño, colores, etc), seguida de los valores de la imagen, pixel a pixel. La estructura de esta cabecera puedes encontrarla en Internet. Siguiendo a esta cabecera, vienen los datos de la imagen por orden, aunque no recuerdo si comienza por la esquina superior izquierda o inferior izquierda.

Si la imagen se guardó con 24 bits de color, para cada pixel tendrás 3 bytes, uno para rojo (R), otro para verde (G) y otro para azul (B), de este modo:

RRGGBB RRGGBB RRGGBB (etc)

(bueno, no recuerdo si aparecen así o aparecen BBGGRR) donde cada secuencia RRGGBB representa 1 pixel.

Si la imagen se guardó con 32 bits de color, a cada pixel le corresponde un entero de 32 bits (4 bytes). El número de colores es el mismo, simplemente se guarda un byte adicional que es siempre cero. En los cuatro bytes de ese entero (que corresponde a un pixel) vas a tener

00 RR GG BB

(aquí sí estoy seguro del orden), es decir, el primer byte es siempre 0, el segundo corresponde al rojo, el tercero al verde y el último al azul. Puedes tratarlos como una matriz de enteros, o puedes obtener tres matrices de bytes, una por color.

Sobre el formato JPG, este lleva algo de compresión, es cuestión de buscar la estructura del archivo y cómo se hace la compresión y descompresión. Una vez restaurada la imagen puedes obtener una o varias matrices de pixels, como las citadas arriba.

Sobre el tema de decidir si la foto se tomó de día o de noche, piensa que si fué de noche lo más probable es que las líneas de pixeles de la parte superior estarán muy oscuras (valores muy bajos de las tres componentes de color), mientras que si fué de día tendrás valores altos de azul y/o verde (no necesariamente de rojo), y si estaba nublado tendrás valores similares de los tres colores (los grises se forman con las tres componentes de color iguales). Incluso, si la componente de rojo es relativamente elevada frente a las de azul y/o verde, puedes pensar que la foto se tomó al amanecer o atardecer.

Convendría que te hicieras con un editor hexadecimal y que abrieras con él el archivo de imagen, así podrás ver "de primera mano" la cabecera del archivo y los datos, esto te ayudará.

Un último detalle si utilizas el editor hexadecimal o tu programa va a leer el archivo byte por byte: Los procesadores INTEL guardan los números (sean del tipo que sean) comenzando por el byte menos significativo (se denomina formato little-endian), por ejemplo, el entero que me guarda la información del pixel, que sería 00 RR GG BB, estará almacenado como BB GG RR 00 (lo puedes ver con el editor hexadecimal).

Saludos,
  #7 (permalink)  
Antiguo 25/11/2011, 02:59
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 10 meses
Puntos: 73
Respuesta: Duda importante C++

Un archivo de imagen, en formato BMP, tiene una cabecera que contiene la información acerca de la imagen (tamaño, colores, etc), seguida de los valores de la imagen, pixel a pixel. La estructura de esta cabecera puedes encontrarla en Internet. Siguiendo a esta cabecera, vienen los datos de la imagen por orden, aunque no recuerdo si comienza por la esquina superior izquierda o inferior izquierda.

Si la imagen se guardó con 24 bits de color, para cada pixel tendrás 3 bytes, uno para rojo (R), otro para verde (G) y otro para azul (B), de este modo:

RRGGBB RRGGBB RRGGBB (etc)

(bueno, no recuerdo si aparecen así o aparecen BBGGRR) donde cada secuencia RRGGBB representa 1 pixel.

Si la imagen se guardó con 32 bits de color, a cada pixel le corresponde un entero de 32 bits (4 bytes). El número de colores es el mismo, simplemente se guarda un byte adicional que es siempre cero. En los cuatro bytes de ese entero (que corresponde a un pixel) vas a tener

00 RR GG BB

(aquí sí estoy seguro del orden), es decir, el primer byte es siempre 0, el segundo corresponde al rojo, el tercero al verde y el último al azul. Puedes tratarlos como una matriz de enteros, o puedes obtener tres matrices de bytes, una por color.

Sobre el formato JPG, este lleva algo de compresión, es cuestión de buscar la estructura del archivo y cómo se hace la compresión y descompresión. Una vez restaurada la imagen puedes obtener una o varias matrices de pixels, como las citadas arriba.

Sobre el tema de decidir si la foto se tomó de día o de noche, piensa que si fué de noche lo más probable es que las líneas de pixeles de la parte superior estarán muy oscuras (valores muy bajos de las tres componentes de color), mientras que si fué de día tendrás valores altos de azul y verde (no necesariamente de rojo), y si estaba nublado tendrás valores similares de los tres colores (los grises se forman con las tres componentes de color iguales).

Convendría que te hicieras con un editor hexadecimal y que abrieras con él el archivo de imagen, así podrás ver "de primera mano" la cabecera del archivo y los datos, esto te ayudará.

Un último detalle si utilizas el editor hexadecimal o tu programa va a leer el archivo byte por byte: Los procesadores INTEL guardan los números (sean del tipo que sean) comenzando por el byte menos significativo (se denomina formato little-endian), por ejemplo, el entero que me guarda la información del pixel, que sería 00 RR GG BB, estará almacenado como BB GG RR 00 (lo puedes ver con el editor hexadecimal ).

Saludos,

Etiquetas: importante, programa
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:49.