Using fft2 with reshaping for an RGB filter
Posted
by
Mahmoud Aladdin
on Stack Overflow
See other posts from Stack Overflow
or by Mahmoud Aladdin
Published on 2012-10-12T14:50:11Z
Indexed on
2012/10/12
15:37 UTC
Read the original article
Hit count: 269
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]]
.
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.
- Load Image.
- Create Filter.
- convert both Filter & Image to Frequency domains.
- multiply both.
- 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.
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)
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.
However, if I let the image to be loaded in color ...
lena.image.shape
will be (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"
.
What I tried next was converted my filter to 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.
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.
# 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.
© Stack Overflow or respective owner