Я пытаюсь удалить синусоидальный шум на этом изображении:
Вот его спектр ДПФ (после применения журнала и произвольного масштабирования интенсивности):
У меня уже есть фильтр Баттерворта для применения к этому изображению.Это выбьет среднечастотные пики.Я стараюсь масштабировать его с [0..255] до [0..1.0] после загрузки.Вот фильтр:
Результаты невелики:
Мои вопросы:
- Почему на изображении все еще остается значительное количество шума?
- Почему результат темнее, чем исходное изображение?Фильтр явно не касается члена постоянного тока, поэтому я ожидаю, что средняя интенсивность будет такой же.
- Почему фильтр отбирает некоторые пиков?Он взят из учебника, поэтому я склонен полагать, что это правильно, но есть и другие пики в спектре - они тоже являются частью шума?Я попытался удалить их, используя концентрические фильтры, но это не принесло много пользы и затемнил изображение до неузнаваемости.
Я взял изображение (обрезано) и отфильтровал из книги DigitalОбработка изображений Гонсалес и Вудс.В их примере периодический шум полностью удаляется фильтрацией, а средняя интенсивность изображения остается неизменной.
Мой исходный код для загрузки изображения и фильтра, DFT, фильтрация, IDFT приведен ниже:
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)
EDIT
В исходном источнике произошла ошибка, когда мнимые компоненты фильтра были загружены как ноль.Это то, что заставило полученное изображение выглядеть темнее, чем оно было на самом деле.Я исправил это и прокомментировал соответствующую строку.
Используя фиксированный источник и фильтр, предоставленный @ 0x69 (да, я знаю, что это не совсем фильтр Баттерворта, но на этом этапе я счастлив попробоватьчто угодно), вот результат:
Лучше, чем то, с чего мне пришлось начинать, но все же не так хорошо, как я надеюсь.Кто-нибудь может победить это?Я подозреваю, что использование большего количества надрезов для удаления оставшихся пиков может быть полезным.
РЕДАКТИРОВАТЬ 2
Я связался с автором.Вот их ответ:
Проблема в том, что изображение, использованное в эксперименте, имело плавающую точку, тогда как изображение, показанное в книге (и оригинал, предоставленный в загрузках), составляет 8 бит.Это необходимо для печати и т. Д.
Чтобы дублировать эксперимент, необходимо начать с бесшумного изображения, а затем добавить к нему собственный шум.