пʼятниця, 7 травня 2021 р.

Реалізація перетворення Фур'є в OpenCV

Mathedemo
В OpenCV швидке дискретне перетворення Фур'є (FFT) напівтонового зображення виконує функція cv2.dft() На виході отримуємо двовимірний масив чисел (окремо дійсна та уявні частини). Зауважимо, що в NumPy існує власна функція np.fft.fft2() яка реалізує перетворення Фур'є, але на виході отримується одновимірний масив комплексних чисел.

Оскільки безпосередньо візуалізувати такий масив неможливо, для візуалізації використовують масив логарифмів модулів цих чисел ( спектр) зміщений так, щоб компонента, яка відповідає нульовій фазовій частоті знаходилася в центрі координат ( як у декартовій системі координат).

Побудова спектрального зображення:

img = cv2.imread('foto.jpg',0)
# виконуємо дискретне перетворення Фур'є
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
#Перенесення нульової фази в центр координат
dft_shift = np.fft.fftshift(dft)
# створення масиву модулів комплексних значень та логарифму від них 
magnitude_spectrum = 1*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Вхідне зображення'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum , cmap = 'gray')
plt.title('Спектральне зображення'), plt.xticks([]), plt.yticks([])
#plt.savefig('Lena.png') # При потребі
plt.show() 
Приклад перетворення Фур'є

Для повернення з частотної області в просторову, потрібно виконати обернене перетворення Фур'є і знову замінити комплексні числа їхніми модулями.

img_back = cv2.idft(dft)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
Виведення такого зображення у блокноті слід виконувати засобами бібліотеки matplotlib - plt.show(), imsave, a не функцією cv2.imshow. Також, для збереження у файлі ( формату .png) використати функцію plt.savefig('file.png').

Для створення фільтру низьких частот (LPF) потрібно перевести зображення у частотну область і виконати маскування, яке відсіче високочастотні області, а потім повернутися назад в просторову область. Приклад побудови фільтру низьких частот

img=cv2.imread('Lena.jpg',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
#Створюємо маску  з центральним квадратом розміру d		
rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
d=50
mask[crow-d:crow+d, ccol-d:ccol+d] = 1
#застосовуємо маску
dft_shift_masked=dft_shift*mask
# виконуємо обернене перетворення
f_ishift = np.fft.ifftshift(dft_shift_masked)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1]) 
Приклад фільтрації фільтром низьких частот

Фільтри низьких частот особливо ефективні при покращенні зображень спотворених високочастотним періодичним шумом:

Видалення періодичного шуму фільтром низьких частот при $d=60$.

Аналогічною створюється маска фільтру низьких частот

mask = np.ones((rows,cols,2),np.uint8)
d=50
mask[crow-d:crow+d, ccol-d:ccol+d] = 0 
В результаті отримуємо зображення відфільтроване фільтром низьких частот

В залежності від типу шуму у складних випадках фільтри можуть мати різноманітну форму і підбираються окремо до кожного зображення.

Немає коментарів:

Дописати коментар