1
votes

I am developing a little application in Visual Studio 2010 in C# to draw a spectrogram (frequency "heat map").

I have already done the basic things:

  • Cut a rectangular windowed array out of the input signal array
  • Feed that array into FFT, which returns complex values
  • Store magnitude values in an array (spectrum for that window)
  • Step the window, and store the new values in other arrays, resulting in a jagged array that holds every step of windowing and their spectra
  • Draw these into a Graphics object, in color that uses the global min/max values of the heat map as relative cold and hot

The LEFT side of the screenshot shows my application, and on the RIGHT there is a spectrogram for the same input (512 samples long) and same rectangular window with size 32 from a program called "PAST - time series analysis" (https://folk.uio.no/ohammer/past/index.html). My 512 long sample array only consists of integer elements ranging from around 100 to 1400. (Note: the light-blue bar on the very right of the PAST spectrogram is only because I accidentally left an unnecessary '0' element at the end of thats input array. Otherwise they are the same.)

Link to screenshot: https://drive.google.com/open?id=1UbJ4GyqmS6zaHoYZCLN9c0JhWONlrbe3

But I have encountered a few problems here:

  1. The spectrogram seems very undetailed, related to another one that I made in "PAST time series analysis" for reference, and that one looks extremely detailed. Why is that? I know that for an e.g. 32 long time window, the FFT returns 32 elements, the 0. elem is not needed here, the next 32/2 elements have the magnitude values I need. But this means that the frequency "resolution" on the output for a 32 long window is 16. That is exactly what my program uses. But "PAST" program shows a lot more detail. If you look at the narrow lines in the blue background, you can see that they show a nice pattern in the frequency axis, but in my spectrogram that information remains unseen. Why?
  2. In the beginning (windowSize/2) wide window step-band and the ending (windowSize/2) step-band, there are less values for FFT input, thus there is less output, or just less precision. But in the "PAST" program those parts also seem relatively detailed, not just stretched bars like in mine. How can I improve that?
  3. The 0. element of the FFT return array (the so called "DC" element) is a huge number, which is a lot bigger than the sample average, or even its sum. Why is that?
  4. Why are my values (e.g. the maximum that you see near the color bar) so huge? That is just a magnitude value from the FFT output. Why are there different values in the PAST program? What correction should I use on the FFT output to get those values?

Please share your ideas, if you know more about this topic. I am very new to this. I only read first about Fourier transform a little more than a week ago.

Thanks in advance!

2
If you want more frequency resolution in the STFT (short time fourier transform) you need more time steps, meaning that this will reduce your time resolution. You can overlap your time intervals however (effectively an interpolation). The DC you can remove by subtracting the average of all data from your data. Whether you want to retain it is a question outside of programming, it's the physical meaning of your data that you need to think about. Ditto about the colorbar, maybe you didn't remove the DC yet.roadrunner66
Note: I would first develop something like this in a higher level environment (like Matlab,Python Numpy, Mathematica) to figure out the parameters. It will make it easier also to get support for your questions (short code can be posted, image code is canned, so you don't get bogged down in C# implementation question).roadrunner66
Thanks for all the answers! :) My greatest problem was that (because my Y values are all huge) I should have subtracted the mean from the whole signal array before any processing. Now I have done that. I also use now maximum amount of overlap, and added zero padding, which helped very much in emphasizing details. Also logarithmic colouring is very effective, and shows the close-to-maximum amplitude information better recognizeable. And if I use 32, 64 (or any even number) long windows, the window function has to be like "matlab symmetric": en.wikipedia.org/wiki/Window_function#SymmetryLimeAndConconut

2 Answers

0
votes

To get more smoothness in the vertical axis, zero pad your FFT so that there are more (interpolated) frequency bins in the output. For instance, zero pad your 32 data points so that you can use a 256 point or larger FFT.

To get more smoothness in the horizontal axis, overlap your FFT input windows (75% overlap, or more).

For both, use a smooth window function (Hamming or Von Hann, et.al.), and try wider windows, more than 32 (thus even more overlapped).

To get better coloring, try using a color mapping table, with the input being the log() of the (non zero) magnitudes.

You can also use multiple different FFTs per graph XY point, and decide which to color with based on local properties.

0
votes

Hello LimeAndConconut,

Even though I do not know about PAST, I can provide you with some general information about FFT. Here is an answer for each of your points

1- You are right, a FFT performed on 32 elements returns 32 frequencies (null frequency, positive and negative components). It means that you already have all the information in your data, and PAST cannot get more information with the same 32 sized window. That's why I suspect the data to be interpolated for plotting, but this just visual. Once again PAST cannot create more information than the one you have in your data.

2- Once again I agree with you. On the borders, you have access to less frequency components. You can decide different strategies: not show data at the borders, or extend this data with zero-padding or circular padding

3- The zero element of the FFT should be the sum of your 32 windowed array. You need to check FFT normalization, have a look at the documentation of your FFT function.

4- Once again check the FFT normalization. Since PAST colorbar exhibit negative values, it seems to be plotted in logarithmic scale. This is common usage to use logarithm for plotting data with high dynamics in order to enhance details.