comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: FFT and ROTATE
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: FFT and ROTATE [message #62326] Fri, 05 September 2008 14:04 Go to next message
wheinz is currently offline  wheinz
Messages: 2
Registered: September 2008
Junior Member
Thanks for the suggestions. I am still confused by a few things, but
with Wox's code I think I can clarify my question. The problem is that
although Wox's code shows that the FFT of the rotated image and the
rotated FFT of the original image give you back images that look like
the original when inverse -transfored, the values of the coefficients
in those two FFTs are not the same. I added some print statements to
Wox's code to show what is confusing me.

pro rotFFTtest3
;;load an image
fn = filepath('md1107g8a.jpg',SUBDIRECTORY='examples/data')
image=bytarr(251,251)
image90=bytarr(251,251)
image[0,0]= read_image(fn)
image90[0,0] = rotate(read_image(fn),1)

;display the images
window,0
tvscl,image,0
tvscl,image90,1
n = size(image,/dim)
nfreq=n/2+1 ; # positive freq in each dim
nfreq_m=nfreq-1-(~(n mod 2)) ; # negative fequencies in each dim

;;take fft of image
f = fft(image)

;;shift it
f = shift(f,-nfreq[0],-nfreq[1])

;;rotate the fft 90 degrees
f90_1 = rotate(f,1)

;;shift it back
f90_1 = shift(f90_1,nfreq[0],nfreq[1])
;;take the fft of image90 -- the rotated image
f90_2 = fft(image90)

;;**********new code to print sorted values of coefficients**********
;;get the real parts of the ffts
fr =real_part(f)
f90_1r = real_part(f90_1)
f90_2r = real_part(f90_2)

;;now we look at the set of real coefficiencts of each fft
sf = fr[sort(fr)]
s1 = f90_1r[sort(f90_1r)]
s2 = f90_2r[sort(f90_2r)]

print,'The sorted list of real coefficients.'
print,' fft(image):',sf[0:4]
print,' rotated fft:',s1[0:4]
print,'fft(image90):',s2[0:4]

;;**********end new code to print sorted values of
coefficients**********


tvscl,fft(f90_1,/inverse),2
tvscl,fft(f90_2,/inverse),5

end

The program prints the following:

IDL> rotFFTtest2
The sorted list of real coefficients.
fft(image): -36.3499 -36.3499 -26.5806 -26.5806
-5.83106
rotated fft: -36.3499 -36.3499 -26.5806 -26.5806
-5.83106
fft(image90): -36.3499 -36.3499 -26.6964 -26.6964
-5.65933

So, you can see that the values differ, and (to answer ken's question)
the differences in the values are greater than the machine's
precision. Here I only printed the real parts, but the same thing
happens with the imaginary parts.

The fact that the inverse transformations return the original image
suggests that there is a phase shift introduced somewhere in the
transform. I can understand that if the array has an even number of
elements in x or y, then a rotation forces a translation of the
pixels. But an array with an odd number of elements in x and y should
not, especially if we are only looking at 90 degree rotations.

Why aren't the sorted lists of the real parts of the coefficients from
the rotated fft and the fft of the rotated image equal?

The article Vince linked to states that different implementations of
the FFT use different indexing and normalization approaches. Is it
possible that these differences could come from whatever scheme IDL
uses for its FFT?

Thanks,
Will
Re: FFT and ROTATE [message #62357 is a reply to message #62326] Thu, 04 September 2008 06:37 Go to previous messageGo to next message
Vince Hradil is currently offline  Vince Hradil
Messages: 574
Registered: December 1999
Senior Member
On Sep 3, 5:20 pm, whe...@gmail.com wrote:
> Hello,
>
> I have been wrestling with the FFT and ROTATE functions recently.  One
> of the properties of the Fourier transform is that the transform of a
> rotated object is equal to the rotation of the transform of the
> unrotated object.  To test this in IDL, I took the FFT of an nxn array
> (called image) and the FFT of that array rotated 90 degrees, image90 =
> ROTATE(image,1).  Then, I sorted the real and imaginary parts of the
> coefficients of the results of the FFTs and compared the sorted
> values.  I expected that the sorted list of real parts from the FFT of
> the original and rotated arrays would be identical, and that the same
> would be true for the imaginary parts.  This is not the case. The sets
> of the magnitudes of the coefficients are equal, as expected.
>
> I understand that edge effects can play a role, but when I rotate a
> square array by 90 degrees, I expect that the sets of real and
> imaginary values that define the coefficients to be equal.
>
> Is this a consequence of how the FFT is calculated -- rows first then
> columns or vice versa?  Or is there something else going on?  Any help
> or suggestions will be greatly appreciated.
>
> Here is some code I am using to try to wrap my head around this.
>
> Thanks,
> Will
>
> pro rotFFTtest
>   ;;load an image
>   fn = filepath('md1107g8a.jpg',SUBDIRECTORY='examples/data')
>   image= read_image(fn)
>   image90 = rotate(image,1)
>
>   ;display the images
>   tvscl,image,0
>   tvscl,image90,1
>
>   n = n_elements(image)
>
>   ;;take fft of image, then get the real and imaginary parts
>   f = fft(image)
>   fr = real_part(f)
>   fi = imaginary(f)
>
>   ;;take the fft of image90 then get the real and imaginary parts.
>   f90 = fft(image90)
>   fr90 = real_part(f90)
>   fi90 = imaginary(f90)
>
>   ;;sort and print the real and imaginary parts
>   frs = sort(fr)
>   fr90s = sort(fr90)
>   fis = sort(fi)
>   fi90s = sort(fi90)
>
>   ;;print some of the sorted coefficients
>   print,'fr[frs[[1:4]]',fr[frs[1:4]]
>   print,'fr90[fr90s[[1:4]]',fr90[fr90s[1:4]]
>
> ;print all of the sorted coefficients
> ;print,'Real','Real rotated','Imag.','Imag. rotated',FORMAT='(4A17)'
> ;for i = 0L,n-1L do
> print,fr[frs[i]],fr90[fr90s[i]],fi[fis[i]],fi90[fi90s[i]],FO RMAT='(4G17.13)'
>
> end

This might help, too: http://cimss.ssec.wisc.edu/~paulv/fft/fft_comparison.html
Re: FFT and ROTATE [message #62358 is a reply to message #62357] Thu, 04 September 2008 04:55 Go to previous messageGo to next message
Wox is currently offline  Wox
Messages: 184
Registered: August 2006
Senior Member
On Wed, 3 Sep 2008 15:20:19 -0700 (PDT), wheinz@gmail.com wrote:

> Hello,
>
> I have been wrestling with the FFT and ROTATE functions recently. One
> of the properties of the Fourier transform is that the transform of a
> rotated object is equal to the rotation of the transform of the
> unrotated object. To test this in IDL, I took the FFT of an nxn array
> (called image) and the FFT of that array rotated 90 degrees, image90 =
> ROTATE(image,1). Then, I sorted the real and imaginary parts of the
> coefficients of the results of the FFTs and compared the sorted
> values. I expected that the sorted list of real parts from the FFT of
> the original and rotated arrays would be identical, and that the same
> would be true for the imaginary parts. This is not the case. The sets
> of the magnitudes of the coefficients are equal, as expected.



First of all, care must be taken when rotating the fourier transform.
Check IDL help on this: you have to shift with half the image size in
both directions. I also noticed that it only works with uneven image
sizes (i.e. rotation around the center pixel). Anyway, check the code
below:


pro rotFFTtest
;;load an image
fn = filepath('md1107g8a.jpg',SUBDIRECTORY='examples/data')
image=bytarr(251,251)
image[0,0]= read_image(fn)
image90 = rotate(image,1)

;display the images
window,0
tvscl,image,0
tvscl,image90,1

n = size(image,/dim)
nfreq=n/2+1 ; # positive freq in each dim
nfreq_m=nfreq-1-(~(n mod 2)) ; # negative fequencies in each dim

;;take fft of image, then get the real and imaginary parts
f = fft(image)
f = shift(f,-nfreq[0],-nfreq[1])
f90_1 = rotate(f,1)
f90_1 = shift(f90_1,nfreq[0],nfreq[1])

;;take the fft of image90 then get the real and imaginary parts.
f90_2 = fft(image90)

tvscl,fft(f90_1,/inverse),2
tvscl,fft(f90_2,/inverse),3
end
Re: FFT and ROTATE [message #62360 is a reply to message #62358] Wed, 03 September 2008 23:11 Go to previous messageGo to next message
Kenneth P. Bowman is currently offline  Kenneth P. Bowman
Messages: 585
Registered: May 2000
Senior Member
In article
<0473bd21-6928-45b9-9e59-56a8aa5ab9df@r15g2000prh.googlegroups.com>,
wheinz@gmail.com wrote:

> Hello,
>
> I have been wrestling with the FFT and ROTATE functions recently. One
> of the properties of the Fourier transform is that the transform of a
> rotated object is equal to the rotation of the transform of the
> unrotated object. To test this in IDL, I took the FFT of an nxn array
> (called image) and the FFT of that array rotated 90 degrees, image90 =
> ROTATE(image,1). Then, I sorted the real and imaginary parts of the
> coefficients of the results of the FFTs and compared the sorted
> values. I expected that the sorted list of real parts from the FFT of
> the original and rotated arrays would be identical, and that the same
> would be true for the imaginary parts. This is not the case. The sets
> of the magnitudes of the coefficients are equal, as expected.
>
> I understand that edge effects can play a role, but when I rotate a
> square array by 90 degrees, I expect that the sets of real and
> imaginary values that define the coefficients to be equal.
>
> Is this a consequence of how the FFT is calculated -- rows first then
> columns or vice versa? Or is there something else going on? Any help
> or suggestions will be greatly appreciated.

Are the differences of the order of the machine precision?

Ken Bowman
Re: FFT and ROTATE [message #62414 is a reply to message #62326] Sun, 07 September 2008 05:59 Go to previous message
Kenneth P. Bowman is currently offline  Kenneth P. Bowman
Messages: 585
Registered: May 2000
Senior Member
In article
<0fc5b913-ae5d-4a1c-afb3-ba1184f174ce@c58g2000hsc.googlegroups.com>,
wheinz@gmail.com wrote:

> Thanks for the suggestions. I am still confused by a few things, but
> with Wox's code I think I can clarify my question. The problem is that
> although Wox's code shows that the FFT of the rotated image and the
> rotated FFT of the original image give you back images that look like
> the original when inverse -transfored, the values of the coefficients
> in those two FFTs are not the same. I added some print statements to
> Wox's code to show what is confusing me.

I find that the only way to really understand FFTs is to work with a
example where I know the answer exactly. I suggest that you create
a highly simplified image by combining a few harmonic components
in the x- and y-directions, then look at the FFTs with and
without rotation.

For example

f(x,y) = sin(2 * !pi * x) # sin(4 * !pi * y)

where x = y = FINDGEN(16)/16.0

You can use try different (distinct) sine and cosine components
to investigate how they translate into real and imaginary
parts.

Also, you can look at dimensions sizes that are not powers of 2.

Ken Bowman
Re: FFT and ROTATE [message #62416 is a reply to message #62326] Sat, 06 September 2008 04:47 Go to previous message
Wox is currently offline  Wox
Messages: 184
Registered: August 2006
Senior Member
On Fri, 5 Sep 2008 14:04:11 -0700 (PDT), wheinz@gmail.com wrote:

> The fact that the inverse transformations return the original image
> suggests that there is a phase shift introduced somewhere in the
> transform. I can understand that if the array has an even number of
> elements in x or y, then a rotation forces a translation of the
> pixels. But an array with an odd number of elements in x and y should
> not, especially if we are only looking at 90 degree rotations.
>
> Why aren't the sorted lists of the real parts of the coefficients from
> the rotated fft and the fft of the rotated image equal?

Maybe it has something to do with this (see rotation and edge
effects):
http://www.cs.unm.edu/~brayer/vision/fourier.html
There you see that the modulus is also different when you compare
mod(fft(rot(image))) with mod(rot(fft(image))). Apparently the fact
that the moduli were the same in your case, was because you rotated 90
degrees. See below for rotating 45 degrees. Someone with a better
knowledge of fourier transformation can probably explain better. So I
don't think it's a rounding problem, but a problem that comes with
images having a finite size.


pro rotFFTtest3
;;make image
image=rebin(bytscl(cos(!pi/18.*findgen(355))),355,355,/sampl e)
image90 = rot(image,-45)
i0=52
i1=i0+250
image=image[i0:i1,i0:i1]
image90=image90[i0:i1,i0:i1]

;display the images
window,0
tvscl,image,0
tvscl,image90,1
n = size(image,/dim)
nfreq=n/2+1 ; # positive freq in each dim
nfreq_m=nfreq-1-(~(n mod 2)) ; # negative fequencies in each dim

;;take fft of image
f = fft(image)

;;shift it
f = shift(f,-nfreq[0],-nfreq[1])

;;rotate the fft 90 degrees
f90_1 = rot(f,45)

;;shift it back
f90_1 = shift(f90_1,nfreq[0],nfreq[1])

;;take the fft of image90 -- the rotated image
f90_2 = fft(image90)

tvscl,fft(f90_1,/inverse),2; fft(rot(fft(image)))
tvscl,fft(f90_2,/inverse),4; fft(fft(rot(image)))

;;phase shift between fft(rot(image)) and rot(fft(image))
f90_1phase=atan(f90_1,/phase)
f90_2phase=atan(f90_2,/phase)
phshift=abs(f90_1phase-f90_2phase)*180/!pi
f90_1mod=abs(f90_1)
f90_2mod=abs(f90_2)
moddiff=abs(f90_1mod-f90_2mod)

window,1
tvscl,shift(moddiff,-nfreq[0],-nfreq[1])<0.1,1
tvscl,shift(phshift,-nfreq[0],-nfreq[1]),0
print,'fft(rot(image)) vs. rot(fft(image))'
print,'Phase shift range (degrees): ',min(phshift),max(phshift)
print,'Modulus diff range: ',min(moddiff),max(moddiff)
end
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: map plotting
Next Topic: block fill image

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 15:16:18 PDT 2025

Total time taken to generate the page: 0.00767 seconds