0
$\begingroup$

am trying to understand how to find a dominant frequency in a signal i've a csvfile for an analog data wich detects the breathing rate for the human i need to find the dominant frequency between 0.1hz and 2hz in this data for every 100 sample , so i wrote a matlab code to do so , after i run the code i find it gives me the same value in every iteration , so i think it must overwrite the value in every index,, here is the code

% clear the current variables in workspace
clear all;
close all;
clc;
filename = 'breathing.txt';
try
    T = csvread(filename);
catch
    warning('no such file');
end

% get the requested signals to process
signalx = T(:,15); % its length is 33167*1

%plot(signalx);


 % ----- apply median filter on data ------

windowSize = 5;
signalx = medfilt1(signalx, windowSize);
plot(signalx);

% -------- process the three signals -------

% initialize variables
samplingRate = 100;
movingwindowSize = 10*samplingRate;
incrementalWindow = 1*samplingRate;
% % % % tolerancefreq = 0.05;
dataLength = size(T,1);
dominantVector = zeros(floor(dataLength/movingwindowSize), 1);
count = 1;
% % % % 
for i =1 : incrementalWindow : dataLength-movingwindowSize

    % ------ data segmentation -----

    currentwindow_sigx=signalx(i:i+movingwindowSize-1);


     % ----- apply hamming window -----


     hammingDatax=currentwindow_sigx.*hamming(length(currentwindow_sigx));
     plot(hammingDatax);

     %---- remove dc offset from data ----

     data_x = detrend(hammingDatax);


      % ------- apply fft ------------

     fftData_x = fft(data_x);
     plot(abs(fftData_x));


     % ------- find dominant frequency -----


     len = (length(fftData_x)/2)+1;
     datax = fftData_x(1:len);
     plot(abs(datax));



     fftLength = length(fftData_x);
     freq = (0:(samplingRate/fftLength) :(samplingRate/2));
     plot(freq,abs(datax)), grid('on'), title('dominant freq')

        freq =  freq(find(freq>=0.1 & freq<=2));


    [v,k] = max(datax);


      dominantFrequency = freq(k);             
      dominantVector(count) = dominantFrequency;            
     count = count +1;

end 

so when i run the code it gives me a 322*1 vector with all values == .2000 am sure there is something wrong with the foor loop and the index but i can't find where te problem is. and here is a photo of the workspace and sample of the overwritten values. enter image description here

$\endgroup$
1
$\begingroup$

You are searching for the maximum on the entire epoched/windowed data-set:

[v,k] = max(datax);

getting the value and index to this maximum. However you should restrict your search on the frequencies of interest:

valid_idx=(freq>=0.1 & freq<=2);
[v,k] = max(datax(valid_idx));

I would leave the find out as you can perform the search on a logical-index variable and thus you do not need to transform the found-index into the original index.

Additionally, I would first demean your data:

data_x = currentwindow_sigx-mean(currentwindow_sigx);

Which would be equal to detrend(currentwindow_sigx,'constant'), without the parameter constant you are detrending and not demeaning. After this I would apply the hamming window. And then calculate the fft. You should inspect your data afterwards and check if the data looks "physiological", especially in the frequency band of interest. Here you need some experience to judge this. If the data looks okay the maximum search should give you the correct result.

I assume that the fft will be noise, you could apply some smoothing to it before you search for the dominat frequency to avoid outliers.

$\endgroup$
  • $\begingroup$ but when i wrote this { valid_idx=(freq>=0.1 & freq<=2); [v,k] = max(datax(valid_idx)); } it gave me .1000 for all values of the dominant frequency !! $\endgroup$ – TAM.G Sep 4 '17 at 6:07
  • $\begingroup$ I edited my response, as I would change the processing order and use the detrend function correctly to demean the data. It is difficult to see what else could be wrong without seeing some graphs of your results. $\endgroup$ – Irreducible Sep 4 '17 at 6:26
  • $\begingroup$ i did all of this before to apply fft to the data and the ( count) variable to sort the dominant vectors because (i) will skip much indices's ,, my problem here ,, why the values are overwritten and and the vector doesn't store new value in every new index ?? $\endgroup$ – TAM.G Sep 4 '17 at 7:01
  • $\begingroup$ You are right, the index i is not incremented by one, so the count variable is better to be used. What I don't understand is what you mean by "is being overwriten". Is the intermediate step correct but the saved values are wrong? Are the ffts looking good? $\endgroup$ – Irreducible Sep 4 '17 at 7:13
  • $\begingroup$ yeah the ffts looking fine ,, and i mean by overwritten here is the value .2000 is repeated in every index and it's impossible to get the same frequency in every iteration ,, so am saying there is a value overwrite in each index instead of the new value $\endgroup$ – TAM.G Sep 4 '17 at 7:21

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.