Как извлечь конкретные значения из автокоррелированных данных в MATLAB? - PullRequest
1 голос
/ 09 сентября 2010

Я работал над извлечением пиковых значений из графика (см. Предыдущий вопрос) , который выглядит следующим образом:

alt text

, но я заметилчто для некоторых графиков xcorr, над которыми я работал, значения не соответствуют ожидаемым, и обычно они выглядят примерно так:

alt text

и это:

альтернативный текст http://a.imageshack.us/img836/7236/plotgraphcopy.jpg

Вместо того, чтобы пытаться выбрать пиковые значения, как код делал на первом рисунке, как бы я попытался выбрать значения, где нисходящий уклон на мгновение выравнивается сам по себеout (как показано на рисунке 3)?

Когда я пытаюсь запустить код в его текущем состоянии на данных, подобных тем, которые показаны на рисунках 2 и 3, я не получаю взамен никаких полезных данных.

Я думаю, что мне нужно выражение if или подобное в разделе «найти точки экстремума», но я не уверен, правильно это или нет.Мой .M-код для функции до сих пор выглядит следующим образом:

[inputname, pathname] = uigetfile('*.wav', 'Select WAV-file');

thumb1 = inputname;               %# Get filename information
fprintf('\n%s is being turned into a 30s thumbnail...\n', thumb1);
fprintf('Please wait..!\n\n');
%# load the signal
[y, fs, nb] = wavread(thumb1);
y = mean(y,2);                               %# stereo, take avrg of 2 channels

%# Calculate frame energy
fWidth = round(fs*1);                    %# 10ms
numFrames = floor(length(y)/fWidth);
energy = zeros(1,numFrames);
for f=1:numFrames
  energy(f) = sum( y((f-1)*fWidth+1:f*fWidth).^2 );
end

%# smooth the signal (moving average with window size = 1% * length of data)
WINDOW_SIZE = round(length(energy) * 0.01);  %# 200
XX = filtfilt(ones(1,WINDOW_SIZE)/WINDOW_SIZE, 1, energy);

%# auto-correlation
[r,lags] = xcorr(XX, 'biased');

%# find extrema points
dr = diff(r);
eIdx = find(dr(1:end-1) .* dr(2:end) <= 0) + 1;

[~,loc] = sort(r(eIdx), 'descend');
loc = loc(1:min(3,end));                     %# take the highest 3 values

inf=lags( eIdx(loc) );

thumb=max(inf);

startrecord=round((thumb/1)*fs);
endrecord=round(((thumb+30)/1)*fs);

wavwrite(y(startrecord:endrecord), fs, nb, 'Temp1');
fprintf('The thumbnail of %s has been created.\n\n', thumb1);

Извините, что все выглядит так грязно, но я хотел бы привести несколько наглядных примеров!

Ответы [ 2 ]

1 голос
/ 09 сентября 2010

Это точки перегиба, и если вы возьмете первую производную ваших данных, вы увидите их как большие отклонения от довольно постоянного наклона.

Играйте с усредненным вагонами, чтобы сделать минимальное сглаживание, и с первой производной, чтобы найти эти точки перегиба.

0 голосов
/ 12 сентября 2010

Я полагаю, что будет легче найти пики в отрицательном значении второй производной. Постоянный или почти постоянный наклон приведет к тому, что 2nd-der = 0; все остальное, включая ваши фактические пики и точки перегиба, будет иметь ненулевое 2-е число. Найдя пики в отрицательных значениях, вы получите только положительные пики, а не отрицательные пики.

...