Resample function is not working properly and damaging the signal
Afficher commentaires plus anciens
Hi,
I have a question regarding the resample function (It is the documentation under "Resample Multichannel Signal"). In this function, I realized that the function damages the signal on both ends of the given signal. Here I am attaching the code to generate 100-sample sinusoidal signal.
p = 3;
q = 2;
tx = 0:p:300-p;
x = cos(2*pi*tx./(1:5)'/100);
plot(tx,x,'.:')
title('Original')
ylim([-1.5 1.5])
However, once you resample with the following give code, the signals are simply damaged at both ends. You can see the effects on both time points close to 0 and close to 300.
ty = 0:q:300-q;
y = resample(x,p,q,'Dimension',2);
plot(ty,y,'.:')
title('Upsampled')
Therefore, could you please help me to solve this issue? Because, I am currently trying to resample my multichannel motion capture signals, which are sampled at 60 Hz or 200 Hz, in "100 Hz". However, this function will damage my signal if I use it, and this will definitely affect the outcome of my research.
I will be waiting for your help and appreciate your assistance.
Thanks!
6 commentaires
Walter Roberson
le 15 Mar 2023
Perhaps you should be using filtfilt
goksu avdan
le 16 Mar 2023
Walter Roberson
le 16 Mar 2023
I do not know; you would have to test it.
y = filtfilt(b,a,x) performs zero-phase digital filtering by processing the input data x in both the forward and reverse directions. After filtering the data in the forward direction, the function reverses the filtered sequence and runs it back through the filter. The result has these characteristics:
- Zero phase distortion.
- A filter transfer function equal to the squared magnitude of the original filter transfer function.
- A filter order that is double the order of the filter specified by b and a.
filtfilt minimizes start-up and ending transients by matching initial conditions. Do not use filtfilt with differentiator and Hilbert FIR filters, because the operation of these filters depends heavily on their phase response.
goksu avdan
le 16 Mar 2023
Paul
le 17 Mar 2023
The doc page resample says that the function "compensates for the delay introduced by the filter," which is the exact language used by lowpass et. al. I'm nearly certain that the filtering in lowpass is effectively the same as filtfilt, which does extend the input signal off the edges to minimize these types of edge transients. I'm suprised that resample doesn't do the same; maybe there is something particular about the filtering in resample that precludes that (assuming it is, in fact, not done as appears to be the case).
Hi,
I do have an additional comment regarding the post by @goksu avdan. There is an issue with using resample() for processing blocks of data. If I'm using resample to interpolate/decimate, I will get erroneous results at the edges. In the past, to get around this, I have used a "brute-force" approach with filter() as in the following:
while dataAvailable
% Say x is dimensioned 1 by Nsamples and I am upsampling by a factor
% Nup and downsampling by Ndown
% Zero fill between samples
xi = [x;zeros(Nup-1,Nsamples)];
xi = xi(:).';
% xi should now be dimensioned 1 by (Nup*Nsamples) with zeros inbetween the original samples
% Now low-pass filter and decimate
[xd, zFilt] = filter(bFilt, 1, xi, zFilt);
xd = xd(1:Ndown:end);
end
Assuming that I use the same bFilt that would come out of resamp(), the above result will match resample() if I ignore the first floor(length(bFilt)/2/Ndown) output samples. By using the above approach, I have to deal with a transient response for the first block, after that I have continuous correct results. In order to achieve that with resample, one would have to devise some kind of overlap-save approach.
The problem with the "brute force" approach is that it is inefficient and does not take advantage of all of the zeros that a proper polyphase filtering technique, as done in resample(), would handle.
What would be ideal would be something like:
[y, zFilt] = resmaple(x, p, q, zFilt);
I do realize that depending on what the ratio of p/q looks like, it might be near impossible to get an integer number of output points without "playing tricks", but I'm ignoring that right now.
Any thoughts on this? Am I missing something? Apologies for spelling errors and any code miscues.
Thanks in advance!
Réponse acceptée
Plus de réponses (2)
Hi goksu,
The observed behavior is documented at resample specifcally here: "... resample assumes that the input sequence, x, is zero before and after the samples it is given. Large deviations from zero at the endpoints of x can result in unexpected values for y." See examples at that doc page.
If you're looking for theoretically pleasing approach, resample provides means to influence transients as shown here, for example. Don't know if that approach applies to the ends of the signal or just transients internal to the signal as shown in that example.
If you're looking for a heuristic approach, one option might be to extrapolate the signal off the ends, apply resample, then chop of the extensions. I used 20 sample extensions and linear extrapolation on the example data. The actual number and method will likely depend on the actual data and the resample filter parameters. I'm only thinking about extrapolations that minimize transients at the transitions to/from the endpoints of the original signal before resampling. spline or pchip might work better. Anyway, here's what I tried:
Original signals
p = 3;
q = 2;
tx = 0:p:300-p;
x = cos(2*pi*tx./(1:5)'/100);
plot(tx,x,'.:')
title('Original')
ylim([-1.5 1.5])
Extend the signals by 20 samples via linear extrapolation.
txext = [(-20:-1)*p tx (1:20)*p+tx(end)];
xext = (interp1(tx,x.',txext,'linear','extrap')).';
Resample
y = resample(xext,p,q,'Dimension',2);
fsx = 1/p;
fsy = fsx*p/q;
ty = txext(1) + (0:(size(y,2)-1))/fsy;
Plot the extended output, note the transients have been pushed away from the central region we care about 0 < t < 300.
figure;
plot(ty,y),grid
Lop off the extensions
y(:,ty<0) = [];
ty(ty<0) = [];
y(:,ty>tx(end)) = [];
ty(ty>tx(end)) = [];
figure
plot(ty,y),grid
4 commentaires
goksu avdan
le 17 Mar 2023
Star Strider
le 17 Mar 2023
If my code is not doing what you want, it is appropriate to post the signal, what my code did to it, and what the problems are with it. All I have to work with are the posted examples.
Also, I was under the impression that the ends of the signals were important data, and not to be deleted from them. That was a constraint in the approach I took.
My code detrends the signals so they are zero at the ends, resamples the detrended signals to eliminate the ‘end effect’, and then retrends the resampled signals to their original values.
goksu avdan
le 17 Mar 2023
Paul
le 17 Mar 2023
I don't think I deleted any needed data at the ends; I certainly didn't mean to if I did. The resampled, post-extraploated data is retained for all times contained within the original tx vector, including the endpoints.
It is easy to avoid the loop too, it is just a simple linear interpolation:
p = 3;
q = 2;
tx = (0:p:300-p).';
x = cos(2*pi*tx./(1:5)/100); % note orientation!
plot(tx,x,'.:')
title('Original')
ylim([-1.5,1.5])
ty = 0:q:300-q;
ax = interp1(tx([1,end]),x([1,end],:),tx);
ay = interp1(ty([1,end]),x([1,end],:),ty);
y = resample(x-ax,p,q)+ay;
plot(ty,y,'.:')
title('Upsampled')
2 commentaires
Note that you can easily avoid all of those loops and all of the superfluous data processsing.
Avoid fighting MATLAB with lots of loops and IFs and the like. Think in terms of arrays and indices.
S = load('Subject3.mat');
S = S.s;
% Select valid dataset:
X = strcmp({S.Data.Task},'Walking');
Y = cellfun(@(m)any(isnan(m(:))),{S.Data.Marker});
Z = find(X&~Y,1,'last');
old = S.Data(Z).Marker;
% Sample rate:
p = interp1([60,200],[5,1],S.KinFreq);
q = interp1([60,200],[3,2],S.KinFreq);
tx = p*(0:size(old,2)-1);
Fs = 1/q;
% Resample:
DeTr = interp1(tx([1,end]),old(:,[1,end]).',tx).';
[M,ty] = resample(old-DeTr,tx,Fs,'Dimension',2);
ReTr = interp1(ty([1,end]),old(:,[1,end]).',ty).';
new = M+ReTr;
% Plot original:
figure
plot(tx, old)
grid
xlabel('Time')
ylabel('Signal')
title('Original Vectors')
% Plot resampled:
figure
plot(ty, new)
grid
xlabel('Time')
ylabel('Signal')
title('Resampled Vectors')
goksu avdan
le 18 Mar 2023
Catégories
En savoir plus sur Descriptive Statistics dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!













