OJODIGITAL |
|
|
|
| Debates sobre la programación Para tratar temas sobre programación |
![]() |
|
||||
|
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:
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 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):
__________________
"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. |
| Publicidad |
|
||||
|
Cita:
Estoy maravillado con los avances que lleváis hechos. Álex. |
|
|||
|
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). |
|
||||
|
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. 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. |
|
||||
|
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. 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:
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: |
|
|||
|
Cita:
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í:
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:
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. |
|
|||
|
Cita:
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:
).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. |
|
||||
|
Me voy a 2º ESO a dar una clase precisamente sobre Estadística que, cómo no, habla de histogramas. Luego os contesto.
![]() |
|
|||
|
Pues háblales de la fotografía y así verán que lo de los histogramas sive para algo.
![]() |
|
||||
|
Cita:
![]() ![]() ![]() Un saludo: Última edición por ManuelLlorens; 26-May-2008 a las 17:36. |
|
||||
|
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.
Un saludo: Última edición por ManuelLlorens; 26-May-2008 a las 17:39. |
|
||||
|
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í |
|
|||
|
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í:
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? |
|
||||
|
Cita:
Cita:
|