Большой вопрос. Я никогда не слышал об этом, но плагин Gimp Fourier кажется действительно опрятным:
Простой плагин для преобразования Фурье на изображение. Основным преимуществом этого плагина является возможность работать с преобразованным изображением внутри GIMP. Вы можете нарисовать или применить фильтры в пространстве Фурье и получить модифицированное изображение с обратным БПФ.
Эта идея - манипулирование в стиле Gimp в области частотной области и преобразование обратно в изображение - очень круто! Несмотря на годы работы с БПФ, я никогда не думал об этом. Вместо того, чтобы возиться с плагинами Gimp и исполняемыми файлами C и уродством, давайте сделаем это на Python!
Предостережение. Я экспериментировал с несколькими способами сделать это, пытаясь получить что-то близкое к выходному изображению Gimp Фурье (серое с рисунком муара) от исходного входного изображения, но я просто не мог. Изображение Gimp кажется несколько симметричным вокруг середины изображения, но оно не перевернуто вертикально или горизонтально, и оно не является транспонированным-симметричным. Я ожидаю, что плагин будет использовать реальный 2D FFT для преобразования изображения H × W в массив H × W вещественных данных в частотной области, и в этом случае симметрии не будет (это просто то, комплексный FFT, который сопряжен-симметричен для вещественных входов, таких как изображения). Поэтому я отказался от попытки перепрограммировать то, что делает плагин Gimp, и посмотрел, как я это сделаю с нуля.
Код. Очень просто: прочитайте изображение, примените scipy.fftpack.rfft
в ведущих двух измерениях, чтобы получить «частотное изображение», перемасштабировать до 0-255 и сохранить.
Обратите внимание, как это отличается от других ответов! Отсутствие серого - 2D реальный БПФ реального времени происходит независимо от всех трех каналов. № abs
необходимо: изображение частотной области может иметь законные отрицательные значения, и если вы сделаете их положительными, вы не сможете восстановить исходное изображение.(Также приятная особенность:. никаких компромиссов по размеру изображений Размер массива остается неизменным до и после FFT, ширина/высота, является ли четным или нечетным.)
from PIL import Image
import numpy as np
import scipy.fftpack as fp
## Functions to go from image to frequency-image and back
im2freq = lambda data: fp.rfft(fp.rfft(data, axis=0),
axis=1)
freq2im = lambda f: fp.irfft(fp.irfft(f, axis=1),
axis=0)
## Read in data file and transform
data = np.array(Image.open('test.png'))
freq = im2freq(data)
back = freq2im(freq)
# Make sure the forward and backward transforms work!
assert(np.allclose(data, back))
## Helper functions to rescale a frequency-image to [0, 255] and save
remmax = lambda x: x/x.max()
remmin = lambda x: x - np.amin(x, axis=(0,1), keepdims=True)
touint8 = lambda x: (remmax(remmin(x))*(256-1e-4)).astype(int)
def arr2im(data, fname):
out = Image.new('RGB', data.shape[1::-1])
out.putdata(map(tuple, data.reshape(-1, 3)))
out.save(fname)
arr2im(touint8(freq), 'freq.png')
(Кроме: Замечание FFT-любовника. Подробнее см. Документацию для rfft
, но я использовал модуль Scipy FFTPACK, потому что его rfft
перемежает реальные и мнимые компоненты одного пикселя в виде двух смежных реальных значений, гарантируя, что вывод для 2D-изображения любого размера (даже vs odd, width vs height). Это контрастирует с Num44's numpy.fft.rfft2
, который, поскольку он возвращает сложные данные размером width/2+1
от height/2+1
, заставляет вас иметь дело с одним дополнительным столбцом/столбцом и иметь дело с обратным перемежающимся комплексом к реальности. Кому нужна эта хлопот для этой заявки.)
Результаты. Учитывая ввод имени test.png
:
этого фрагмент производит следующий вывод (глобальная мин/макс пересчитаны и квантуется 0-255):
И широкие масштабы:
На этом частотном изображении компонент частоты постоянного тока (0 Гц) находится в верхнем левом углу, а частоты движутся выше, когда вы идите вправо и вниз.
Теперь давайте посмотрим, что произойдет, когда вы манипулируете этим изображением несколькими способами. Вместо этого тестового изображения, давайте использовать cat photo.
Я сделал несколько масок изображений в Gimp, которые я затем загрузить в Python и умножить частотное изображение с, чтобы увидеть, какой эффект маска имеет на изображении.
Вот код:
# Make frequency-image of cat photo
freq = im2freq(np.array(Image.open('cat.jpg')))
# Load three frequency-domain masks (DSP "filters")
bpfMask = np.array(Image.open('cat-mask-bpfcorner.png')).astype(float)/255
hpfMask = np.array(Image.open('cat-mask-hpfcorner.png')).astype(float)/255
lpfMask = np.array(Image.open('cat-mask-corner.png')).astype(float)/255
# Apply each filter and save the output
arr2im(touint8(freq2im(freq * bpfMask)), 'cat-bpf.png')
arr2im(touint8(freq2im(freq * hpfMask)), 'cat-hpf.png')
arr2im(touint8(freq2im(freq * lpfMask)), 'cat-lpf.png')
Вот фильтра низких частот маска слева, и справа, результат нажмите, чтобы увидеть полное разрешение изображения:
В маске черный = 0,0, белый = 1,0. Таким образом, низкие частоты сохраняются здесь (белые), а высокие - заблокированы (черные). Это размывает изображение за счет ослабления высоких частот. Фильтры нижних частот используются повсюду, в том числе при уничтожении («понижающей дискретизации») изображения (хотя они будут формироваться гораздо более тщательно, чем я рисую в Gimp).
Это полосовой фильтр , в котором сохранены самые низкие частоты (см. Этот бит белого в верхнем левом углу?) И высокие частоты, но средние частоты блокируются. Довольно странно!
Вот высоких частот фильтр, где верхний левый угол, который был оставлен белым в вышеприведенных масках затемнен:
Это как edge- обнаружения.
Постскриптум. Кто-то, сделайте webapp, используя эту технику, которая позволяет нарисовать маски и применить их к изображению в режиме реального времени !!!
Если у вас есть изображение, я бы предложил вам использовать 'fft2' для 2d дискретного преобразования Фурье http://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.fft2.html – giosans
Я думаю, что вопрос имеет большую проблему [XY] (http://meta.stackexchange.com/a/66378/262011). Скажите, пожалуйста, что вы * действительно пытаетесь сделать *. Есть ли определенный алгоритм, который вы хотите реализовать? Кроме того, вы можете показать нам пример изображения и то, что производит FFT Gimp (что вы хотите попробовать и произвести на Python)? –
Не могли бы вы также поделиться кодом, который сохраняет ваш FFT в качестве изображения? – Vovanrock2002