OJODIGITAL |
|
|
|
| Debates sobre la programación Para tratar temas sobre programación |
![]() |
|
||||
|
Sobre el control de Exposición
Me vuelvo loco cada vez buscando donde puse el último código así que abro este hilo.
Esto fue lo último que comentamos en distintos hilos: De hecho mantelo como la única opción cuando f>1, va a ser lo mejor. Forzando que el descenso de sobreexposición baje a 0EV en lineal (abajo-der.), se obtienen sobreexposiciones que saturan la luminosidad (abajo-izq.). Además cualquier esquema que supusiera una curva por encima de las rectas de la gráfica sup.-izq. implicaría más facilidad de saturación parcial así que ya que el esquema actual no crea extraños lo dejamos así. ![]() Para f<1 sí por favor prueba lo que he propuesto, creo que mejorará. Si es así el esquema final de curvas quedaría: ![]() Otro esquema que puede dar resultados muy interesantes, o como poco curiosos, es el de usar las curvas que ya tenemos definidas pero con una definición diferente de la luminosidad como el máximo de los canales: Y=max(R,G,B), tal como se hace en el modelo de color HSV. Según ese esquema los colores más saturados tendrán mayor luminosidad y se sobre/subexpondrán menos. El resultado puede ser curioso; lo cierto es que por mucha sobreexposición que se aplique, nunca se va a alterar el tono de un solo píxel porque no habrá saturaciones parciales. Esto deberá respetar el verde de tus hojas al subir la exposición, si bien las puede dejar estancadas en una determinada luminosidad cuando su entorno menos saturado sigue ganando brillo. Originalmente publicado por _GUI_ He estado dándole vueltas al control de exposición. El modo de aumento (f>1) la verdad que no me preocupa mucho qué modelo escojamos al final, porque en realidad no está justificado revelar un RAW con un aumento de la exposición sino que lo veo más bien como un control de display para revelar más comodamente imágenes subexpuestas. Si no me he perdido ya probamos estas 3 estrategias: 0. Normal 1. Modelo Y CIE + curva con codo 2. Modelo Y HSV + curva con codo 2bis. Modelo Y HSV experimental (el que genera halos) Pero lo probamos, tanto en su versión normal (daba posterizaciones) como experimental (daba halos): Así que nos quedamos con el modelo Y CIE y curvas con codo para exp<1 y rectas con codo para exp>1. Abajo pongo el código final.
__________________
"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_; 25-may-2008 a las 21:39. |
| Publicidad |
|
||||
|
El código final implementa un único modo de ajuste de exposición, pero existe un parámetro adicional (también en pasos de diafragma) que indica cuántos diafragmas de altas luces se preservarán en los aumentos y reducciones del valor de la exposición, es decir, cuántos diafragmas a contar desde la saturación no serán corregidos por el facto standard sino por una curva de preservación. Si este parámetro vale 0, el funcionamento será como era hasta ahora el modo 0, es decir, no se preserva nada y todos los niveles se multiplican por la corrección de exposición.
Así se requieren dos controles para definir la corrección de exposición:
Código:
void exposure_correction(void){
// variables de entrada desde formulario:
// exposure (lineal): 2^(-8..0..8)
// preserve (log): 0..8
int i;
float Y, Yp, exposure2, K, EV;
if(verbose) printf("Exposure correction ");
if(preserve==0.0){
// Exposure correction without highlight preservation
if(verbose) printf("without highlight preservation\n");
for(i=0;i<height*width;i++){
image[i][0]=CLIP((float)image[i][0]*exposure); // R
image[i][1]=CLIP((float)image[i][1]*exposure); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure); // B
}
}else{
// Exposure correction with highlight preservation
if(verbose) printf("with highlight preservation\n");
if(exposure>1){
K=65535/exposure*pow(2,-preserve);
for(i=0;i<height*width;i++){
Y=0.299*(float)image[i][0]+0.587*(float)image[i][1]+0.114*(float)image[i][2]; // CIE luminosity
if(Y<K){
image[i][0]=CLIP((float)image[i][0]*exposure); // R
image[i][1]=CLIP((float)image[i][1]*exposure); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure); // B
}else{
Yp=(65535-K*exposure)/(65535-K)*(Y-65535)+65535;
exposure2=Yp/Y;
image[i][0]=CLIP((float)image[i][0]*exposure2); // R
image[i][1]=CLIP((float)image[i][1]*exposure2); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure2); // B
}
}
}else{
EV=log(exposure)/log(2); // Convertimos exp. lineal a EV
K=pow(2,-preserve);
for(i=0;i<height*width;i++){
Y=0.299*(float)image[i][0]+0.587*(float)image[i][1]+0.114*(float)image[i][2]; // CIE luminosity
if(Y<K){
image[i][0]=CLIP((float)image[i][0]*exposure); // R
image[i][1]=CLIP((float)image[i][1]*exposure); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure); // B
}else{
exposure2=pow(2,EV*(1-Y/65535)/(1-K));
image[i][0]=CLIP((float)image[i][0]*exposure2); // R
image[i][1]=CLIP((float)image[i][1]*exposure2); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure2); // 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 ManuelLlorens; 26-may-2008 a las 21:58. |
|
||||
|
Cita:
También tengo que contestar a lo del histograma gamma sí, gamma no, y tengo malas noticias (es imprescindible calcularlo sobre la imagen final, incluyendo conversión a perfil de color y compensación gamma).
__________________
"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í |
|
||||
|
Cita:
Cita:
Un saludo: Última edición por ManuelLlorens; 26-May-2008 a las 15:30. |
|
||||
|
Cita:
De hecho al histograma aunque sea en gamma le voy a poner palitos que representen los diafragmas logarítmicos. A lo segundo (negro y sat.) imposible, porque el histograma ya muestra esos puntos de negro y sat. corregidos:
Por lo tanto en el histograma no se tiene noción de esos dos puntos que acaban ajustados a 0 y 65535. Sí tiene sentido usar el histograma con un grado de zoom 1:1 en el 0 y en 65535 (o donde termine el histograma RAW), para ver cómo ajustar el negro y la sat. afectan a la imagen. Por cierto en el link de scale_colors() os preguntaba una dudilla del acceso al array de la imagen en C.
__________________
"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í |
|
||||
|
Cita:
Cita:
Aggg! me estoy quedando sin pilas en el teclado... Un saludo: |
|
||||
|
Hay un bug en mi código para exp<1 Manuel, tema de escala (0..1 vs 0..65535). Con exp<1 y preservación de 1 diafragma se obtenía menos exposición que con exp<1 y sin preservación.
El código corregido (en azul los cambios): Código:
void exposure_correction(void){
// variables de entrada desde formulario:
// exposure (lineal): 2^(-8..0..8)
// preserve (log): 0..12
int i;
float Y, Yp, exposure2, K, EV;
if(verbose) printf("Exposure correction ");
if(preserve==0.0){
// Exposure correction without highlight preservation
if(verbose) printf("without highlight preservation\n");
for(i=0;i<height*width;i++){
image[i][0]=CLIP((float)image[i][0]*exposure); // R
image[i][1]=CLIP((float)image[i][1]*exposure); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure); // B
}
}else{
// Exposure correction with highlight preservation
if(verbose) printf("with highlight preservation\n");
if(exposure>1){
K=65535/exposure*pow(2,-preserve);
for(i=0;i<height*width;i++){
Y=0.299*(float)image[i][0]+0.587*(float)image[i][1]+0.114*(float)image[i][2]; // CIE luminosity
if(Y<K){
image[i][0]=CLIP((float)image[i][0]*exposure); // R
image[i][1]=CLIP((float)image[i][1]*exposure); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure); // B
}else{
Yp=(65535-K*exposure)/(65535-K)*(Y-65535)+65535;
exposure2=Yp/Y;
image[i][0]=CLIP((float)image[i][0]*exposure2); // R
image[i][1]=CLIP((float)image[i][1]*exposure2); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure2); // B
}
}
}else{
EV=log(exposure)/log(2); // Convertimos exp. lineal a EV
K=65535*pow(2,-preserve);
for(i=0;i<height*width;i++){
Y=0.299*(float)image[i][0]+0.587*(float)image[i][1]+0.114*(float)image[i][2]; // CIE luminosity
if(Y<K){
image[i][0]=CLIP((float)image[i][0]*exposure); // R
image[i][1]=CLIP((float)image[i][1]*exposure); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure); // B
}else{
exposure2=pow(2,EV*(65535-Y)/(65535-K));
image[i][0]=CLIP((float)image[i][0]*exposure2); // R
image[i][1]=CLIP((float)image[i][1]*exposure2); // G (mixed)
image[i][2]=CLIP((float)image[i][2]*exposure2); // 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_; 27-May-2008 a las 04:22. |
|
||||
|
Idea: para Manuel que no ve intuitiva la relación entre las cifras de corrección de ajuste de exp. y diafragmas preservados, no cuesta nada dibujar a voluntad sobre el histograma la curva que representa el ajuste de exp./preserv. que se ha aplicado.
Por supuesto hay que entender que no es una curva RGB sino que se aplica sobre la luminosidad, pero el concepto está claro. También hay que entender que dicha curva afecta al histograma, y el histograma sobre el que se está superponiendo es el histograma resultante de aplicar (entre otras cosas) esa curva, cuando lo intuitivo y/o más habitual es ver las curvas sobre el histograma origen.
__________________
"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í |
|
||||
|
Cita:
Un saludo: |
![]() |
| Marcadores |
| Herramientas | |
| Desplegado | |
|
|