3
$\begingroup$

I have the following image: img = Import["https://i.imgur.com/Peu6mwd.png"]

Each column shows the y coordinate of some objects (each row is 0.012 mm apart) and the horizontal coordinate corresponds to the time (one column is 1/35 sec). One can see a general drift from top to bottom with time.

Expressed in plot with axes this is:

enter image description here

I want to display an image showing the FFT amplitudes vs. frequency for each y coordinate.

My code is the following:

img = Import["https://i.imgur.com/Peu6mwd.png"];

{dimx, dimy} = ImageDimensions[img]; 

dy = 0.012; 
dt = 1/35; 

fftData = Abs[Fourier[Flatten@ImageData@ImageTake[img, {#, #}, {0, All}], 
     FourierParameters -> {-1, 1}]] & /@ Range[dimy]; 

fftImg = 
 ImageTake[Image@Rescale[fftData, {0.00001, 0.005}], 
  All, {1, dimx/2}]; 

Graphics[
 Inset[Colorize[fftImg, ColorFunction -> "Rainbow"], Scaled[{.5, .5}],
   Automatic, Scaled[1]], Frame -> True, 
 FrameLabel -> {{"y (mm)", ""}, {"f (Hz)", ""}}, 
 PlotRange -> {{0, 35/2}, {0, dimy*dy}}, 
 AspectRatio -> ImageAspectRatio@fftImg]

which gives:

enter image description here

Do you know a better solution especially to replace the calculation of fftData?. IDL e.g. allows to call the FFT with dimension=1. I did not find any integrated mathematica function.

$\endgroup$
  • 3
    $\begingroup$ "Better" in what way? Faster? Smaller? More colors? Something else? What is the metric for "Better" in your context? $\endgroup$ – Eric Towers Nov 30 '16 at 17:14
  • 1
    $\begingroup$ I don't think you need ImageTake. Just use Fourier /@ ImageData[img] to transform every row in your image or Transpose[Fourier /@ Transpose[ImageData[img]]] to transform every column. (I have no idea what the rest of the code does.) $\endgroup$ – Niki Estner Nov 30 '16 at 20:04
  • 1
    $\begingroup$ Use Map. fft=Rescale[Abs[Fourier[#,FourierParameters->{-1,1}]&/@data][[All,1;;Floor[dimx/2]]],{0.00001,0.005}]; Colorize[Image[fft],ColorFunction->"Rainbow"] $\endgroup$ – Julien Kluge Nov 30 '16 at 20:32
3
$\begingroup$

Here's a way that's pretty close to your approach:

img = Import["https://i.imgur.com/Peu6mwd.png"];
imgData = ImageData[img];
imgDims = Dimensions[imgData];
all = Table[fft = Abs[Fourier[imgData[[i]]]]; fft[[1]] = 0;
   fft[[1 ;; 50]], {i, 1, imgDims[[1]]}];
MatrixPlot[all, AspectRatio -> 1/2] // ImageAdjust

enter image description here

Each row shows the FFT of the corresponding row of the image. This sets the first coefficient to zero because it was large and made the details harder to see. It also plots just the first 50 terms because after about 100 there is not much to see.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you, this is very nice solution. $\endgroup$ – mrz Dec 1 '16 at 0:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.