МАТЛАБ: Как избежать смещения при пересчете сегментированного сигнала?
Из-за ограничений памяти я сегментирую и передискретизирую свои данные перед обработкой. Однако в процессе повторной выборки некоторые сэмплы каким-то образом смещаются, т.е. если у меня есть сигнал A длиной N, который я делю на два меньших сегмента B и C, где B=A(1:j) и C=A(j+1:N), часть сигнала после j смещена по сравнению с исходным сигналом A.
Приведенный ниже код и изображения иллюстрируют мою проблему. Я не настолько обеспокоен получением различий по краям сегментов, но накопление ошибок проблематично для меня.
target_freq = 1000;
sampling_frequency = 32556;
order = 2;
fcutlow_low = 140;
fs = sampling_frequency;
[b_low,a_low] = butter(order,fcutlow_low/(fs/2), 'low');
myresamp = @(array) resample(array,target_freq,sampling_frequency);
myfilt = @(array) filtfilt(b_low, a_low, abs(array));
mydata = rand(1,100000);
target_freq = 1000;
original_freq = fs;
segresample = [myresamp(mydata(1:end/4)) myresamp(mydata((end/4)+1:end/2)) myresamp(mydata((end/2)+1:end))];
%% misalignment at the point of segmentation
figure
subplot(2,1,1)
plot(myresamp(mydata) - segresample)
ylabel('difference')
title('resampled')
%% this works as expected
segresample = [mydata(1:end/2)...
mydata(end/2+1:end)];
subplot(2,1,2)
plot(mydata-segresample)
title('not resampled')
ylabel('difference')
1 ответ
Я полагаю, что передискретизация реализована с помощью набора КИХ-фильтров, поэтому, когда вы разделяете сигнал таким образом, фильтры передискретизации не имеют никакой истории входного сигнала в ваших точках сегментации, по сути это сумма для последнего n-го входа сэмплов ноль.
Чтобы избежать этого, вам нужно сегментировать ваш сигнал в кадры, которые перекрываются, обеспечивая достаточное количество выборок, чтобы у фильтра FIR было достаточно истории входных сигналов. Рассматривать:
|--------------------- long signal ------------------|
|----- frame 1 -----|
|----- frame 2 -----|
|----- frame 3 -----|
|----- frame 4 -----|
Повторно сэмплируйте каждый кадр, затем выбросьте начало пересчитанных внутренних кадров:
|----- frame 1 -----|
| frame 2 -----|
| frame 3 -----|
|---|
Отбрасывая начало пересчитанных внутренних кадров, вы отбрасываете сэмплы FIR-выхода, которые не имели полной истории входного сигнала.
Я не уверен, как предварительно рассчитать размер задержки FIR для использования в качестве размера перекрытия, поэтому вам придется экспериментировать. Это должно быть связано с отношением sr и target_sr. Сделайте размер перекрытия параметром в вашей функции, чтобы вы могли легко настроить его.