简体   繁体   English

使用fft2重塑整形RGB滤镜

[英]Using fft2 with reshaping for an RGB filter

I want to apply a filter on an image, for example, blurring filter [[1/9.0, 1/9.0, 1/9.0], [1/9.0, 1/9.0, 1/9.0], [1/9.0, 1/9.0, 1/9.0]] . 我想在图像上应用滤镜,例如,模糊滤镜[[1/9.0, 1/9.0, 1/9.0], [1/9.0, 1/9.0, 1/9.0], [1/9.0, 1/9.0, 1/9.0]]

Also, I'd like to use the approach that convolution in Spatial domain is equivalent to multiplication in Frequency domain. 此外,我想使用空间域中的卷积等效于频域中的乘法的方法。

So, my algorithm will be like. 所以,我的算法就像。

  1. Load Image. 加载图片。
  2. Create Filter. 创建过滤器。
  3. convert both Filter & Image to Frequency domains. 将过滤器和图像转换为频域。
  4. multiply both. 两者相乘。
  5. reconvert the output to Spatial Domain and that should be the required output. 将输出重新转换为空间域,这应该是所需的输出。

The following is the basic code I use, the image is loaded and displayed as cv.cvmat object. 以下是我使用的基本代码,图像被加载并显示为cv.cvmat对象。

Image is a class of my creation, it has a member image which is an object of scipy.matrix and toFrequencyDomain(size = None) uses spf.fftshift(spf.fft2(self.image, size)) where spf is scipy.fftpack and dotMultiply(img) uses scipy.multiply(self.image, image) Image是我的一个类,它有一个成员图像,它是scipy.matrix的对象, toFrequencyDomain(size = None)使用spf.fftshift(spf.fft2(self.image, size)) ,其中spfscipy.fftpackdotMultiply(img)使用scipy.multiply(self.image, image)

f = Image.fromMatrix([[1/9.0, 1/9.0, 1/9.0],
          [1/9.0, 1/9.0, 1/9.0],
          [1/9.0, 1/9.0, 1/9.0]])
lena = Image.fromFile("Test/images/lena.jpg")
print lena.image.shape
lenaf = lena.toFrequencyDomain(lena.image.shape)
ff = f.toFrequencyDomain(lena.image.shape)
lenafm = lenaf.dotMultiplyImage(ff)
lenaff = lenafm.toTimeDomain()
lena.display()
lenaff.display()

So, the previous code works pretty well, if I told OpenCV to load the image via GRAY_SCALE. 所以,如果我告诉OpenCV通过GRAY_SCALE加载图像,前面的代码效果很好。

However, if I let the image to be loaded in color ... lena.image.shape will be (512, 512, 3) .. 但是,如果我让图像加载颜色... lena.image.shape将是(512, 512, 3) lena.image.shape (512, 512, 3) ..

so, it gives me an error when using scipy.fttpack.ftt2 saying "When given, Shape and Axes should be of same length" . 因此,当使用scipy.fttpack.ftt2"When given, Shape and Axes should be of same length"时,它会给我一个错误。

What I tried next was converted my filter to 3-D .. as 我接下来尝试的是将我的过滤器转换为3-D .. as

[[[1/9.0, 1/9.0, 1/9.0], 
  [1/9.0, 1/9.0, 1/9.0], 
  [1/9.0, 1/9.0, 1/9.0]],
 [[1/9.0, 1/9.0, 1/9.0], 
  [1/9.0, 1/9.0, 1/9.0], 
  [1/9.0, 1/9.0, 1/9.0]],
 [[1/9.0, 1/9.0, 1/9.0], 
  [1/9.0, 1/9.0, 1/9.0], 
  [1/9.0, 1/9.0, 1/9.0]]]

And, not knowing what the axes argument do, I added it with random numbers as (-2, -1, -1), (-1, -1, -2), .. etc. until it gave me the correct filter output shape for the dotMultiply to work. 并且,不知道轴参数是做什么的,我用随机数添加它(-2, -1, -1), (-1, -1, -2), .. etc.直到它给了我正确的过滤器dotMultiply的输出形状可以工作。

But, of course it wasn't the correct value. 但是,当然这不是正确的价值。 Things were totally worse. 事情变得更糟。

My final trial, was using fft2 function on each of the components 2-D matrices, and then re-making the 3-D one, using the following code. 我的最终试验是在每个组件2-D矩阵上使用fft2函数,然后使用以下代码重新制作3-D矩阵。

# Spiltting the 3-D matrix to three 2-D matrices.
for i, row in enumerate(self.image):
            r.append(list())
            g.append(list())
            b.append(list())
            for pixel in row:
                r[i].append(pixel[0])
                g[i].append(pixel[1])
                b[i].append(pixel[2])
        rfft = spf.fftshift(spf.fft2(r, size)) 
        gfft = spf.fftshift(spf.fft2(g, size)) 
        bfft = spf.fftshift(spf.fft2(b, size))
        newImage.image = sp.asarray([[[rfft[i][j], gfft[i][j], bfft[i][j]] for j in xrange(len(rfft[i]))] for i in xrange(len(rfft))] )
        return newImage

Any help on what I made wrong, or how can I achieve that for both GreyScale and Coloured pictures. 我做错了什么的帮助,或者我如何实现GreyScale和彩色图片。

最简单的解决方案是将图像分割成单独的r / g / b图像并独立过滤每个图像。

You are headed in the right direction at the end where you split the 3D matrix into three 2D matrices. 在最后,您将3D矩阵分成三个2D矩阵,从而朝着正确的方向前进。 Here is how I would do it - obviously this is untested (I don't have your Image class, etc.), but it should give you a good start: 这是我将如何做到的 - 显然这是未经测试的(我没有你的Image类等),但它应该给你一个良好的开端:

for i, channel in enumerate(self.image):
    channel_ = spf.fftshift(spf.fft2(channel)) # take FFT of each channel (r,g,b) separately
    channel_ = scipy.multiply(channel_,ff) # multiply each channel by the filter (freq. domain)
    filtered_image[:][:][i] = spf.fftshift(spf.ifft2(channel_)) # inverse FFT each channel separately

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM