Изображение представляет то, что я делаю в упражнении 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])
Полный скрипт здесь
Если вы распечатаете значения в массиве изображений вашего product
, вы обнаружите, что все пиксели в белых полосах на самом деле имеют значение -inf
, а не 0
. В своем коде, как часть процесса создания product
вы используете np.log
для изменения np.log
некоторых ваших данных. То есть данные, 0
в нем, и результат np.log(0)
является -inf
.
Вы можете исправить это несколькими способами. Простейшим вариантом будет просто заменить все значения -inf
в product
на 0
. После создания product
, если вы добавите следующую строку:
product[np.isneginf(product)] = 0
тогда, когда вы строите product
него будут черные полосы, как вы и ожидали:
Вот почему вы -inf
product
-inf
. Это строка в вашем коде, которая создает 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
вдоль полос, как вы ожидали. Однако, если вы попытаетесь изобразить величину напрямую, вы получите очень темный график, который не показывает много:
Причина этого заключается в том, что Matplotlib будет масштабировать ваши данные при выборе цветов так, чтобы наименьшие значения в массиве изображений были черными, а самые большие значения - белым. Проблема здесь в том, что наибольшее значение по magnitude
намного больше, чем почти любое другое значение. Таким образом, вы получаете несколько пикселей белого цвета (около центра), а каждый второй пиксель окрашивается почти в черный цвет.
Вы можете сделать график magnitude
показывают немного больше подстилающих детали пропускания vmax=1000
к imshow
функции вы используете для построения изображения. Это устанавливает явное максимальное значение данных для карты цветов:
Это далеко от идеала, так как это означает, что большая часть вашего изображения отображается как полностью насыщенный белый, независимо от его основных деталей.
В действительности у вас уже есть лучшее решение для этой проблемы в вашем коде: вы масштабируете данные по magnitude
используя np.log
. Результат этого масштабирования, массив product
, будет иметь все свои значения гораздо ближе друг к другу. Это имеет полезный эффект, позволяя вам видеть мелкие детали на изображении, когда вы строите product
. Однако проблема, с которой вы столкнулись, заключается в том, что лог 0 равен бесконечности:
print(np.log(0))
# this outputs
# -inf
Таким образом, полосы с magnitude
0
становятся полосами -inf
в product
. Matplotlib -inf
эти значения -inf
, окрашивая их так же, как и максимальное значение в вашем входном массиве (то есть в белый цвет). Таким образом, вы получаете полосы белого цвета, которые вы видите в вашем нанесен product
изображения.
inf
в его массиве изображенийproduct
. В любом случае, стандартная'gray'
цветовая карта в Matplotlib всегда будет по умолчанию показывать наименьшие значения черным цветом, а наибольшие значения белым. Выбор не произвольный.