предисловие
В предыдущем сообщении блога мы подробно объяснили принцип преобразования Фурье и реализацию преобразования Фурье с использованием библиотеки Numpy. Но на самом деле в OpenCV есть функция, непосредственно реализующая преобразование Фурье.
В OpenCV мы используем cv2.dft() для реализации преобразования Фурье и cv2.idft() для реализации обратного преобразования Фурье. Эти две функции определяются следующим образом:
cv2.dft(原始图像,转换标识)
Исходное изображение здесь должно быть в формате np.float32. Итак, сначала нам нужно преобразовать изображение с помощью функции cv2.float32(). Значение флага преобразования обычно равно cv2.DFT_COMPLEX_OUTPUT, которое используется для вывода сложного массива.
После преобразования функции cv2.dft() мы получим спектральную информацию исходного изображения. На данный момент нулевой компонент не находится в центре, как в реализации библиотеки Numpy. Здесь нам все еще нужно использовать функцию numpy.fft.fftshift(), чтобы переместить ее в среднее положение.
Следует отметить, что возвращаемое значение функции cv2.dft() является двухканальным, первый канал — действительная часть результата, а второй канал — мнимая часть результата. Спектральное изображение после обработки функцией numpy.fft.fftshift() представляет собой просто значение, состоящее из действительной и мнимой частей, для его отображения используется другая функция cv2.magnitude().
Функция определяется следующим образом:
cv2.magnitude(参数1,参数2)
Параметр 1: значение координаты x с плавающей запятой, то есть действительная часть
Параметр 2: значение координаты y с плавающей запятой, то есть мнимая часть, он должен иметь тот же размер, что и параметр 1 (размер)
После получения величины спектрального изображения необходимо сопоставить величину с пространством в градациях серого [0,255], чтобы отобразить его как изображение в градациях серого. Как и в предыдущем сообщении блога, используйте 20*np.log(cv2.magnitude()).
Реализуйте преобразование Фурье
Далее давайте реализуем преобразование Фурье с помощью вышеуказанной функции OpenCV и отображаем его спектральную информацию.
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("4.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
result = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1]))
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis('off')
plt.subplot(122)
plt.imshow(result, cmap="gray")
plt.axis('off')
plt.show()
После запуска эффект отображения такой же, как и в предыдущем сообщении в блоге.
Реализуйте обратное преобразование Фурье
Все так же, как и в предыдущем сообщении в блоге, здесь мы фильтруем спектральную информацию изображения, а здесь мы фильтруем информацию о низких частотах.
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("4.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
result = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1]))
rows,cols=img.shape
rows_half,cols_half=int(rows/2),int(cols/2)
mask=np.zeros((rows,cols,2),dtype=np.uint8)
mask[rows_half-30:rows_half+30,cols_half-30:cols_half+30]=1
#逆傅里叶变换
fShift=dftShift*mask
ishift=np.fft.ifftshift(fShift)
iimg=cv2.idft(ishift)
iimg=cv2.magnitude(iimg[:,:,0],iimg[:,:,1])
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis('off')
plt.subplot(122)
plt.imshow(iimg, cmap="gray")
plt.axis('off')
plt.show()
После запуска эффект следующий:
Видно, что после фильтрации низкочастотной информации ослабляется краевая информация изображения.