OpenWave #9 : Measuring significant wave height in the frequency domain


The last post looked at two time domain measurements of significant wave height, the highest 3rd calculation and the 4 times the standard deviation measurement.

It turns out that the standard deviation measurement can also be made in the frequency domain. This is because the variance of a time domain signal is equal to the area under the power-spectral density curve.

The first step of the measurement is to start out with time domain surface elevation data:


Perform a fourier transform on the data to get the frequency content:

Then convert the FFT data to a power-spectral distribution :

The area under this PSD curve will equal the variance of the original time domain signal. Standard deviation is just the square root of the variance so signinificant wave height can easily be calculated from here. The calculation would be:

4*sqrt(area under psd curve).

An example of this calculation in Matlab is available on the OpenWave Github repo. The script is called sig_wave_ex2.m:

%Generates simulated ocean elavation data
%Calculates significant wave height in the time domain and the freq domain
%(Area under PSD curve is equal to variance of time domain signal)

num_waves = 100; %number of sine waves combined to make simulated wave data
fs = 10; %sample rate
stoptime = 40; %signal duration in seconds
sample_length = (fs*stoptime)+1;

t = (0:dt:stoptime)'; % seconds

S = oceanWaveSim(num_waves, 1, fs, stoptime); %Generate simulated ocean surface displacement data
psd_area = psd_test(S, fs); %Get area under power-spectral distribution curve

fprintf('Elevation data signal variance = %0.2f\n',var(S));
fprintf('PSD area under curve = %0.2f\n',psd_area);

fprintf('Significant wave height (time domain calc) = %0.2f\n',4*sqrt(var(S)));
fprintf('Significant wave height (freq domain calc) = %0.2f\n',4*sqrt(psd_area));

%plot time domain ocean surface displacement signal


6 thoughts on “OpenWave #9 : Measuring significant wave height in the frequency domain

  1. Hi Shane,
    I have browsed through your project and I really appreciate the detail you’ve gone into explaining the process. I am curious, with the processing power of the BNO055, would it be possible to ran double integration and fft to obtain real time displacement from the IMU without going through an arduino only. I am not familiar with MATLAB and was thinking of playing around with a similar project since I’ve got one of those IMU’s available.


    1. Hey Rich,

      Yes I’m sure that it is possible. I started out with Matlab in an attempt to figure out what kind of algorithm would work best with the intention of then moving to a microcontroller. Life got in the way and I never for around to that. One of the main reasons I even started this project is I used to work in the marine data industry. One day my manager plops a new sensor on my desk and asked my to write a driver for it. He told me it cost ten thousand euros and to be careful with it. It was an ocean wave sensor. I cracked it open to take a look at the PCB inside and they had the microcontroller from a teensy (cant recall which one, 2 or 3 probably) and an accelerometer. It was then that I realised that even though these wave sensors sell for thousands of euros, the hardware they use is relatively cheap. The magic sauce is in the algorithms. I would love to see an open-source open wave sensor out there.

      There is a group of guys in Spain that made an ocean wave sensor using an Arduino and an accelerometer, they wrote a paper about it which you can see here:
      Unfortunately, they did not open-source the algorithm and in fact, I believe they went on to turn that project into a commercial venture! So if you crack the code…do the world a favour and share the algo…there should be an ocean wave sensor on every data buoy in the world and that will happen if they become dirt cheap. Huge benefits for real-time ocean wave data which is very useful for emergency services, fishermen etc – your invention could literally save a life if it becomes ubiquitous.

      Best of luck,

    1. Hi Mikhail,

      Apologies I didn’t reply to your other message. That looks very cool. I have never used a kalman filter myself so I’m struggling to understand exactly how your code works. I have actually started playing around with the openwave project again and am trying to get it working on a microcontroller (Esp32). Maybe with the help of ChatGPT I’ll be able to use some of the same techniques as you. I think to start off with if I could get just significant wave height (without direction) working that would be a great starting point. Then I would move on to wave height with direction info.

      Interesting point about assuming the average displacement is 0. I can’t see exactly how that feeds into your code but it seems like it unlocks some novel way of calculating wave height. The code for that section is quite short aswell so perhaps it is more microcontroller friendly too.

      1. I’ve made reference data. Generated it in python.
        Without noise. With noise.
        With bias.
        With noise and bias.

        And fed acceleration data only into algorithm. And compared how algorithm results of displacement score against actual displacement from reference data. To make sure algorithm converges.
        Also with different unknown initial velocity and displacement.

      2. I used that article mentioned for keeping double integral from drifting. Third integral is assumed zero in observation matrix for Kalman filter.
        You can see that it is third intergral in transition matrix.

        I’ve coded everything in python. Then moved parts into c++ and rust.

        Unfortunately my boat doesn’t have a speed through water sensor and that’s needed to calculate drift and set (direction of current).

        Needed for Doppler formula to measure actual wave frequency from observed from moving boat.

        If your buoy is freely drifting you can assume it moves with water.

        Makes things much easier.
        It’s not hard to code that into esp32 microcontroller. It has enough power. (About 5 times faster than pentium one, people manages to run windows 3.0 on it with byte code emulation).

Leave a Reply

%d bloggers like this: