2011-03-02 30 views
13

estoy tratando de eliminar el ruido sinusoidal en esta imagen:Eliminación de ruido sinusoidal con filtro Butterworth

enter image description here

Aquí está su espectro DFT (después de la aplicación de registro y la escala de intensidad arbitraria):

enter image description here

Ya tengo un filtro de Butterworth para aplicar a esta imagen. Noqueará los picos de frecuencias medias. Me estoy ocupando de escalar de [0..255] a [0..1.0] después de la carga. Aquí está el filtro:

enter image description here

Los resultados no son grandes:

enter image description here

Mis preguntas:

  • ¿Por qué hay todavía una cantidad significativa de ruido que queda en el ¿imagen?
  • ¿Por qué el resultado es más oscuro que la imagen original? El filtro claramente no toca el término DC, así que esperaría que la intensidad promedio sea la misma.
  • ¿Por qué el filtro solo saca algunos de los picos? Viene de un libro de texto, por lo que me inclino a creer que es correcto, pero hay otros picos en el espectro: ¿también son parte del ruido? Traté de eliminarlos usando filtros concéntricos, pero no sirvió de mucho y oscureció la imagen más allá del reconocimiento.

He tomado la imagen (recortada) y el filtro del libro Digital Image Processing de Gonzalez and Woods. En su ejemplo, el ruido periódico se elimina por completo mediante el filtrado, y la intensidad media de la imagen sigue siendo la misma.

Mi código fuente para cargar la imagen y el filtro, DFT, filtrado, IDFT es a continuación:

import cv 

def unshift_crop(comp, width, height): 
    result = cv.CreateImage((width, height), cv.IPL_DEPTH_8U, 1) 
    for x in range(height): 
     for y in range(width): 
      real, _, _, _ = cv.Get2D(comp, x, y) 
      real = int(real) * ((-1)**(x+y)) 
      cv.Set2D(result, x, y, cv.Scalar(real)) 
    return result 

def load_filter(fname): 
    loaded = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE) 
    flt = cv.CreateImage(cv.GetSize(loaded), cv.IPL_DEPTH_32F, 2) 
    width, height = cv.GetSize(loaded) 
    for i in range(width*height): 
     px, _, _, _ = cv.Get1D(loaded, i) 
     #cv.Set1D(flt, i, cv.Scalar(px/255.0, 0)) 
     cv.Set1D(flt, i, cv.Scalar(px/255.0, px/255.0)) 
    return flt 

if __name__ == '__main__': 
    import sys 
    fname, filt_name, ofname = sys.argv[1:] 
    img = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE) 
    width, height = cv.GetSize(img) 
    src = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2) 
    dst = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2) 
    cv.SetZero(src) 
    for x in range(height): 
     for y in range(width): 
      px, _, _, _ = cv.Get2D(img, x, y) 
      px = float(px) * ((-1) ** (x+y)) 
      cv.Set2D(src, x, y, cv.Scalar(px, 0)) 
    cv.DFT(src, dst, cv.CV_DXT_FORWARD) 
    flt = load_filter(filt_name) 
    cv.Mul(dst, flt, src) 
    cv.DFT(src, dst, cv.CV_DXT_INV_SCALE) 
    result = unshift_crop(dst, width, height) 
    cv.SaveImage(ofname, result) 

EDITAR

Hubo un error en la fuente original donde los componentes imaginarios de filtro eran cargado como cero Esto es lo que causó que la imagen resultante aparezca más oscura de lo que realmente era. Lo arreglé y comencé la línea relacionada.

Uso de la fuente fija y el filtro que @ 0x69 proporcionado (sí, ya sé que no es realmente un filtro Butterworth, pero en este momento estoy feliz de probar lo que sea), este es el resultado:

enter image description here

Mejor de lo que tenía que empezar, pero aún así no es tan bueno como esperaba. ¿Alguien puede vencer esto? Sospecho que poner más muescas para quitar los picos restantes puede ser de algún beneficio.

EDITAR 2

me he puesto en contacto el autor.Esta es su respuesta:

El problema es que la imagen utilizada en el experimento se punto, flotando mientras que la que se muestra en el libro (y el original proporcionado en los descargas) son 8 bits. Esto se requiere para la impresión, etc.

Con el fin de duplicar el experimento, usted tiene que comenzar con la imagen libre de ruido y luego añadir su propio ruido de ella.

+3

+1 para una pregunta bien explicada – macarthy

+0

¿Por qué no muestra el documento original de la imagen filtrada? – highBandWidth

+0

@highBandWidth porque es trivial determinarlo desde el filtro y el DFT de la imagen de entrada (por multiplicación). – misha

Respuesta

5

he tratado de usar tal filtro modificado: enter image description here
y lo que tengo es este ->
enter image description here
No puedo explicar plenamente los resultados, pero mi mejor conjetura es que el ruido sinusoidal interactuando con la señal de imagen principal de alguna manera genera ondas de ruido secundarias, terceras, ... armónicas. El resultado también está lejos de ser ideal, parece que todavía quedan algunos armónicos de ruido aquí ... Por cierto, gracias por una pregunta interesante.

EDIT:

Mi segundo intento de mejora del filtro. Filtro: resultado
enter image description here filtrada:
enter image description here
parece que esta vez hay un patrón de ruido sinusoidal claro es visible.

+0

¡Gracias por intentar esto y producir un mejor filtro! Ver mi respuesta actualizada. – misha

3

Recuerdo haber jugado con esta imagen durante un curso de procesamiento de imágenes hace un par de años, y obtuve los mismos resultados que tú.

No sé cómo los autores del libro de texto obtuvieron la imagen que muestran en el libro, pero deben haber hecho algo más que aplicar ese filtro de Butterworth. Como mencionas, hay más picos, por lo que es posible que hayan aplicado más filtros de Butterworth para eliminarlos.

Sin embargo, la media de la imagen no fue igual para mí. ¿Has intentado calcular la media de las dos imágenes y comparar? Podría ser que es solo la escala al mostrar que causa la imagen más oscura.

+0

Gracias por su aporte. Estaba empezando a sospechar que se realizó algún procesamiento adicional. Escuchar a alguien enfrentar el mismo problema es tranquilizador. En cuanto a la media de la imagen, mira mi publicación editada. – misha

Cuestiones relacionadas