Redondeos en conversion a gris

Redondeos en conversion a gris

de Guillermo Cossio Coppes -
Número de respuestas: 4

Buenas,

en el autotest de la funcion convertirImagenColorAGris me aparecen solamente 4 pixeles erroneos. Todos ellos me estan dando el valor esperado + 1, por lo que supongo que hay algun error de redondeo. Cada componente del pixel a color lo pase a float antes de multplicar por los coeficientes y hacer la suma, pero el resultado no cambio. Finalmente decidi imprimir la cuenta que iba a hacer antes de convertir cada pixel para chequearla a mano y efectivamente el resultado es correcto. Note que en los cuatro pixeles que dan mal la formula de la letra da un numero entero exacto, pero si cada termino se redondea antes de sumarlos da el valor que espera el autotest.

Mi duda entonce es la siguiente: lo que deberiamos hacer es

w = round(0.2 * r) + round(0.7 * g) + round(0.1 * b)

o

w = round(0.2 * r + 0.7 * g + 0.1 * b)?

desde ya muchas gracias!


En respuesta a Guillermo Cossio Coppes

Re: Redondeos en conversion a gris

de Leopoldo Agorio -
Ojo con el round, porque la convención es redondear para abajo. Lo esperado es
w = floor(0.2 * r + 0.7 * g + 0.1 * b), donde floor es el redondeo hacia abajo (ocurre automáticamente si uno castea, o puede llamar a la función floor de math).
Si como dices es un error del autotest y hay una situación en la que está calculándose incorrectamente le ponemos la lupa y lo ajustamos. Podes decirnos la imagen en concreto y alguno de los píxeles en concreto en que crees que debería dar otra cosa?
En respuesta a Leopoldo Agorio

Re: Redondeos en conversion a gris

de Guillermo Cossio Coppes -
Habia probado con floor tambien y no hubo caso. Adjunto el log de la funcion. auxConvertir es un float que utilice para guardar el resultado de la suma, al que luego castee a unsigned int antes de guardarlo en el pixel. Puse un printf para que muestre que esta haciendo en uno de los pixeles problematicos, y como veras la cuenta deberia dar exactamente 5. En el caso de que se flooree cada termino por separado daria 4, como dice el autotest.

Mis disculpas si aparece este mensaje dos veces, se me tranco el eva al mandarlo y tuve que reescribirlo
En respuesta a Guillermo Cossio Coppes

Re: Redondeos en conversion a gris

de Leopoldo Agorio -
Comentario menor, el casteo debería ser a unsigned char. La lógica que hace nuestro autotest es la de hacer la suma de los productos en una variable tipo float y luego castearla a unsigned char, como comentás, por lo que el error se me sigue escapando.

De hecho, me puse a jugar un poco más con C y estoy perplejo, pero es sin lugar a dudas una rareza de C. Hice un código de prueba con lo siguiente:
printf("result = %f, casteo uint = %d , casteo uchar = %hhu \n", (float)((0.7*6.0+0.2*4.0+0.1*0.0)), (unsigned int)((0.7*6.0+0.2*4.0+0.1*0.0)), (unsigned char)((0.7*6.0+0.2*4.0+0.1*0.0)) );
printf("casts de 5.0: %d,%d\n", (int)5.0, (unsigned int) 5.0);

Y en pantalla obtuve:
result = 5.000000, casteo uint = 4 , casteo uchar = 4
casts de 5.0: 5,5

Así que parece que C está casteando para abajo el flotante que le da aproximadamente 5.0, pero es sin duda un problema de representaciones y casteos en C. Vos de momento no te preocupes que no es un error tuyo, es suficientemente interesante como para que lo discutamos en el equipo.