Algorithm for detecting the lowest level of EMG activity? - signal-processing

How, having only data from the EMG sensor, to determine whether a person is in the REM phase? In other words, I need to detect the lowest level of activity from the sensor's EMG. Well, or at least register the phase change ...
In more detail... I'm going to make a REM phase detector using an EMG (electromyography) sensor. There is already a sketch of the Android application on the github, if you are interested, I can post a link. Although there is still work to be done...)
The device should work based on the fact that in different states of the brain (wakefulness, slow sleep, REM sleep), different levels of activity will be recorded from the sensor. In REM sleep, this activity is minimal.
The Bluetooth sensor is attached to the body before going to bed, the Android program is launched, communicates with the sensor and sends the data read from it to the connected TCP client via WiFi. TCP client - python script running on a nettop. It receives data, and by design should determine in real time whether the current level of activity is the minimum for the entire observation period. If so, the script will tell the server (Android program) to turn on the hint - it can be a vibration on the phone or a fitness bracelet, playing an audio sample through a headphone, light flashes, a slight electric shock =), etc.
Because only one EMG sensor is used, I admit that it will not be possible to catch REM sleep phases with 100% accuracy, but this is not necessary. If the accuracy is 80% - it's already good. For starters, even an algorithm for detecting a change in the current activity level is suitable. - There will be something to experiment with and something to build on.
The problem is with the algorithm. I would not like to use fixed thresholds, because these thresholds will be different for different people, and even for the same person at different times and in different states they will differ. Therefore, I will be glad to ideas and tips from your side.
I found an interesting article "A Self-adaptive Threshold Method for Automatic Sleep Stage Classifi-
cation Using EOG and EMG" (https://www.researchgate.net/publication/281722966_A_Self-adaptive_Threshold_Method_for_Automatic_Sleep_Stage_Classification_Using_EOG_and_EMG):
But there remains incomprehensible, a few points. First, how is the energy calculated (Step 1-4: Energy)?
d = f.read(epoche_seconds*SAMPLE_RATE*2)
if not d:
break
print('epoche#{}'.format(i))
fmt = '<{}H'.format(len(d) // 2)
t = unpack(fmt, d)
d = list(t)
d = np.array(d)
d = d / (1 << 14) # 14 - bits per sample
df=pd.DataFrame({'signal': d, 'id': [x*2 for x in range(len(d))]})
df = df.set_index('id')
d = df.signal
# signal prepare:
d = butter_bandpass_filter(d, lowcut, highcut, SAMPLE_RATE, order=2)
# extract signal futures:
future_iv = np.mean(np.absolute(d))
print('iv={}'.format(future_iv))
future_var = np.var(d)
print('var={}'.format(future_var))
ws = 6
df = pd.DataFrame({'signal': np.absolute(d)})
future_e = df.rolling(ws).sum()[ws-1:].max().signal
print('E={}'.format(future_e))
-- Will it be right?
Secondly, can someone elaborate on this:
Step 2-1: normalized processed
EMG and EOG feature vectors were processed with
normalized function before involved into classification
steps. Feature vectors were normalized as the follow-
ing function (4):
Where, Xmax and Xmin were got by following
steps: first, sort x(i) vector, and set window length N
represents 50 ; then compare 2Nk (k, values from
10 to 1) with the length of x(i) , if 2Nk is bigger
than the later one, reduce k , until 2Nk is lower than
the length of x(i). If length of x(i) is greater than
2Nk, compute the mean of 50 larger values as
Xmax, and the average of 50 smaller values as Xmin.
?

If you are looking for REM (deep sleep); a spectogram will show you intensity and frequency information on a 1 page graph/chart. People of a certain age refer to spectograms as TFFT - the wiki link is... https://en.wikipedia.org/wiki/Spectrogram
Can you input the data into a spectogram display/plot. Use a large FFT window (you probably have hours of data) with a small overlap (15%). I would recommend starting with an FFT window around 1 second.

Related

Creating a phase vocoder with the webaudio API using analyzer and periodic wave

I was wondering if it would be possible to poll the AnalyzerNode from the WebAudio API and use it to construct a PeriodicWave that is synthesized via an OscillatorNode?
My intuition is that something about the difference in amplitudes between analyzer frames can help calculate the right phase for a PeriodicWave, but I'm not sure how to go about implementing it. Any help on the right algorithm to use would be appreciated!
As luck would have it, I was working on a similar project just a few weeks ago. I put together a JSFiddle to explore the idea of reconstructing a phase-randomized version of a waveform using frequency data from an AnalyserNode. You can find that experiment here:
https://jsfiddle.net/mattdiamond/w4u7x8zk/
Here's the code that takes in the frequency data output from an AnalyserNode and generates a PeriodicWave:
function generatePeriodicWave(freqData) {
const real = [];
const imag = [];
freqData.forEach((x, i) => {
const amp = fromDecibels(x);
const phase = getRandomPhase();
real.push(amp * Math.cos(phase));
imag.push(amp * Math.sin(phase));
});
return context.createPeriodicWave(real, imag);
}
function fromDecibels(x) {
return 10 ** (x / 20);
}
function getRandomPhase() {
return Math.random() * 2 * Math.PI - Math.PI;
}
Since the AnalyserNode converts the FFT amplitude values to decibels, we need to recover those original values first (which we do by simply using the inverse of the formula that was used to convert them to decibels). We also need to provide a phase for each frequency, which we select at random from the range -π to π.
Now that we have an amplitude and phase, we construct a complex number by multiplying the amplitude by the cosine and sine of the phase. This is because the amplitude and phase correspond to a polar coordinate, and createPeriodicWave expects a list of real and imaginary numbers corresponding to Cartesian coordinates in the complex plane. (See here for more information on the mathematics behind this conversion.)
Once we've generated the PeriodicWave, all that's left to do is load it into an OscillatorNode, set the desired frequency, and start the oscillator. You'll notice that the default frequency is set to context.sampleRate / FFT_SIZE (you can ignore the toFixed, that was just for the sake of the UI). This causes the oscillator to play the wave at the same rate as the original samples. Increasing or decreasing the frequency from this value will pitch-shift the audio up or down, respectively.
You'll also notice that I chose 2^15 as the FFT size, which is the maximum size that the AnalyserNode allows. For my purposes -- creating interesting looped drones -- a larger FFT results in a more interesting and less "loopy" drone. (A while back I created a webpage that allowed users to generate drones from much larger FFTs... that experiment utilized a third-party FFT library instead of the AnalyserNode.) I'm not sure if this is the right FFT size for your purposes, but it's something to consider.
Anyway, I think that covers the core of the algorithm. Hope this helps! (And feel free to ask more questions in the comments if anything's unclear.)

3D object position prediction using Kalman filter, variable time period

I'm working on advanced vision system which consist of two static cameras (used for obtaining accurate 3d object location) and some targeting device. Object detection and stereovision modules have been already done. Unfortunately, due to the delay of targeting system it is obligatory to develop a proper prediction module.
I did some tests using Kalman filter but it is working not accurate enough.
kalman = cv2.KalmanFilter(6,3,0)
...
kalman.statePre[0,0] = x
kalman.statePre[1,0] = y
kalman.statePre[2,0] = z
kalman.statePre[3,0] = 0
kalman.statePre[4,0] = 0
kalman.statePre[5,0] = 0
kalman.measurementMatrix = np.array([[1,0,0,0,0,0],[0,1,0,0,0,0],[0,0,1,0,0,0]],np.float32)
kalman.transitionMatrix = np.array([[1,0,0,1,0,0],[0,1,0,0,1,0],0,0,1,0,0,1],[0,0,0,1,0,0],[0,0,0,0,1,0],[0,0,0,0,0,1]],np.float32)
kalman.processNoiseCov = np.array([[1,0,0,0,0,0],[0,1,0,0,0,0],0,0,1,0,0,0],[0,0,0,1,0,0],[0,0,0,0,1,0],[0,0,0,0,0,1]],np.float32) * 0.03
kalman.measurementNoiseCov = np.array([[1,0,0],[0,1,0],0,0,1]],np.float32) * 0.003
I noticed that time periods between two frames are different each time (due to the various detection time).
How could I use last timestamp diff as an input? (Transition matrices?, controlParam?)
I want to determine the prediction time e.g want to predict position of object in 0,5sec or 1,5sec
I could provide example input 3d points.
Thanks in advance
1. How could I use last timestamp diff as an input? (Transition matrices?, controlParam?)
Step size is controlled through prediction matrix. You also need to adjust process noise covariance matrix to control uncertainty growth.
You are using a constant speed prediction model, so that p_x(t+dt) = p_x(t) + v_x(t)·dt will predict position in X with a time step dt (and the same for coords. Y and Z). In that case, your prediction matrix should be:
kalman.transitionMatrix = np.array([[1,0,0,dt,0,0],[0,1,0,0,dt,0],0,0,1,0,0,dt],[0,0,0,1,0,0],[0,0,0,0,1,0],[0,0,0,0,0,1]],np.float32)
I left the process noise cov. formulation as an exercise. Be careful with squaring or not squaring the dt term.
2. I want to determine the prediction time e.g want to predict position of object in 0,5sec or 1,5sec
You can follow two different approaches:
Use a small fixed dt (e.g. 0.02 sec for 50Hz) and calculate predictions in a loop until you reach your goal (e.g. get a new observation from your cameras).
Adjusting prediction and process noise matrices online to the desired dt (0,5 / 1,5 sec in your question) and execute a single prediction step.
If you are asking about how to anticipate the detection time of your cameras, that should be a different question and I am afraid I can't help you :-)

Does FFT neccessary to find peaks and pits on audio files

I'm able to read a wav files and its values. I need to find peaks and pits positions and their values. First time, i tried to smooth it by (i-1 + i + i +1) / 3 formula then searching on array as array[i-1] > array[i] & direction == 'up' --> pits style solution but because of noise and other reasons of future calculations of project, I'm tring to find better working area. Since couple days, I'm researching FFT. As my understanding, fft translates the audio files to series of sines and cosines. After fft operation the given values is a0's and a1's for a0 + ak * cos(k*x) + bk * sin(k*x) which k++ and x++ as this picture
http://zone.ni.com/images/reference/en-XX/help/371361E-01/loc_eps_sigadd3freqcomp.gif
My question is, does fft helps to me find peaks and pits on audio? Does anybody has a experience for this kind of problems?
It depends on exactly what you are trying to do, which you haven't really made clear. "finding the peaks and pits" is one thing, but since there might be various reasons for doing this there might be various methods. You already tried the straightforward thing of actually looking for the local maximum and minima, it sounds like. Here are some tips:
you do not need the FFT.
audio data usually swings above and below zero (there are exceptions, including 8-bit wavs, which are unsigned, but these are exceptions), so you must be aware of positive and negative values. Generally, large positive and large negative values carry large amounts of energy, though, so you want to count those as the same.
due to #2, if you want to average, you might want to take the average of the absolute value, or more commonly, the average of the square. Once you find the average of the squares, take the square root of that value and this gives the RMS, which is related to the power of the signal, so you might do something like this is you are trying to indicate signal loudness, intensity or approximate an analog meter. The average of absolutes may be more robust against extreme values, but is less commonly used.
another approach is to simply look for the peak of the absolute value over some number of samples, this is commonly done when drawing waveforms, and for digital "peak" meters. It makes less sense to look at the minimum absolute.
Once you've done something like the above, yes you may want to compute the log of the value you've found in order to display the signal in dB, but make sure you use the right formula. 10 * log_10( amplitude ) is not it. Rule of thumb: usually when computing logs from amplitude you will see a 20, not a 10. If you want to compute dBFS (the amount of "headroom" before clipping, which is the standard measurement for digital meters), the formula is -20 * log_10( |amplitude| ), where amplitude is normalize to +/- 1. Watch out for amplitude = 0, which gives an infinite headroom in dB.
If I understand you correctly, you just want to estimate the relative loudness/quietness of an audio digital sample at a given point.
For this estimation, you don't need to use FFT. However your method of averaging the signal does not produce the appropiate picture neither.
The digital signal is the value of the audio wave at a given moment. You need to find the overall amplitude of the signal at that given moment. You can somewhat see it as the local maximum value for a given interval around the moment you want to calculate. You may have a moving max for the signal and get your amplitude estimation.
At a 16 bit sound sample, the sound signal value can go from 0 up to 32767. At a 44.1 kHz sample rate, you can find peaks and pits of around 0.01 secs by finding the max value of 441 samples around a given t moment.
max=1;
for (i=0; i<441; i++) if (array[t*44100+i]>max) max=array[t*44100+i];
then for representing it on a 0 to 1 scale you (not really 0, because we used a minimum of 1)
amplitude = max / 32767;
or you might represent it in relative dB logarithmic scale (here you see why we used 1 for the minimum value)
dB = 20 * log10(amplitude);
all you need to do is take dy/dx, which can getapproximately by just scanning through the wave and and subtracting the previous value from the current one and look at where it goes to zero or changes from positive to negative
in this code I made it really brief and unintelligent for sake of brevity, of course you could handle cases of dy being zero better, find the 'centre' of a long section of a flat peak, that kind of thing. But if all you need is basic peaks and troughs, this will find them.
lastY=0;
bool goingup=true;
for( i=0; i < wave.length; i++ ) {
y = wave[i];
dy = y - lastY;
bool stillgoingup = (dy>0);
if( goingup != direction ) {
// changed direction - note value of i(place) and 'y'(height)
stillgoingup = goingup;
}
}

How to calculate distance from Wifi router using Signal Strength?

I would like to calculate the exact location of a mobile device inside a building ( so no GPS access)
I want to do this using the signal strength(in dBm) of at least 3 fixed wifi signals(3 fixed routers of which I know the position)
Google already does that and I would like to know how they figure out the exact location based on the this data
Check this article for more details : http://www.codeproject.com/Articles/63747/Exploring-GoogleGears-Wi-Fi-Geo-Locator-Secrets
FSPL depends on two parameters: First is the frequency of radio signals;Second is the wireless transmission distance. The following formula can reflect the relationship between them.
FSPL (dB) = 20log10(d) + 20log10(f) + K
d = distance
f = frequency
K= constant that depends on the units used for d and f
If d is measured in kilometers, f in MHz, the formula is:
FSPL (dB) = 20log10(d)+ 20log10(f) + 32.44
From the Fade Margin equation, Free Space Path Loss can be computed with the following equation.
Free Space Path Loss=Tx Power-Tx Cable Loss+Tx Antenna Gain+Rx Antenna Gain - Rx Cable Loss - Rx Sensitivity - Fade Margin
With the above two Free Space Path Loss equations, we can find out the Distance in km.
Distance (km) = 10(Free Space Path Loss – 32.44 – 20log10(f))/20
The Fresnel Zone is the area around the visual line-of-sight that radio waves spread out into after they leave the antenna. You want a clear line of sight to maintain strength, especially for 2.4GHz wireless systems. This is because 2.4GHz waves are absorbed by water, like the water found in trees. The rule of thumb is that 60% of Fresnel Zone must be clear of obstacles. Typically, 20% Fresnel Zone blockage introduces little signal loss to the link. Beyond 40% blockage the signal loss will become significant.
FSPLr=17.32*√(d/4f)
d = distance [km]
f = frequency [GHz]
r = radius [m]
Source : http://www.tp-link.com/en/support/calculator/
To calculate the distance you need signal strength and frequency of the signal. Here is the java code:
public double calculateDistance(double signalLevelInDb, double freqInMHz) {
double exp = (27.55 - (20 * Math.log10(freqInMHz)) + Math.abs(signalLevelInDb)) / 20.0;
return Math.pow(10.0, exp);
}
The formula used is:
distance = 10 ^ ((27.55 - (20 * log10(frequency)) + signalLevel)/20)
Example: frequency = 2412MHz, signalLevel = -57dbm, result = 7.000397427391188m
This formula is transformed form of Free Space Path Loss(FSPL) formula. Here the distance is measured in meters and the frequency - in megahertz. For other measures you have to use different constant (27.55). Read for the constants here.
For more information read here.
K = 32.44
FSPL = Ptx - CLtx + AGtx + AGrx - CLrx - Prx - FM
d = 10 ^ (( FSPL - K - 20 log10( f )) / 20 )
Here:
K - constant (32.44, when f in MHz and d in km, change to -27.55 when f in MHz and d in m)
FSPL - Free Space Path Loss
Ptx - transmitter power, dBm ( up to 20 dBm (100mW) )
CLtx, CLrx - cable loss at transmitter and receiver, dB ( 0, if no cables )
AGtx, AGrx - antenna gain at transmitter and receiver, dBi
Prx - receiver sensitivity, dBm ( down to -100 dBm (0.1pW) )
FM - fade margin, dB ( more than 14 dB (normal) or more than 22 dB (good))
f - signal frequency, MHz
d - distance, m or km (depends on value of K)
Note: there is an error in formulas from TP-Link support site (mising ^).
Substitute Prx with received signal strength to get a distance from WiFi AP.
Example: Ptx = 16 dBm, AGtx = 2 dBi, AGrx = 0, Prx = -51 dBm (received signal strength), CLtx = 0, CLrx = 0, f = 2442 MHz (7'th 802.11bgn channel), FM = 22. Result: FSPL = 47 dB, d = 2.1865 m
Note: FM (fade margin) seems to be irrelevant here, but I'm leaving it because of the original formula.
You should take into acount walls, table http://www.liveport.com/wifi-signal-attenuation may help.
Example: (previous data) + one wooden wall ( 5 dB, from the table ). Result: FSPL = FSPL - 5 dB = 44 dB, d = 1.548 m
Also please note, that antena gain dosn't add power - it describes the shape of radiation pattern (donut in case of omnidirectional antena, zeppelin in case of directional antenna, etc).
None of this takes into account signal reflections (don't have an idea how to do this). Probably noise is also missing. So this math may be good only for rough distance estimation.
the simple answer to your question would be Triangulation. Which is essentially the concept in all GPS devices, I would give this article a read to learn more about how Google goes about doing this: http://www.computerworld.com/s/article/9127462/FAQ_How_Google_Latitude_locates_you_?taxonomyId=15&pageNumber=2.
From my understanding, they use a service similar to Skyhook, which is a location software that determines your location based on your wifi/cellphone signals. In order to achieve their accuracy, these services have large servers of databases that store location information on these cell towers and wifi access points - they actually survey metropolitan areas to keep it up to date. In order for you to achieve something similar, I would assume you'd have to use a service like Skyhook - you can use their SDK ( http://www.skyhookwireless.com/location-technology/ ).
However, if you want to do something internal (like using your own routers' locations) - then you'd likely have to create an algorithm that mimics Triangulation. You'll have to find a way to get the signal_strength and mac_address of the device and use that information along with the locations of your routers to come up with the location. You can probably get the information about devices hooked up to your routers by doing something similar to this ( http://www.makeuseof.com/tag/check-stealing-wifi/ ).
Distance (km) = 10^((Free Space Path Loss – 92.45 – 20log10(f))/20)
In general, this is a really bad way of doing things due to multipath interference. This is definitely more of an RF engineering question than a coding one.
Tl;dr, the wifi RF energy gets scattered in different directions after bouncing off walls, people, the floor etc. There's no way of telling where you are by trianglation alone, unless you're in an empty room with the wifi beacons placed in exactly the right place.
Google is able to get away with this because they essentially can map where every wifi SSID is to a GPS location when any android user (who opts in to their service) walks into range. That way, the next time a user walks by there, even without a perfect GPS signal, the google mothership can tell where you are. Typically, they'll use that in conjunction with a crappy GPS signal.
What I have seen done is a grid of Zigbee or BTLE devices. If you know where these are laid out, you can used the combined RSS to figure out relatively which ones you're closest to, and go from there.
Don't care if you are a moderator. I wrote my text towards my audience not as a technical writer
All you guys need to learn to navigate with tools that predate GPS. Something like a sextant, octant, backstaff or an astrolabe.
If you have receive the signal from 3 different locations then you only need to measure the signal strength and make a ratio from those locations. Simple triangle calculation where a2+b2=c2. The stronger the signal strength the closer the device is to the receiver.

Software Phase Locked Loop example code needed

Does anyone know of anywhere I can find actual code examples of Software Phase Locked Loops (SPLLs) ?
I need an SPLL that can track a PSK modulated signal that is somewhere between 1.1 KHz and 1.3 KHz. A Google search brings up plenty of academic papers and patents but nothing usable. Even a trip to the University library that contains a shelf full of books on hardware PLL's there was only a single chapter in one book on SPLLs and that was more theoretical than practical.
Thanks for your time.
Ian
I suppose this is probably too late to help you (what did you end up doing?) but it may help the next guy.
Here's a golfed example of a software phase-locked loop I just wrote in one line of C, which will sing along with you:
main(a,b){for(;;)a+=((b+=16+a/1024)&256?1:-1)*getchar()-a/512,putchar(b);}
I present this tiny golfed version first in order to convince you that software phase-locked loops are actually fairly simple, as software goes, although they can be tricky.
If you feed it 8-bit linear samples on stdin, it will produce 8-bit samples of a sawtooth wave attempting to track one octave higher on stdout. At 8000 samples per second, it tracks frequencies in the neighborhood of 250Hz, just above B below middle C. On Linux you can do this by typing arecord | ./pll | aplay. The low 9 bits of b are the oscillator (what might be a VCO in a hardware implementation), which generates a square wave (the 1 or -1) which gets multiplied by the input waveform (getchar()) to produce the output of the phase detector. That output is then low-pass filtered into a to produce the smoothed phase error signal which is used to adjust the oscillation frequency of b to push a toward 0. The natural frequency of the square wave, when a == 0, is for b to increment by 16 every sample, which increments it by 512 (a full cycle) every 32 samples. 32 samples at 8000 samples per second are 1/250 of a second, which is why the natural frequency is 250Hz.
Then putchar() takes the low 8 bits of b, which make up a sawtooth wave at 500Hz or so, and spews them out as the output audio stream.
There are several things missing from this simple example:
It has no good way to detect lock. If you have silence, noise, or a strong pure 250Hz input tone, a will be roughly zero and b will be oscillating at its default frequency. Depending on your application, you might want to know whether you've found a signal or not! Camenzind's suggestion in chapter 12 of Designing Analog Chips is to feed a second "phase detector" 90° out of phase from the real phase detector; its smoothed output gives you the amplitude of the signal you've theoretically locked onto.
The natural frequency of the oscillator is fixed and does not sweep. The capture range of a PLL, the interval of frequencies within which it will notice an oscillation if it's not currently locked onto one, is pretty narrow; its lock range, over which it will will range in order to follow the signal once it's locked on, is much larger. Because of this, it's common to sweep the PLL's frequency all over the range where you expect to find a signal until you get a lock, and then stop sweeping.
The golfed version above is reduced from a much more readable example of a software phase-locked loop in C that I wrote today, which does do lock detection but does not sweep. It needs about 100 CPU cycles per input sample per PLL on the Atom CPU in my netbook.
I think that if I were in your situation, I would do the following (aside from obvious things like looking for someone who knows more about signal processing than I do, and generating test data). I probably wouldn't filter and downconvert the signal in a front end, since it's at such a low frequency already. Downconverting to a 200Hz-400Hz band hardly seems necessary. I suspect that PSK will bring up some new problems, since if the signal suddenly shifts phase by 90° or more, you lose the phase lock; but I suspect those problems will be easy to resolve, and it's hardly untrodden territory.
This is an interactive design package
for designing digital (i.e. software)
phase locked loops (PLLs). Fill in the
form and press the ``Submit'' button,
and a PLL will be designed for you.
Interactive Digital Phase Locked Loop Design
This will get you started, but you really need to understand the fundamentals of PLL design well enough to build it yourself in order to troubleshoot it later - This is the realm of digital signal processing, and while not black magic it will certainly give you a run for your money during debugging.
-Adam
Have Matlab with Simulink? There are PLL demo files available at Matlab Central here. Matlab's code generation capabilities might get you from there to a PLL written in C.

Resources