"Normalizar" minha transformação de wavelet D4 em cada etapa reduz a qualidade final da imagem

7

Imagem original:

imagem original antes da transformação e filtragem

(As imagens incluídas são imagens .png, portanto, nenhuma distorção adicional foi adicionada ao salvar / fazer upload para visualização)

Eu usei a transformação D4 da página 20 de "Ondulações na matemática" , que são basicamente essas 5 etapas:

Encaminhar 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 ;

O 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 ] ;

Estou compilando e executando isso usando doublevalores de precisão do C ++. Eu corro isso nas linhas da imagem, depois nas colunas. Eu uso um algoritmo de filtragem bruto para remover os 90% mais baixos dos coeficientes de diferença na imagem.

O algoritmo de filtragem é:

  • Percorrer toda a imagem transformada (como um conjunto de números)
  • Encontre o maior coeficiente de diferença ( maxVal) (na imagem 2d inteira )
  • Escolha minValToSurvivecomo 1% de maxVal.
  • Se um coeficiente de diferença tiver uma magnitude menor que minValToSurvive, será zerado.

Aqui está o meu problema. Quando removo apenas 83% dos coeficientes de diferença mais baixa da imagem (minValToSurvive = 0,01 * maxVal), você obtém o seguinte:

normalizado

d4 83% de redução normalizada

Se eu remover as etapas de normalização:

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

(nas transformações avante e reversa), o resultado após a remoção de 90% dos componentes é muito melhor (muito menos ruído)

Redução de 90%, não normalizada

Então, eu posso pensar em 1 de 2 problemas:

  • Normalizar a imagem pelos fatores (√3 - 1) / √2 está matando a precisão
  • Não estou filtrando corretamente

Ou eu estou errado? Se estou filtrando (removendo componentes insignificantes) incorretamente, qual é a melhor maneira de filtrar? Se for a precisão do ponto flutuante, não devo normalizar a transformação a cada passo ?

bobobobo
fonte

Respostas:

3

A resposta certa é que você tem que executar cada um a actualização / Prever passos no sinal de entrada completamente antes de fazer a próxima atualização / prever. O que eu estava fazendo era atravessar o sinal e executar cada atualização / previsão à medida que avançava.

Na página 158 de "Ondulações", há uma implementação de referência.

// 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 ;
  }
}

A transformação D4 de 98% 0:

d4 98%

bobobobo
fonte
Parabéns por postar a atualização em sua pesquisa! Este site ainda não reuniu uma grande variedade de especialistas. Portanto, nem todas as perguntas podem ser respondidas, mas é ótimo que você volte e compartilhe suas descobertas. Tenho certeza de que será útil para outras pessoas que procuram informações semelhantes.
Phonon