Spectral Centroid - get the same results in matlab and python
5 views (last 30 days)
Show older comments
I obtain spectral centroid in matlab using this code.
Fs = 200
v = [0.79230, 0.28280, 0.63000, 0.64140, 0.76430, 0.25560, 0.27780, 0.73330, 0.48960, 0.01990];
s = spectrogram(v,rectwin(round(Fs*0.03)),...
round(Fs*0.02),...
numel(rectwin(round(Fs*0.03))),...
Fs,...
'power',...
'onesided');
X = abs(sqrt(s/2));
centroid = spectralCentroid(v,Fs,'Window',rectwin(round(Fs*0.03)),...
'OverlapLength',round(Fs*0.02),...
'FFTLength',numel(rectwin(round(Fs*0.03))),...
'Range',[0, Fs/2],...
'SpectrumType','power')
vsc = FeatureSpectralCentroid (X, Fs)
centroid = [10.6816, 6.0146, 19.6662]
vsc = [40.4499, 27.4300, 41.0146]
I also use a different implementation of spectral centroid and the results are also different. Sometimes scalar, not vector. How to use `FeatureSpectralCentroid` to get the same results as in spectralCentroid ? Can we always get the same results of spectral centroid?
0 Comments
Answers (1)
Brian Hemmat
on 10 Dec 2019
Hi Mariusz,
Below is some code showing how you can get the FeatureSpectralCentroid function in your link to give close to the same result as the spectralCentroid. Note that they do not give exactly the same result because there is one fundamental difference: FeatureSpectralCentroid calculates the spectral centroid in the normalized domain then converts to Hz, whereas spectralCentroid calculates the spectral centroid on a Hz grid. The spectralCentroid also accepts frequency-domain input, so you could feed it the same intermediate representations from spectrogram, periodogram, or stft and expect the same resutls.
Fs = 200;
v = [0.79230, 0.28280, 0.63000, 0.64140, 0.76430, 0.25560, 0.27780, 0.73330, 0.48960, 0.01990];
v = v(:); % Time is along rows.
win = rectwin(round(Fs*0.03));
overlapLength = round(Fs*0.02);
% Spectral Centroid Using spectralCentroid -------------------------------------------------
centroid = spectralCentroid(v,Fs,'Window',win,...
'OverlapLength',overlapLength,...
'FFTLength',numel(win));
% ------------------------------------------------------------------------------------------
% Spectral Centroid Using FeatureSpectralCentroid and spectrogram --------------------------
[~,~,~,ps] = spectrogram(v,win,...
overlapLength,...
numel(win),...
Fs,...
'power',...
'onesided');
vsc = FeatureSpectralCentroid(ps, Fs);
vsc = vsc'; % reorient so that centroid is along rows.
mean((centroid-vsc).^2,'all') % 1.6829e-29
% ------------------------------------------------------------------------------------------
% Spectral Centroid Using FeatureSpectralCentroid and periodogram --------------------------
[vBuffered,throwaway] = buffer(v,numel(win),overlapLength,'nodelay');
[powerSpectrum,frequencyVector] = periodogram(vBuffered,win,numel(win),Fs,'onesided','power');
vsc = FeatureSpectralCentroid(powerSpectrum,Fs);
vsc = vsc'; % reorient so that centroid is along rows.
mean((centroid-vsc).^2,'all') % 1.6829e-29
% ------------------------------------------------------------------------------------------
% Spectral Centroid Using FeatureSpectralCentroid and stft ---------------------------------
s = stft(v,Fs,'Window',win,'OverlapLength',overlapLength,'FFTLength',numel(win),'Centered',false);
s = (s.*conj(s))./(sum(win)^2); % convert to window-normalized power spectrum
s = s(1:4,:); % convert to half-sided spectrum
s(2:3,:) = 2*s(2:3,:); % Adjust weights for half-sided power spectrum
vsc = FeatureSpectralCentroid(s,Fs);
vsc = vsc'; % reorient so that centroid is along rows.
mean((centroid-vsc).^2,'all') % 1.6829e-29
% ------------------------------------------------------------------------------------------
Regarding scalar versus vector: In audio, spectral descriptors (like centroid) are generally calculated for sliding windows over the audio. This is because audio signals are non-stationary.
0 Comments
See Also
Categories
Find more on Spectral Measurements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!