"Normalizar" mi transformación de wavelet D4 en cada paso reduce la calidad de imagen final

7

Imagen original:

imagen original antes de la transformación y filtrado

(Las imágenes incluidas son imágenes .png, por lo que no se agregó ninguna distorsión adicional al guardar / cargar para ver)

He usado la transformación D4 de la página 20 de "Ondulaciones en matemáticas" , que es básicamente estos 5 pasos:

Reenviar d4:

c1 = √3 / 4.0 ;
c2 = (√3 - 2) / 4.0 ;
s[ IEVEN ] += √3 * s[ IODD ] ;
s[ IODD ] -= c1*s[ IEVEN ] + c2*s[ IPREVEVEN ] ;
s[ IEVEN ] -= s[ INEXTODD ] ;
s[ IEVEN ] *= ( √3 - 1 ) / √2 ;
s[ IODD ] *= ( √3 + 1 ) / √2 ;

El inverso:

c1 = √3 / 4.0 ;
c2 = (√3 - 2) / 4.0 ;
s[ IODD ] *= ( √3 - 1 ) / √2 ;
s[ IEVEN ] *= ( √3 + 1 ) / √2  ;
s[ IEVEN ] += s[INEXTODD] ;
s[ IODD ] += c1*s[ IEVEN ] + c2*s[IPREVEVEN] ;
s[ IEVEN ] -= √3 * s[ IODD ] ;

Estoy compilando y ejecutando esto usando doublevalores de precisión de C ++. Ejecuto esto en las filas de la imagen, luego en las columnas. Utilizo un algoritmo de filtración cruda para eliminar el 90% más bajo de los coeficientes de diferencia en la imagen.

El algoritmo de filtración es:

  • Recorrer toda la imagen transformada (como un conjunto de números)
  • Encuentre el coeficiente de diferencia más grande ( maxVal) (en toda la imagen 2d)
  • Elija minValToSurvivecomo 1% de maxVal.
  • Si un coeficiente de diferencia tiene una magnitud menor que minValToSurvive, se pone a cero.

Aquí está mi problema es. Cuando elimino solo el 83% de los coeficientes de diferencia más bajos de la imagen (minValToSurvive = 0.01 * maxVal), obtienes esto:

normalizado

d4 83% de reducción normalizada

Si elimino los pasos de normalización:

s[ IEVEN ] *= ( √3 - 1 ) / √2 ; // REMOVE
s[ IODD ] *= ( √3 + 1 ) / √2 ;

(en las transformaciones fwd y reverse), el resultado después de eliminar el 90% de los componentes es mucho mejor (mucho menos ruido)

90% de reducción, no normalizado

Entonces puedo pensar en 1 de 2 problemas:

  • Normalizar la imagen por los factores (√3 - 1) / √2 está matando la precisión
  • No estoy filtrando correctamente

¿O estoy equivocado? Si estoy filtrando (eliminando componentes insignificantes) incorrectamente, ¿cuál es una mejor manera de filtrar? Si se trata de la precisión de coma flotante, ¿no debería normalizar la transformación en cada paso ?

bobobobo
fuente

Respuestas:

3

La respuesta correcta es que debe realizar cada uno de los pasos Actualizar / Predecir en la señal de entrada completamente antes de realizar la próxima Actualización / Predecir. Lo que estaba haciendo era caminar a través de la señal y realizar cada Actualización / Predicción sobre la marcha.

En la página 158 de "Ondas", hay una implementación de referencia.

// s is the signal
#define IEVEN (2*j)
#define IODD (2*j + i)
for( int i = 1 ; i <= n/2 ; i *= 2 )
{
  for( int j = 0 ; j <= n/2 - i ; j += i ) // Must do this Predict step COMPLETLEY
    s[ IEVEN ] += √3 * s[ IODD ] ;

  for( int j = 0 ; j <= n/2 - i ; j += i ) // Then this one..
  {
    int prevEvenIndex = IPREVEVEN ;
    s[ IODD ] -= d4c1*s[ IEVEN ] + d4c2*SAFE_PREV(s,prevEvenIndex) ;
  }

  for( int j = 0 ; j <= n/2 - i ; j += i )
  {
    int nextOddIndex = INEXTODD ;
    s[ IEVEN ] -= SAFE_NEXT(s,nextOddIndex) ;
  }

  for( int j = 0 ; j <= n/2 - i ; j += i )
  {
    s[ IEVEN ] *= d4normEvens ;
    s[ IODD ] *= d4normOdds ;
  }
}

La transformación D4 del 98% 0:

d4 98%

bobobobo
fuente
¡Felicitaciones por publicar la actualización en su investigación! Este sitio aún no ha reunido una gran variedad de expertos, por lo que no todas las preguntas pueden ser respondidas, pero es genial que haya regresado y compartido sus hallazgos. Estoy seguro de que será útil para otros que buscan información similar.
Phonon