我在Python中使用FFT实现了一个问题.我有完全奇怪的结果.好吧,我想打开图像,获取RGB中每个像素的值,然后我需要在它上面使用fft,然后再次转换为图像.
我的步骤:
1)我正在使用Python中的PIL库打开图像
from PIL import Image im = Image.open("test.png")
2)我得到了像素
pixels = list(im.getdata())
3)我将每个像素分成r,g,b值
for x in range(width): for y in range(height): r,g,b = pixels[x*width+y] red[x][y] = r green[x][y] = g blue[x][y] = b
4).我们假设我有一个像素(111,111,111).并在所有红色值上使用fft
red = np.fft.fft(red)
然后:
print (red[0][0], green[0][0], blue[0][0])
我的输出是:
(53866+0j) 111 111
我认为这是完全错误的.我的图像是64x64,而来自gimp的FFT完全不同.实际上,我的FFT只给出了具有巨大值的数组,这就是为什么我的输出图像是黑色的.
你知道问题出在哪里吗?
[编辑]
我按照建议改变了
red= np.fft.fft2(red)
然后我扩展它
scale = 1/(width*height) red= abs(red* scale)
而且,我只得到黑色图像.
[EDIT2]
好的,让我们拍一张照片.
假设我不想打开它并保存为灰度图像.所以我这样做.
def getGray(pixel): r,g,b = pixel return (r+g+b)/3 im = Image.open("test.png") im.load() pixels = list(im.getdata()) width, height = im.size for x in range(width): for y in range(height): greyscale[x][y] = getGray(pixels[x*width+y]) data = [] for x in range(width): for y in range(height): pix = greyscale[x][y] data.append(pix) img = Image.new("L", (width,height), "white") img.putdata(data) img.save('out.png')
在此之后,我得到了这张照片 ,没关系.所以现在,我想在我将它保存到新图像之前对我的图像进行fft,所以我就是这样做的
scale = 1/(width*height) greyscale = np.fft.fft2(greyscale) greyscale = abs(greyscale * scale)
加载后.保存到文件后,我有.所以让我们现在尝试使用gimp打开test.png并使用FFT过滤器插件.我收到这张图片,这是正确的
我该怎么办呢?
好问题.我从来没有听说过它,但Gimp Fourier插件似乎很整洁:
一个简单的插件,可以对您的图像进行傅立叶变换.这个插件的主要优点是能够在GIMP中使用转换后的图像.您可以在傅立叶空间中绘制或应用滤波器,并使用逆FFT获得修改后的图像.
这个想法 - 对频域数据进行Gimp风格的操作并转换回图像 - 非常酷!尽管多年来使用FFT,但我从未考虑过这样做.不要乱用Gimp插件和C可执行文件和丑陋,让我们用Python做到这一点!
警告.我尝试了很多方法来做到这一点,试图从原始输入图像中获得接近输出Gimp Fourier图像(带有莫尔图案的灰色)的东西,但我根本不能.Gimp图像在图像中间看起来有些对称,但它不是垂直或水平翻转,也不是转置对称的.我希望插件能够使用真正的2D FFT将H×W图像转换为频域中的实数值数据的H×W阵列,在这种情况下,不存在对称性(它只是 - 对于像图像这样的实值输入,它是共轭对称的复数FFT.所以我放弃了尝试逆向工程Gimp插件正在做什么,看看我是如何从头开始做的.
代码.非常简单:读取图像,应用scipy.fftpack.rfft
前两个维度获得"频率图像",重新缩放到0-255,然后保存.
请注意这与其他答案有何不同!没有灰度 - 2D实际到FFT在所有三个通道上独立发生.没有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-lover geek note.请查看文档以rfft
获取详细信息,但我使用了Scipy的FFTPACK模块,因为它将rfft
单个像素的实部和虚部交错为两个相邻的实数值,保证了任意大小的2D图像的输出(即使是奇数,宽度与高度)也将被保留.这与Numpy相反numpy.fft.rfft2
,因为它返回大小width/2+1
的复杂数据height/2+1
,迫使你处理一个额外的行/列并处理复杂到真实的自我交织谁需要为这个应用程序麻烦.)
结果.给定输入命名test.png
:
此代码段产生以下输出(全局最小值/最大值已重新调整并量化为0-255):
并升级:
在此频率图像中,DC(0 Hz频率)分量位于左上角,频率随着向右和向下移动而变高.
现在,让我们看看当您以几种方式操作此图像时会发生什么.而不是这个测试图像,让我们使用猫照片.
我在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中绘制的要小得多).
这是一个带通滤波器,其中保留了最低频率(见左上角的白色位?)和高频,但中频频率被阻挡.相当奇怪!
这是一个高通滤波器,上面掩模中左上角的左上角被涂黑:
这就是边缘检测的工作原理.
后记.有人,使用这种技术制作一个webapp,让你绘制蒙版并将它们实时应用到图像中!