estoy tratando de eliminar el ruido sinusoidal en esta imagen:Eliminación de ruido sinusoidal con filtro Butterworth
Aquí está su espectro DFT (después de la aplicación de registro y la escala de intensidad arbitraria):
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:
Los resultados no son grandes:
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:
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.
+1 para una pregunta bien explicada – macarthy
¿Por qué no muestra el documento original de la imagen filtrada? – highBandWidth
@highBandWidth porque es trivial determinarlo desde el filtro y el DFT de la imagen de entrada (por multiplicación). – misha