PDA

Ver la versión completa : Alternativas Flujo de trabajo: Del buffer revelado a la pantalla



ariznaf
19/05/2008, 14:32
En el Hilo general de Desarrollo de la aplicación se plantearon dos alternativas sobre cómo se debía de hacer el paso de la imagen devuelta por DCRaw en 16 bits a la imagen final mostrada en pantalla en 8 bits.
En concreto la discusión se centra más bien en cuándo hacer la conversión a 8 bits, pues ello tiene influencia en los resultados obtenidos (sobre todo en relación con el aviso de zonas quemadas, ya que si se hace sobre la imagen de 8 bits en vez de 16 se muestran pixels quemados que en realidad no lo están debido al redondeo).

Abro este hilo para discutir en profundidad las dos alternativas y ver los pros y los contras, sin mezclar esto con otros temas colaterales.

Las dos alternativas a discutir son:
1.-Seguir con el flujo de conversión tal y como se venía haciendo (por las funciones FastDraw creadas por Manul), creando previamente un nuevo buffer de 8 bits para marcar los pixels quemados calculados sobre el buffer de 16 bits.

El flujo sería algo así:

BUFFER SALIDA 16 bits --> Detección Altas luces (si está activada produce buffer altas luces 8 bits) --> Conversión a 8 bits (a partir de aquí todo en 8 bits) --> Reescalado usando FastDraw (deberá reescalar los dos buffers, el de la imagen y el del aviso de la detección --> Aplicación de Gamma rápida de monitor (si es distinta de la del revelado) --> Superposición del Buffer Altas luces en imagen de salida --> Dibujado encima de la parte de imagen seleccionada --> dibujado encima del histograma. --> mostrar en pantalla.

2.- Adaptar el código de Fastdraw para que el buffer de entrada fuera de 16 bits, encargándose este código de comprobar las altas luces y de convertir a 8 bits.

El flujo de trabajo sería algo así:

BUFFER SALIDA 16 bits --> Reescalado usando FastDraw Con detección altas luces y conversión a 8 bits (detección previa a la conversión) Salida en 8 bits --> Aplicación de Gamma rápida de monitor (si es distinta de la del revelado) --> Dibujado encima de la parte de imagen seleccionada --> dibujado encima del histograma. --> mostrar en pantalla.

La discusión se centra sobre todo en las ventajas de una y otra alternativa y en si la opción 2 puede tener una velocidad suficiente.

ManuelLlorens
19/05/2008, 14:49
No te molestes ariznaf, voy a implementar directamente la tuya y si la velocidad es suficiente pasamos de la otra.

ariznaf
19/05/2008, 14:57
Ahora voy daré mi opinión:

La primera alternativa es posible que sea más rápida y ha estado funcionando bien hasta ahora. El problema surge al querer hacer un marcado de los pixels quemados.
Si se hace sobre la imagen en 8 bits dentro de FastDraw o sobre la salida de fastDraw, ya se ha perdido información, pues se ha rendondeado y se marcarán muchos más pixels quemados de los que realmente están (no sólo los que tengan valor 65535 sino entre 65281 y 65535 (si usamos el algoritmo rápido x16>>8 propuesto por Manuel).

Para evitar eso, la alternativa propuesta por Manuel sugiere crear un nuevo buffer de ocho bits en el que se asignen los colores quemados calculados sobre el buffer ya revelado de 16 bits y convertir a continuación el buffer de 16 bits a 8 bits.

Luego se llama al FastDraw para el reescalado y se superpone la imagen de los pixels quemados.
A destacar que hay que hacer el reescalado dos veces: uno sobre la imagen y otro sobre el buffer de pixels quemados, para luego poder superponerlos.

Creo que la adtación a la gamma del monitor se puede hacer sobre la imagen de 8 bits sin problemas. Según dice GUI el lugar no afecta a los pixels quemados.
Aunque si esto es así igual se podía hacer justo después de la conversión a 8 bits, previo al reescalado y así no hay que hacerlo cada vez que se hace zoom de la imagen o pan.
_________________________________


No te molestes ariznaf, voy a implementar directamente la tuya y si la velocidad es suficiente pasamos de la otra.


Bien, Manuel a ver si funciona suficientemente bien.

De todas maneras creo que quedan cosas por pulir en este esquema que había propuesto.

Sobre el esquema de 16 bits:
En este caso la corrección de gamma para ajustar a la salida del monitor no se puede hacer previa como en el caso anterior, pues si el buffer es el de 16 bits de la salida del revelado (con una gamma lineal u otra que no coincida con la del monitor) si cambiamos el gamma estropeamos el buffer.

A no ser claro está que hiciéramos otra copia del buffer sobre el que trabajar o que cuando se vaya a guardar o a poner en el portapapeles se haga otro revelado partiendo de cero (quizás esto es lo mejor y creo que algo habíais comentado de utilizar algoritmos de más precisión para el revelado final) con lo que no importaría "estropear" el buffer del revelado.

En este caso el flujo sería así:
BUFFER SALIDA 16 bits -->Aplicación de Gamma rápida de monitor en 16 bits(si es distinta de la del revelado) --> Reescalado usando FastDraw Con detección altas luces y conversión a 8 bits rápida (detección previa a la conversión) Salida en 8 bits --> Dibujado encima de la parte de imagen seleccionada --> dibujado encima del histograma. --> mostrar en pantalla.
_________________________________
El meollo de la cuestión será en la forma de implementar el reescalado con FastDraw y las otras tareas que se le encomiendan:

Comentaste que era necesario llevar otro buffer interno. En principio creo que no es necesario (aunque no conozco en detalle cómo haces el escalado porque me pierdo un poco con tanta variable críptica ;) ).

El algoritmo debería de ser algo así:



Para cada pixel que vaya a ir en la salida diezmada por el escalado {
Comprobar si el pixel está quemado: {
quemado: asignar en el buffer de salida un valor de 128 en el canal quemado.
no quemado: {
convertir el color a 8 bits // (usando el algoritmo >>8 será suficiente.El preciso para el guardado a disco o a portapapeles).
asignar al pixel de salida en 8 bits.
}
}
}


Como ves en ese esquema sólo se ejecutan los pasos sobre los pixels diezmados (seleccionados para la salida). Y no haría falta llevar otro buffer intermedio de 16 bits.

Cuando decías que el buffer era necesario me imagino que es porque usas algún algoritmo de copiado rápido de filas o algo así.

En ese caso, el procedimiento anterior podría hacerse por filas, pidiendo memoria únicamente para una fila de pixels de salida de 16 bits y luego haciendo los pasos de conversión a 8 bits y detección de altas luces.



Pedir memoria para una fila de pixels de salida con valores de 16 bits.
Para cada fila seleccionada {
Copiar pixels seleccionados a fila de 16 bits usando método de copiado rápido {
Para cada pixel de la fila {
Comprobar si el pixel está quemado: {
quemado: asignar en el buffer de salida un valor de 128 en el canal quemado.
no quemado: {
convertir el color a 8 bits (usando el algoritmo >>8 será suficiente. El preciso para el guardado a disco o a portapapeles).
asignar al pixel de salida en 8 bits.
}
}
}
}
liberar memoria pedida para fila de 16 bits.



Bueno algo así.

¿Ves algún fallo en ese esquema?