OJODIGITAL

 
Debates sobre la programación Para tratar temas sobre programación

Respuesta
  #1 (permalink)  
Antiguo 24-may-2008, 13:02
Avatar de _GUI_
Gurú Ojodigitalero
 
Fecha de Ingreso: marzo-2006
Ubicación: Madrid (a ratos Alicante)
Mensajes: 6.330
Enviar un mensaje por MSN a _GUI_
Sobre el Histograma

Bueno esta parte aunque sea la base en pseudo código me tocaba a mí. Hay que discutir varias cosas:


SOBRE QUÉ BUFFER SE CALCULA EL HISTOGRAMA

Quedamos que se hace sobre el bffer de salida final, pero hay dos casuísticas:
  • Histograma en gamma compensada (tipo Photoshop): se calcula sobre el buffer de salida final, incluida la aplicación de la gamma compensada. Este histograma será 100% congruente con el chivato de altas luces quemadas así que tiene que mamar del mismo sitio.
  • Histograma logarítmico: para plotear el histograma logarítmico (por pasos de diafragma) lo idóneo es partir del buffer justo antes de la gamma; la podría deshacer yo pero es tontería si se puede acceder a la imagen antes de gamma. Hay 2 posibilidades: o permitirmos que este histograma solo esté disponible cuando se tiene ajustada una salida lineal (gamma=1.0), o tiene que chupar de un buffer pre-gamma. Cómo de complicado es esto último?
Hay otra duda que me surge, ahora estais trabajando con imágenes de muestra, pero en el caso real cuando hablemos de sacar por pantalla la imagen, y la gamma no se ha ajustado (es decir, sea lineal), cómo lo vamos a hacer? se aplica una gamma sRGB con una LUT para el display? sale la imagen oscura? (no lo veo como opción).
Lo que tengo claro es que si se elige gamma=1.0 el histograma en gamma compensada ha de reflejar dicha linealidad, es decir será un histograma pegadito a la izquierda.

Y otra cosa: queremos un histograma que pueda representar solo el área sobre la que se está haciendo zoom? yo tengo claro que tiene que ser posible tenerlo sobre la imagen completa independientemente del grado de zoom, pero no veo mucho problema en un modo adicional que solo muestre el histograma de lo que aparezca en pantalla (como cuando en PS seleccionas un área y el histograma corresponde solo a ella).



DÓNDE SE DIBUJA Y CON QUÉ FORMATO

Se dibuja:
  • En una ventana aparte que haga popup al activarlo
  • En una parte del GUI dedicada
  • Sobre la misma imagen (en modo transparente o pantalla partida por ejemplo)
Y las opciones de cada una:
  • La tercera opción es super galáctica (casi tanto como que aparezca la foto de la cámara como propuso Manuel en una de sus maquetas ), plantea el problema de que dependemos del tamaño del display que es variable.
  • La segunda inutlizaría una parte importante del display cuando no se use.
  • La primera no le gusta a Manuel, pero es la que solucionaría los problema de formato.

En cuanto al formato, os digo que es MUY MUY recomendable, tener la garantía del que el eje X del histograma tiene una potencia de 2 de píxels (256, 512, incluso 768). Es la forma de que no aparezcan picos que puedan malinterpretarse debido al redondeo del ajuste al display.



FUNCIONALIDADES

Que tenga histograma gamma y logarítmico por pasos de diafragma lo tengo claro (va a ser el único revelador que lo tenga! y esto aparte de ser un concepto 100% fotográfico va a permitir medir el rango dinámico de las escenas). A este efecto, qué os parece un modo de display de la imagen en gamas de gris por pasos de diafragma (zonas de Ansel Adams)?



Por supuesto funcionalidad de representar las 7 combinaciones de canales: R, G, B, RG, RB, GB, RGB mediante 3 checkboxes R,G,B. Marcar niveles vacíos. Dibujar o no ejes y etiquetas,... esas chorradillas.

Lo que no tengo claro si vale la pena es la parte de poder hacer zoom y movernos a cualquier parte del histograma. Esto os digo que es con diferencia lo que da más lata, y no se si teniendo un histograma de 512 píxels (ningún revelador lo tiene tan potente) vale la pena. Para analizar a fondo histogramas ya está Histogrammar.




IMPLEMENTACIÓN

Necesito que me digáis el nombre de la variable (buffer) que contendrá los niveles de la imagen a mostrar en el histograma y la forma de acceder a ellos (image[c][x+width*y], algo así), así como el buffer donde hay que pintar el histograma. Si lo hacemos fijo será un bufffer de 512x256px por ejemplo.

Y los nombres de los parámetros requeridos para el histograma y que deberán provenir del GUI (del GUI general o del Gui del propio histograma si va en una ventana aparte):
  • Modo (gamma/log)
  • Canales a representar R,G,B
  • ...
__________________
"En ocasiones veo halos."

Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS
http://www.guillermoluijk.com para suscribirte pulsa aquí

Última edición por _GUI_; 24-may-2008 a las 13:43.
Responder Citando
Publicidad
  #2 (permalink)  
Antiguo 24-may-2008, 13:52
Avatar de ManuelLlorens
Habitual
 
Fecha de Ingreso: abril-2008
Ubicación: Madrid
Mensajes: 506
Enviar un mensaje por MSN a ManuelLlorens
¿Llovía demasiado para irte a Alicante?

Cita:
Iniciado por _GUI_ Ver Mensaje
  • Histograma en gamma compensada (tipo Photoshop): se calcula sobre el buffer de salida final, incluida la aplicación de la gamma compensada. Este histograma será 100% congruente con el chivato de altas luces quemadas así que tiene que mamar del mismo sitio.
Mi idea era calcular cuatro histogramas: gamma compensada y sin compensar para la vista y para la imagen completa, todos de 16 bits. Los completos sólo se calcularían al abrir el "visor de histogramas" en ventana aparte. Los de la vista se recalculan junto con la vista y sólo se mostrarían superpuestos a esta. Pero era sólo una idea.

Cita:
Iniciado por _GUI_ Ver Mensaje
  • Histograma logarítmico: para plotear el histograma logarítmico (por pasos de diafragma) lo idóneo es partir del buffer justo antes de la gamma; la podría deshacer yo pero es tontería si se puede acceder a la imagen antes de gamma. Hay 2 posibilidades: o permitirmos que este histograma solo esté disponible cuando se tiene ajustada una salida lineal (gamma=1.0), o tiene que chupar de un buffer pre-gamma. Cómo de complicado es esto último?
Nada. La idea es que la gamma se aplique sobre la vista (es decir sobre la porción de la imagen que se visualiza) y no sobre la imagen completa. Así que tienes disponibles los dos buffers permanentemente. Ahora (al no estar mezcladas las dos maquetas), se calcula en toda la imagen una vez obtenida la salida de dcraw. Estos cálculos se hacen con una LUT muy rápida a 16 bits, justo antes de la conversión a 8 bits (en realidad en el mismo paso), viene a ser así: out=(PX8)(LUTsRGB[in]>>8);

Cita:
Iniciado por _GUI_ Ver Mensaje
Hay otra duda que me surge, ahora estais trabajando con imágenes de muestra, pero en el caso real cuando hablemos de sacar por pantalla la imagen, y la gamma no se ha ajustado (es decir, sea lineal), cómo lo vamos a hacer? se aplica una gamma sRGB con una LUT para el display? sale la imagen oscura? (no lo veo como opción).
Lo que tengo claro es que si se elige gamma=1.0 el histograma en gamma compensada ha de reflejar dicha linealidad, es decir será un histograma pegadito a la izquierda.
Como te pongo arriba. En principio, la idea era que el usuario no pudiera elegir la gamma de salida hasta el momento de dar a grabar y que mientras tanto sólo se visualizara en sRGB (en esta primera versión, hasta que podamos meter gestión de color)... podemos cambiarlo, pero será un lío que el histograma sí corresponda a la gamma de salida y sin embargo en la pantalla se muestre con sRGB, ¿no crees? Mi idea era que en esta primera versión en la vista de histograma se pudiera elegir entre mostrarlo con la gamma sRGB (tal cual se ve en la vista) y gamma 1.0. Eso lo tenemos chupao porque ambos buffers están disponibles y es rápido de calcular.

Cita:
Iniciado por _GUI_ Ver Mensaje
Y otra cosa: queremos un histograma que pueda representar solo el área sobre la que se está haciendo zoom? yo tengo claro que tiene que ser posible tenerlo sobre la imagen completa independientemente del grado de zoom, pero no veo mucho problema en un modo adicional que solo muestre en el histograma lo que aparezca en pantalla (como cuando en PS seleccionas un área y el histograma corresponde solo a ella).
Mi idea era, como ya pongo arriba, que ese fuera el modo de ver el histograma cuando se solapa con la imagen. El único tema a resolver es la escala, pero podría tener 512 píxels, 256, 128, etc. No pretende ser un histograma exacto, solo informativo. Si quieres más precisión abres el histograma de ventana aparte y tienes la funcionalidad de histogrammar completa.

Cita:
Iniciado por _GUI_ Ver Mensaje
DÓNDE SE DIBUJA Y CON QUÉ FORMATO
Y las opciones de cada una:
  • La tercera opción es super galáctica (casi tanto como que aparezca la foto de la cámara como propuso Manuel en una de sus maquetas ), plantea el problema de que dependemos del tamaño del display que es variable.
Bueno, es de esos detalles que entra por los ojos, y no me parece difícil de implementar. Lo de la foto está chupao. Solo hay que bajarse una imagen de cada cámara que soporte dcraw y reescalarla... más o menos. Pensaba tirar a lo bruto de dpreview. Es una pijada, pero ¿a que mola?

Cita:
Iniciado por _GUI_ Ver Mensaje
  • La segunda inutlizaría una parte importante del display cuando no se use.
Yo descartaría esta directamente. No le veo ninguna ventaja.

Cita:
Iniciado por _GUI_ Ver Mensaje
  • La tercera no le gusta a Manuel, pero es la que solucionaría los problema de formato.
No es que no me guste, es que iba en la filosofía de la aplicación usar una sola pantalla... pero hace tiempo que acepté que el histograma iría de ese modo, me parece bien abrir el histograma en plan histogrammar en ventana aparte, siempre que también se pueda ver solapado un histograma menos exacto. Así tienes lo mejor de las dos opciones.

Cita:
Iniciado por _GUI_ Ver Mensaje
En cuanto al formato, os digo que es MUY MUY recomendable, tener la garantía del que el eje X del histograma tiene una potencia de 2 de píxels (2256, 512, incluso 768). Es la forma de que no aparezcan picos que puedan malinterpretarse debido al redondeo del ajuste al display.
En la ventana aparte totalmente de acuerdo, en el histograma solapado habrá que usar 512, 256, 128... hmm... es que 512*2=1024 y aún hay monitores que trabajan a esa resolución, quitando márgenes... no cabrá si forzamos 512. ¿Crees que sería aceptable poner un histograma solapado a 256 teniendo en cuenta que es aproximado y que hay otra opción de verlo más grande? Si es así ponemos de tamaño mínimo de ventana 800 (está así ahora) y lo dejamos siempre a 256.

Cita:
Iniciado por _GUI_ Ver Mensaje
FUNCIONALIDADES
Que tenga histograma gamma y logarítmico por pasos de diafragma lo tengo claro (va a ser el único revelador que lo tenga! y esto aparte de ser un concepto 100% fotográfico va a permitir medir el rango dinámico de las escenas). A este efecto, qué os parece un modo de display de la imagen en gamas de gris por pasos de diafragma (zonas de Ansel Adams)?
Perfecto. Habría que meterla en la DLL, es muy fácil. Me parece que encaja en la línea de perfectRAW como un guante, de hecho una vez funcione perfectRAW habrá que fusionar todos tus artículos y manuales para que perfectRAW sea un revelador perfecto y didáctico al mismo tiempo.

Cita:
Iniciado por _GUI_ Ver Mensaje
Lo que no tengo claro si vale la pena es la parte de poder hacer zoom y movernos a cualquier parte del histograma. Esto os digo que es con diferencia lo que da más lata, y no se si teniendo un histograma de 512 píxels (ningún revelador lo tiene tan potente) vale la pena. Para analizar a fondo histogramas ya está Histogrammar.
En la ventana aparte yo sí lo pondría, a mí me gustaría tener toda la funcionalidad de histogrammar dentro de perfectRAW... o eso o pones el Command$ en histogrammar que te pedí hace... ¿tres semanas? y lo llamamos desde perfectRAW (así salimos del paso en la versión 1.0). Pero mi opción para más adelante es rehacer histogrammar en C# dentro de una clase y así poder compilarlo dentro de perfectRAW y como un producto a parte: perfectHistogram/perfectH/perfectHist/perfectHistogrammar... tú decides.

Cita:
Iniciado por _GUI_ Ver Mensaje
IMPLEMENTACIÓN
Creo que no me costaría nada implementarlo en mi DLL. Sólo hay que decidir si lo implemento yo o lo hace ariznaf para que no nos pisemos, como hacemos habitualmente. Yo creo que lo lógico sería que yo implementara el cálculo y él el dibujo solapado.

RESUMO MI POSTURA PARA QUE QUEDE MÁS CLARO:
  • Para la versión 1.0: sólo histograma solapado de baja precisión pudiendo elegir gamma sRGB/lineal, con 256/512 bytes de ancho y volcado a disco TIFF 16 bits y llamada a histogrammar para verlo ampliado. Yo implementaría el cálculo y ariznaf la visualización solapada.
  • En paralelo: rehacer histogrammar en C#/C con dos formularios y código totalmente independiente: uno para abrirlo dentro de perfectRAW desde donde recibiría el buffer (y desde perfectBLEND, etc. en el futuro) y otro formulario para funcionar como aplicación (y producto) independiente. De ese modo se saca mucho más rendimiento del esfuerzo.
Un saludo:
__________________
Manuel Llorens
Olympus E-510, E-300
Mis fotos

Última edición por ManuelLlorens; 25-may-2008 a las 02:17.
Responder Citando
  #3 (permalink)  
Antiguo 24-May-2008, 17:44
Avatar de ÁlexG
Habitual
 
Fecha de Ingreso: May-2006
Ubicación: Levante
Mensajes: 252
Cita:
Iniciado por _GUI_ Ver Mensaje
DÓNDE SE DIBUJA Y CON QUÉ FORMATO
Se dibuja:
En una ventana aparte que haga popup al activarlo
En una parte del GUI dedicada
Sobre la misma imagen (en modo transparente o pantalla partida por ejemplo)
En mi humilde opinión, veo interesante la ventana pop up teniendo en cuenta que muchos fotógrafos usamos dos pantallas y sería genial poder poner el histograma en la ventana secundaria.

Estoy maravillado con los avances que lleváis hechos.

Álex.
Responder Citando
  #4 (permalink)  
Antiguo 26-May-2008, 14:19
Habitual
 
Fecha de Ingreso: March-2008
Ubicación: Oviedo
Mensajes: 728
Según la maqueta que se había propuesto, el usuario puede mantener entre 1 y cuatro zonas para la representación de la imagen.

Mi idea era que en ellas se dibujara la imagen y se fuera superponiendo otro tipo de información (pixels quemados, histograma, patch de la zona seleccionada para el ajuste de blancos, información sobre el grado de zoom y cosas por el estilo, etc.
Esto se superpondría con un cierto grado de transparencia y se debería de poder activar sobre cualquiera de las cuatro zonas (vistas) visualizadas en un momento dado.

Se debería de poder también dejar que se quite la imagen ya así quedaría únicamente el histograma, por ejemplo.

Tampoco habría mayor problema en permitir que se puediera dibujar el histograma (además de en la forma anterior) en una ventana popup.

El cálculo del histograma sobre la imagen completa, creo que debería de hacerse en 16 bits (con 65536 clases, de 0 a 65535) y dos histogramas: el histograma sobre la imagen lineal (sin gamma aplicada) y el de la imagen corregida en gamma PARA LA GAMMA Y ESPSCIO DE COLOR SELECCIONADOS no para la gamma de pantalla, ya que el que se aprecie o no en la pantalla de nuestro monitor no creo que sea importante, lo importante es si el espacio de salida los representa como un mismo color o no.

En la representación la cosa puede ser más delicada.

Estamos acostumbrados a histogramas de 8 bits, con colores agrupados en 256 clases. Un histograma de 65536 clases tendrá un aspecto diferente mucho más "ruidoso" con picos que suben y bajan. Al agrupar en menos clases el histograma se suaviza.

El problema también está en que si intentamos utilizar los 16 bits completos (65536 clases) no tendremos pixels suficientes para representar cada uno de los valores en pantalla (en el eje horizontal) y por tanto necesariamente va a haber que agruparlos.
Pero entonces el aspecto del histograma cambiará según la pantalla de visualización sea más o menos ancha (pues aumentaremos el número de clases a medida que la ventana se hace más grande).

¿Vamos a utilizar 256 clases o agrupaciones, o un mayor número de ellas?

En cualquier caso, creo que el histograma almacenado debe de hacerse siempre sobre el total de valores posibles (65536) pues agrupar luego en un número menor de clases es sencillo (basta con sumar todos los valores asociados a las clases a agrupar).
Mantendremos así en todo momento el máximo de información disponible.

Para dibujar en GDI+ no hay ningún problema en que la ventana sea de tamaño variable, es sólo cuestión de preparar el dispositivo de manera adecuada y la matriz de transformación de coordenadas, de manera que nosotros dibujamos en el eje x siempre entre 0 y 255 por ejemplo, y GDI se ocupa de escalarlo a la ventana de salida.

Lo que sí que puede ocurrir es (como dice GUI) que aparezcan picos extraños cuandos se usa un número de pixels que no sea múltiplo del número de clases representadas. Pero para ello es suficiente con usar una porción de la ventana disponible que sí que sea múltiplo (la parte izquierda, la derecha o centrado en la ventana de salida, a vuestra opción).
Responder Citando
  #5 (permalink)  
Antiguo 26-May-2008, 15:05
Avatar de _GUI_
Gurú Ojodigitalero
 
Fecha de Ingreso: March-2006
Ubicación: Madrid (a ratos Alicante)
Mensajes: 6.330
Enviar un mensaje por MSN a _GUI_
Cita:
Iniciado por ariznaf Ver Mensaje
Pero entonces el aspecto del histograma cambiará según la pantalla de visualización sea más o menos ancha (pues aumentaremos el número de clases a medida que la ventana se hace más grande).
No te preocupes de estas cosas que lo tengo ya trillado; por eso insistía todo el rato en que el histograma ha de tener un eje X en potencias de 2, ésa es la clave para no tener problemas. Siendo potencias de 2, todo histograma que se dibuje, en el grado de zoom que sea, siempre tendrá en cada nivel del eje X el mismo número de niveles reales de la imagen de 16 bits representados, y por eso nunca se van a producir picos (esto es importante en grados de zoom grandes, o sea, cuando nos zambullimos en el histograma para verlo de más cerca, algo que nunca hacen los reveladores comerciales ni PS).

Lo que es IMPRESCINDIBLE (y esto choca con lo que comentó Manuel) es que el histograma, así como el chivato de zonas quemadas, se base en la imagen convertida al perfil de color de salida elegido, y aplicada la gamma final (no la de pantalla). Esto mismo es lo que hace ACR y es una de sus ventajas sobre LR.

Por lo menos lo de la conversión al espacio de color es la única manera de hacer una gestión de color correcta: una de las mayores críticas a LightRoom, es que en cuanto a gestión de color es tan sumamente cutre, que el histograma que te muestra es el del espacio de color intermedio, que es una versión de ProPhoto (muy amplio), con lo que puedes ver el histograma perfecto y cuando lo exportas a PS te llevas la sorpresa de que en sRGB has recortado niveles.
La gestión de color empieza en el propio revelado: elegir un perfil de color que sea capaz de representar toda la gama de la imagen, así como un grado de exposición que no recorte niveles son críticos para acondicionar la imagen correctamente. Luego acaberemos eligiendo Adobe RGB para casi todo y arreando, pero qué menos que las simplificaciones sean decisión del usuario, no del revelador.

Para el histograma logarítmico se ha de acudir al paso anterior a la aplicación de la gamma, y no sé (dependiendo de la facilidad de acceder al buffer correspondiente) si sería mejor incluso acudir al buffer anterior a la conversión al espacio de color final; aunque este tema del histograma log ya es secundario.

Esta noche leo más en detalle todo lo que hemos comentado sobre los modos de visualización del histograma.
__________________
"En ocasiones veo halos."

Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS
http://www.guillermoluijk.com para suscribirte pulsa aquí

Última edición por _GUI_; 26-May-2008 a las 15:08.
Responder Citando
  #6 (permalink)  
Antiguo 26-May-2008, 15:29
Avatar de ManuelLlorens
Habitual
 
Fecha de Ingreso: April-2008
Ubicación: Madrid
Mensajes: 506
Enviar un mensaje por MSN a ManuelLlorens
Cita:
Iniciado por _GUI_ Ver Mensaje
Lo que es IMPRESCINDIBLE (y esto choca con lo que comentó Manuel) es que el histograma, así como el chivato de zonas quemadas, se base en la imagen convertida al perfil de color de salida elegido, y aplicada la gamma final (no la de pantalla). Esto mismo es lo que hace ACR y es una de sus ventajas sobre LR.
Técnicamente no tenemos ningún problema para calcular un histograma u otro, aunque sobrecargará un poco la aplicación si tenemos que mantener dos buffers completos distintos para cada imagen, por lo que propongo abajo mi solución técnica.

Lo que yo decía era que va a quedar raro que lo que se ve por pantalla no coincida con el histograma. Por ejemplo, el chivato de luces altas indicará algo diferente al histograma y eso no es muy coherente, porque, de momento en la primera versión, la salida por pantalla siempre va a ser sRGB. Otra opción es calcular las altas luces sobre el mismo espacio de color que la salida. Opciones que tenemos: asumir que el histograma depende de la elección del usuario y que lo que se ve en pantalla es distinto (me parece raro) y dos, meter la gestión de color completa en la primera versión. Entre estas opciones yo me quedaba con la intermedia que me parecía que era poner un histograma logarítmico y otro con gamma sRGB.

Técnicamente tendremos que obtener la imagen sin espacio de color ni gamma y convertirla dos veces, una con el espacio de color de salida y otra con el espacio de color sRGB. Eso o nos planteamos meter gestión de colr desde la primera versión ¿Tan difícil puede ser meter la gestión de color en esta primera versión? Mirando el código de Coffin parece fácil convertir de un espacio a otro y tenemos la librería LCMS.

Cita:
Iniciado por _GUI_ Ver Mensaje
Por lo menos lo de la conversión al espacio de color es la única manera de hacer una gestión de color correcta: una de las mayores críticas a LightRoom, es que en cuanto a gestión de color es tan sumamente cutre, que el histograma que te muestra es el del espacio de color intermedio, que es una versión de ProPhoto (muy amplio), con lo que puedes ver el histograma perfecto y cuando lo exportas a PS te llevas la sorpresa de que en sRGB has recortado niveles.
Vamos a ver si me aclaro lo que necesitamos para ir implementándolo:
  1. Salida pura 16 bits: sin espacio de color ni gamma, para el histograma logarítmico.
  2. Salida pura 16 bits+espacio de color de salida+gamma de salida, para el histograma completo.
  3. Salida pura 16 bits+espacio de color sRGB+gamma sRGB+conversión a 8 bits, para la presentación en pantalla. Habrá que decidir si el histograma superpuesto sale de aquí o del anterior y lo mismo del chivato.
Eso en la versión 1.0. En la versión en la que metamos gestión de color quitaríamos la salida 3 y sacaríamos por pantalla directamente la 2. Para ahorrar memoria deberíamos tener solo la salida 1 y calcular la 2 a la vez que el histograma, sin almacenarlo y la 3 para el trozo que se ve en la vista sin calcularlo para toda la imagen. Eso sería un poco lento pero ahorra memoria. En la siguiente versión podemos pensar si sacrificamos memoria y tenemos la salida 2 calculada en un buffer.

Tenemos que coger el buffer de salida puro de dcraw (en eso no hay problema) y crear una función nuestra en C (copiando código de Coffin supongo que será muy fáci) que convierta al espacio de color y aplique la gamma con LUT para un solo píxel de 16 bits. Luego se le llama desde la función que calcula el histograma o desde la que pinta en pantalla, manteniendo dos LUTs en memoria a la vez. Supongo que será posible meter en una misma LUT la conversión al espacio de color y la gamma. Si es así irá muy rápido. Esta tarde miro el código de Coffin.

Un saludo:
__________________
Manuel Llorens
Olympus E-510, E-300
Mis fotos
Responder Citando
  #7 (permalink)  
Antiguo 26-May-2008, 15:33
Habitual
 
Fecha de Ingreso: March-2008
Ubicación: Oviedo
Mensajes: 728
Cita:
...por eso insistía todo el rato en que el histograma ha de tener un eje X en potencias de 2...
O sea, que el número de clases en que se divida deberían de ser 256,512,1024,2048....
Evidentemente, nunca podrá ser mayor que el número de pixels en la ventana de representación (pues si lo hacemos de 512 y lo representamos en 256 habría información solapada).

Pero si la ventana es de 800 pixels por ejemplo, no hay mucho problema en utilizar 512 clases pero dibujarlas en los 800 pixels completos (rectangulitos verticales por cada clase). Lo único es que habrá clases que se dibujen con barras de dos pixels de ancho y otras con uno (no serán todas de exactamente el mismo ancho, unas tendrían un pixel más que otras).
Esto no da lugar a la aparición de picos, y tendría mejor aspecto al dibujarlo de extremo a extremo del área disponible, en vez de ocupar una zona solo de la ventana. Del escalado "en horizontal" se ocupa el GDI.

El algoritmo para dibujarlo podría ser algo así:
  • Obtener ancho de la ventana (en pixels).
  • Calcular la potencia de dos que es inmediatamente inferior al número de pixels.
  • Reagrupar las clases del histograma guardado (de 0 a 65535) en el número de clases seleccionado (esto es rápido, pues se trabaja sobre el histograma, no sobre la imagen. Sólo hay que sumar los valores del histograma de 16 bits que están en la misma clase que el de salida).
  • Preparar la transformación de escala de la ventana de salida para que el eje x vaya de 0 al número de clases.
  • Dibujar una franja vertical por cada clase utilizando GDI para escalar la franja.
El algoritmo así planteado es sencillo de modificar para poder hacer zooms en el histograma entre dos valores dados v0 y v1 del histograma de 16 bits.
Sólo hay que agrupar en este caso las clases entre dichos valores v0 y v1.
Del escalado a la hora de dibujar se ocupa GDI.

Cita:
Lo que es IMPRESCINDIBLE (y esto choca con lo que comentó Manuel) es que el histograma, así como el chivato de zonas quemadas, se base en la imagen convertida al perfil de color de salida elegido, y aplicada la gamma final (no la de pantalla). Esto mismo es lo que hace ACR y es una de sus ventajas sobre LR.
Completamente de acuerdo. De nada sirve el histograma o los pixels quemados de la salida a pantalla, sino de lo que el usuario va a querer guardar en su fichero de salida: es decir gamma y espacio de color de salida, no del sRGB de pantalla.

Creía que en un principio se había dicho que sobre el de salida por pantalla (con gamma 2.2) y no me parecía correcto.

Otra cosa es que Manuel estará preocupado por las dificultades de implementación de esto y el aumento de tiempo de revelado.

Evidentemente hay que hacer la compensación gamma final (y ajuste de espacio de color) para poder calcular los histogramas correctos.
Eso no hay quién lo evite. Lo único que se puede poner un flag de que lo calcule o no en las funciones de la DLL. Sólo activaríamos el cálculo de histograma cuando hay algún histograma viéndose en pantalla.
Si luego el usuario lo activa, habrá que llamar a la función de cálculo a partir del buffer correspondiente.

Ese punto es un punto de bifurcación del algoritmo... por un lado se parte de la salida lineal para hacer la preparación para mostrar en pantalla y por otro las correcciones para el archivo final.
Habíamos quedado en que las correcciones finales no se harían hasta el revelado final.
El histograma impone tener que hacer esos cálculos (al menos parte de ellos) en todo momento.
En cualquier caso, yo el resultado no lo almacenaría en un buffer intermedio.
El histograma se puede calcular haciendo las correcciones gamma y de espacio de color pixel a pixel pero sin almacenar el resultado en un buffer de salida, únicamente aumentando el contador de la clase correspondiente al resultado de la conversión para dicho pixel.

Con ello nos ahorramos un buffer más de memoria y nos aseguramos de que el revelado final se pueda hacer partiendo desde cero y con la máxima precisión, sin concesiones que se hayan podido hacer para acelerar los cálculos intermedios para presentación en pantalla.
Responder Citando
  #8 (permalink)  
Antiguo 26-May-2008, 15:49
Habitual
 
Fecha de Ingreso: March-2008
Ubicación: Oviedo
Mensajes: 728
Cita:
Lo que yo decía era que va a quedar raro que lo que se ve por pantalla no coincida con el histograma. Por ejemplo, el chivato de luces altas indicará algo diferente al histograma y eso no es muy coherente, porque, de momento en la primera versión, la salida por pantalla siempre va a ser sRGB. Otra opción es calcular las altas luces sobre el mismo espacio de color que la salida. Opciones que tenemos: asumir que el histograma depende de la elección del usuario y que lo que se ve en pantalla es distinto (me parece raro) y dos, meter la gestión de color completa en la primera versión. Entre estas opciones yo me quedaba con la intermedia que me parecía que era poner un histograma logarítmico y otro con gamma sRGB.
Hombre a mi me parece lo suyo. Precisamente si el histograma sirve para algo es para mostrar información que no se aprecia fácilmente en pantalla o que por las limitaciones del dispositivo en que se muestra, queda oculta.

Que el ojo no pueda apreciar una diferencia entre dos tonos dados (por sus propias limitaciones o más habitualmente por las limitaciones del dispositivo de salida) no implica que esos dos tonos sean iguales en el fichero que manejamos. Si son iguales no hay forma de separarlos. Si son distintos, podremos procesarlo para acentuar esa diferencia (aumentando contraste, briloo, lo que sea) y que el ojo lo aprecie.
Un histograma bien calculado nos ayudará a distinguir entre esas dos situaciones y no nos engañará haciéndonos pensar que no hay información donde en realidad sí que la hay.

En cuanto a lo de las altas luces: habíamos quedado en que la gamma no afecta a los pixels quemados. Al poner un umbral esto no es exactamente así, pues el valor que se conserva con la gamma es únicamente el correspondiente al más elevado.
Esto lo podemos obviar recalculando el umbral corrigiéndolo en la diferencia entre los valores con la gamma de salida y la de pantalla (con salida 2.2).
Quizás el umbral debería de estar definido sobre la imagen lineal y no sobre el valor compensado en gamma. De hecho el umbral a escoger debería de ser cercano al punto de saturación de la cámara.
Para obtener el valor del chivato o umbral a utilizar en FastDraw una vez convertida la imagen a gamma de pantalla, es suficiente con calcular la compensación gamma para el umbral lineal: umbral= gammaPantalla(umbralLineal).

Si el umbral se quiere establecer sobre los valores en el fichero de salida, calcularíamos el umbralLineal deshaciendo la compensación gamma de salida.

Así evitamos tener que hacer las compensaciones de salida cuando no hay ningún histograma en pantalla.
Cita:
Eso en la versión 1.0. En la versión en la que metamos gestión de color quitaríamos la salida 3 y sacaríamos por pantalla directamente la 2. Para ahorrar memoria deberíamos tener solo la salida 1 y calcular la 2 a la vez que el histograma, sin almacenarlo y la 3 para el trozo que se ve en la vista sin calcularlo para toda la imagen. Eso sería un poco lento pero ahorra memoria. En la siguiente versión podemos pensar si sacrificamos memoria y tenemos la salida 2 calculada en un buffer.

Tenemos que coger el buffer de salida puro de dcraw (en eso no hay problema) y crear una función nuestra en C (copiando código de Coffin supongo que será muy fáci) que convierta al espacio de color y aplique la gamma con LUT para un solo píxel de 16 bits. Luego se le llama desde la función que calcula el histograma o desde la que pinta en pantalla, manteniendo dos LUTs en memoria a la vez. Supongo que será posible meter en una misma LUT la conversión al espacio de color y la gamma. Si es así irá muy rápido. Esta tarde miro el código de Coffin.
Vaya, aquí hemos coincidido en la respuesta (aunque lo tuyo está mucho mejor explicado que lo mío ).

Claro que eso es fácil de decir por mi parte, por que como lo tiene que hacer tú .
De ello lo que puede ser más complicado es convertir el pixel individual al espacio de color de salida, pues hay que sacarlo del código de Coffin. Lo otro lo tienes controlado

Última edición por ariznaf; 26-May-2008 a las 15:56.
Responder Citando
  #9 (permalink)  
Antiguo 26-May-2008, 15:59
Avatar de ManuelLlorens
Habitual
 
Fecha de Ingreso: April-2008
Ubicación: Madrid
Mensajes: 506
Enviar un mensaje por MSN a ManuelLlorens
Me voy a 2º ESO a dar una clase precisamente sobre Estadística que, cómo no, habla de histogramas. Luego os contesto.
__________________
Manuel Llorens
Olympus E-510, E-300
Mis fotos
Responder Citando
  #10 (permalink)  
Antiguo 26-May-2008, 16:00
Habitual
 
Fecha de Ingreso: March-2008
Ubicación: Oviedo
Mensajes: 728
Pues háblales de la fotografía y así verán que lo de los histogramas sive para algo.
Responder Citando
  #11 (permalink)  
Antiguo 26-May-2008, 17:13
Avatar de ManuelLlorens
Habitual
 
Fecha de Ingreso: April-2008
Ubicación: Madrid
Mensajes: 506
Enviar un mensaje por MSN a ManuelLlorens
Cita:
Iniciado por ariznaf Ver Mensaje
Pues háblales de la fotografía y así verán que lo de los histogramas sive para algo.
Una vez a la semana les suelo hablar de "temas transversales", es decir, de aplicaciones de las matemáticas... y no sólo les he hablado de fotografía, saben lo que es una matriz de Bayer, el modo raw, un revelador...

Un saludo:
__________________
Manuel Llorens
Olympus E-510, E-300
Mis fotos

Última edición por ManuelLlorens; 26-May-2008 a las 17:36.
Responder Citando
  #12 (permalink)  
Antiguo 26-May-2008, 17:35
Avatar de ManuelLlorens
Habitual
 
Fecha de Ingreso: April-2008
Ubicación: Madrid
Mensajes: 506
Enviar un mensaje por MSN a ManuelLlorens
Recapitulación

A ver si tenemos algo definitivo y podemos ponernos con ello. Más que nada porque yo tengo aún bastante trabajo por delante, pero ariznaf cuando termine lo de ahora (que entiendo que le va quedando poco) tendrá que ponerse con lo siguiente.
  1. dcraw.dll devolverá un buffer de 16 bits sin espacio de color ni gamma a perfectRAW. Cambios que hay que hacer: ninguno, simplemente cambiar en el revelador que no pida espacio de salida sRGB, sino color raw.
  2. Voy a renombar image.dll a colormng.dll, para encapsular toda la (escasa de momento) gestión de color de la aplicación. En el futuro esta DLL llamará a LCMS.dll por nosotros. Dicho ésto, colormng.dll tomará ese buffer que sale de dcraw.dll y calculará un histograma completo al que se le podrán pasar tres parámetros (espacio de color, gamma, lineal/logarítmico). Eso lo hará una sola vez cuando se le pida y el resultado se pintará directamente en un Bitmap con el que luego podréis hacer lo que queráis. Cogiendo código de Coffin para el espacio de color (que como dice ariznaf es lo único que no he mirado) + la LUT gamma lo metemos en una LUT para sacar el histograma directamente tal y como especifique _GUI_. Yo le paso ese nuevo Bitmap a ariznaf y él se encarga de pintarlo, bien superpuesto, bien en una ventana aparte (recomiendo encapsularlo en una clase Histograma para en el futuro poder usarla desde otros proyectos). Cambios que hay que hacer en colormng.dll: que calcule, además de la LUT sRGB que calcula ahora, la LUT de la gamma de salida (5 minutos). Que convierta al espacio de color un píxel y exponga ambas funciones fuera. Añadir la función que calcula los histogramas, que entiendo que está chupado.
  3. perfectImageDLL lee la imagen lineal que ha salido de dcraw.dl y tirará de colormng.dll para aplicar el espacio de color y gamma a un sólo píxel de 16 bits del trozo de la imagen que se muestra en la vista antes de convertirlo a 8 bits (aunque lo ideal de nuevo es que lo haga en un solo paso), pidiendo espacio de color sRGB y gamma sRGB para la versión 1.0 (más adelante ya veremos). Si quisiéramos calcular el histograma del trozo de imagen mostrado en la vista (por cierto, ariznaf, creo que al final quedamos que dos vistas eran suficientes, en vez de 4, que aporta poco, consume memoria y hace más complicado el código, para la versión 1.0), lo haríamos en perfectImageDLL, no en colormng.dll, en la misma función que hace los demás cálculos y yo creo que no debería ser posible calcularlo logarítmico para evitar ralentizar el pintado en pantalla.
  4. Para ir más rápido colormng.dll mantendrá internamente dos LUTs diferentes (sRGB y gamma de salida). Además, (eso creo que no está aún bien definido), el código que llama a perfectImageDLL desde C# podrá solicitar a colormng.dll que invierta en gamma y espacio de color el rango del chivato para poder definirlo sobre la imagen corregida en gamma. Esa operación no debería ser complicada.
¿Qué os parece?

Un saludo:
__________________
Manuel Llorens
Olympus E-510, E-300
Mis fotos

Última edición por ManuelLlorens; 26-May-2008 a las 17:39.
Responder Citando
  #13 (permalink)  
Antiguo 26-may-2008, 17:42
Avatar de _GUI_
Gurú Ojodigitalero
 
Fecha de Ingreso: marzo-2006
Ubicación: Madrid (a ratos Alicante)
Mensajes: 6.330
Enviar un mensaje por MSN a _GUI_
no metáis demasiada info en este hilo que si esta noche me veo mucho texto me estreso y acabo por no leeros...
__________________
"En ocasiones veo halos."

Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS
http://www.guillermoluijk.com para suscribirte pulsa aquí
Responder Citando
  #14 (permalink)  
Antiguo 26-may-2008, 18:18
Habitual
 
Fecha de Ingreso: marzo-2008
Ubicación: Oviedo
Mensajes: 728
A ver en lineas generales me parece bien, Manuel, pero algunas matizaciones:
2.- En este punto dices que para el histograma generas un bitmap y que yo lo pinte. No me parece bien un bitmap. Tal y como lo veo, el histograma consiste simplemente un 4 vectores (uno por canal más luminosidad) con 65536 números el número de pixels en la imagen que tienen el valor correspondiente al índice del vector en el canal asociado a cada vector (RGB+L). Eso sería lo que hay que calcular. A la hora de pintarlo, se puede hacer en C# sin problemas sobre una ventana (utilizando transparencias si se quiere). Si el pintado es un poco lento, se puede pintar desde GDI en un bitmap del tamaño de la ventana y superponerla cada vez que haga falta.
La rutina de pintado se ha de ocupar de agrupar las clases en un número menor de clases (la potencia de 2 inmediatamente inferior al tamaño de la ventana). Esto es muy rápido y no es necesario volver a recorrer la imagen.
Ventaja: sólo contamos los pixels que contienen un color una vez, no cada vez que se quiera dibujar.
La otra opción es crear un bitmap de 256 pixels de ancho, pero es más pobre y menos flexible, y no se adapta al cambio de tamaño de la ventana.

3.- Para manejar las vistas pensaba utilizar un contenedor de controles de tipo tabla. Con él será fácil añadir columnas y filas y meter en cada celda un PerfectView de manera dinámica. No creo que el que sean 2 o 4 dificulte mucho esa parte de la programación. Entonces por lo que entiendo, la propia rutina de escalado hará la conversión al espacio de color y la gamma de salida para comprobar si está quemado (sólo si se ha seleccionado marcar los pixels quemados). Por las mismas puede también hacer la conversión a sRGB+Gamma y nos evitamos buffers intermedios. Si es manejar una LUT no habría mucho problema ¿no?
El algoritmo sería algo así:
  1. Para cada pixel en la imagen de salida
  2. Usar la LUT para convertir a Color de Salida y Gamma de salida (16 bits).
  3. Aumentar el contador del número de pixels del color correpondiente en el histograma parcial.
  4. Comprobar si el pixel está quemado.
  5. Usar la LUT para convertir a sRGB y gamma de monitor (16 bits)
  6. Convertir de 16 a 8 bits.
¿Es así? ¿Qué te parece el hacer la conversión a sRGB en directo en vez de precalcularla en un buffer? Si se hace con LUTs y dado que hay que hacer necesariamente la correspondiente al espacio y gamma de salida para los pixels quemados, no creo que se ralentize mucho.

En cuanto a lo que dices de calcular el histograma logarítmico... no creo que hubiera problema.
Lo primero a ver si entiendo bien qué es el histograma logarítmico. Entiendo que cuando habláis del histograma logarítmico os referís a calcular el histograma sobre la imagen en lineal, sin la corrección gamma ¿no? y el histograma normal hace referencia al histograma calculado con el conjunto de valores que salen después de la corrección.

¿Por qué crees que es más problemático? Se podría implementar entre los pasos 1 y 2 ¿no? Simplemente hacer lo mismo que en el paso 3.
Lo único que ese histograma no tengo claro si habría de ser sobre la imagen Raw o ya convertida al espacio de color... Si es sobre el Raw no hay problema ¿no?
Responder Citando
  #15 (permalink)  
Antiguo 26-may-2008, 19:15
Avatar de ManuelLlorens
Habitual
 
Fecha de Ingreso: abril-2008
Ubicación: Madrid
Mensajes: 506
Enviar un mensaje por MSN a ManuelLlorens
Cita:
Iniciado por ariznaf Ver Mensaje
2.- En este punto dices que para el histograma generas un bitmap y que yo lo pinte. No me parece bien un bitmap.
Era por no tener que guardar en memoria el histograma completo y ahorrar algo. Calcular el histograma es muy rápido y pintar con GDI+ muy lento. Me parece mejor opción calcular un Bitmap directamente desde el histograma en C y recalcularlo si hace falta cambiarlo de tamaño etc. y dejar que GDI+ sólo vuelque el histograma en la pantalla, que pasar a C# un histograma completo y pintarlo línea a línea ¿en dónde? ¡En un Bitmap! Otra opción es guardar el histograma completo en memoria... pero en cualquier caso hacer una función en C que pinte el histograma en un Bitmap.

Cita:
Iniciado por ariznaf Ver Mensaje
3.- Para manejar las vistas pensaba utilizar un contenedor de controles de tipo tabla. Con él será fácil añadir columnas y filas y meter en cada celda un PerfectView de manera dinámica. No creo que el que sean 2 o 4 dificulte mucho esa parte de la programación. Entonces por lo que entiendo, la propia rutina de escalado hará la conversión al espacio de color y la gamma de salida para comprobar si está quemado (sólo si se ha seleccionado marcar los pixels quemados). Por las mismas puede también hacer la conversión a sRGB+Gamma y nos evitamos buffers intermedios. Si es manejar una LUT no habría mucho problema ¿no?
Lo del control tipo tabla como tú quieras. A mí me gustaba más la so