0 в спектре БПФ белые? Почему?- OpenCV - PullRequest
0 голосов
/ 09 декабря 2018

enter image description here

Изображение представляет то, что я делаю в упражнении openCV с преобразованием Фурье.Это упражнение для устранения периодического шума.Я обнаруживаю полосы, издающие шум, и маской удаляю это.Как видите, я делаю продукт из dft_shift с маской.Я предполагаю, что произведение этого 0, мой вопрос: почему эти строки белые, если эти значения 0 ???

Код:

dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)    #calcula la transf. Fourier 
dft_shift = np.fft.fftshift(dft) #proyecta los cuadrantes de la imagen 
dft_shift = dft_shift*mask2
f_ishift = np.fft.ifftshift(dft_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

Полный сценарий Здесь

1 Ответ

0 голосов
/ 09 декабря 2018

Решение

Если вы распечатаете значения в массиве product, вы обнаружите, что все пиксели в белых полосах на самом деле имеют значение -inf, а не 0,В вашем коде, как часть процесса создания product, вы используете np.log для изменения масштаба некоторых ваших данных.Эти данные содержат 0, а результат np.log(0) равен -inf.

Это можно исправить несколькими способами.Самым простым вариантом будет просто заменить все значения -inf в product на 0.После создания product, если вы добавите следующую строку:

product[np.isneginf(product)] = 0

, тогда при построении product будут черные полосы, как вы и ожидали:

enter image description here

Глубокое погружение

Вот почему вы заканчиваете с -inf в product.Это строка в вашем коде, которая создает product:

product = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))

Если мы разделим это на две строки, мы сможем выяснить, что происходит:

magnitude = cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1])
product = 20*np.log(magnitude)

magnitudeимеет 0 по группам, как вы ожидали.Однако, если вы попытаетесь изобразить величину напрямую, вы получите очень темный график, который не показывает много:

enter image description here

Причина этогов том, что Matplotlib будет масштабировать ваши данные при выборе цветов так, чтобы самые маленькие значения в массиве изображений были черными, а самые большие значения - белыми.Проблема здесь в том, что наибольшее значение в magnitude намного больше, чем почти любое другое значение.Таким образом, вы получите несколько пикселей белого цвета (около центра), а каждый второй пиксель будет окрашен почти в черный цвет.

Вы можете заставить график magnitude показать немного больше базовой детали, пропустив vmax=1000 до функции imshow, которую вы используете для построения своих изображений.Это устанавливает явное максимальное значение данных для цветовой карты:

enter image description here

Это далеко от идеала, поскольку это означает, что отображается большая часть вашего изображениякак полностью насыщенный белый, независимо от лежащих в его основе деталей.

В действительности у вас уже есть лучшее решение этой проблемы в вашем коде: вы масштабируете данные в magnitude, используя np.log.Результат этого масштабирования, массив product, будет иметь все свои значения намного ближе друг к другу.Это имеет полезный эффект, позволяя вам видеть мелкие детали на изображении при печати product.Однако проблема, с которой вы здесь сталкиваетесь, состоит в том, что лог 0 равен бесконечности:

print(np.log(0))
# this outputs
# -inf

Таким образом, полосы 0 в magnitude становятся полосами -inf в product.Matplotlib обрабатывает эти -inf значения, окрашивая их так же, как и максимальное значение в вашем входном массиве (т. Е. Как белый).Таким образом, вы получаете полосы белого цвета, которые вы видите на графике product.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...