How to find the median in a zero crossing?

Hello, I have calculated zero crossings for a certain signal named 'zip9'. and plotted with a star mark on it. As shown in the figure using the following code: lets consider, y = zip9; zci = @(v) find(v(:).*circshift(v(:), [1 0]) <= 0); % Returns Zero-Crossing Indices Of Argument Vector zx = zci(y); % Approximate Zero-Crossing Indices figure(1) plot(t, y, '-r') hold on plot(t(zx), y(zx), 'bp') hold off grid legend('Signal', 'Approximate Zero-Crossings')
Now, If you zoom the picture towards zero crossings point you will see a picture something like that:
Please note: The zoomed picture is from the first group of start occurrences. Now What I need is that I need to calculate the median of the zero crossing points among those 9 points(picture 2). This has to be done for the rest of the periods. So basically I need to calculate the medians from each of the group of stars from a full period, not half a period.

 Accepted Answer

Thank you for quoting my code!
I am not certain what you intend by ‘median’ zero-crossings. It is straightforward to calculate the more precise zero-crossings using simple linear interpolation. (You can use interp1 for this, but the calculations in my code are likely more efficient for this simple problem.)
The Code
t = linspace(0, 20*pi, 5000);
y = sin(2*pi*t);
zci = @(v) find(v(:).*circshift(v(:), [1 0]) <= 0); % Returns Zero-Crossing Indices Of Argument Vector
zx = zci(y);
for k1 = 1:numel(zx)-1 % Interpolate To Calculate ‘Exact’ Zero-Crossings
tv = t(zx(k1):zx(k1)+1); % Independent Variable Vector
yv = y(zx(k1):zx(k1)+1); % Dependent Variable Vector
b = [[1;1], tv(:)]\yv(:); % Linear Interpolation
ti(k1) = -b(1)/b(2); % Actual Zero-Crossing Times (Values Of Independent Variable)
end
figure(1)
plot(t, y)
hold on
plot(t(zx), y(zx), 'pg')
plot(ti, zeros(size(ti)), '+r')
hold off
figure(2) % Zoomed Plot (Optional)
plot(t, y)
hold on
plot(t(zx), y(zx), 'pg')
plot(ti, zeros(size(ti)), '+r')
hold off
axis([60 63 ylim])

6 Comments

Hi Star, I appreciate for the help... and your code always helped me... Thanks a lot for that.
I am attaching the picture below.. i want to get the medians from the each of the groups. The zoomed version is only the zoomed group of one half of a period. I need to find the median of all the meians of the group among each and every full period. I have tried to make it understand in a more easy if... hope it helps
I do not understand your Comment.
The code in my Answer calculates the more precise values of the times for the zero-crossings. If you want to calculate the period, take the inverse of the median (or mean) of every other value of the differences in ‘ti’:
period = median(diff(ti(1:2:end)));
frequency = 1/period;
Is this what you want to do? (This works, and produces the correct result for the sine function in my Answer.)
Thanks for keeping up the patience.
I do not want so many zero crossings at one time. I need to find a single zero crossing for a 50 hrz signal. Ideally there should be 50 /48(around) zero crossings in a signal. The idea is there are other signals mixed with the 50 hrz signal. The only way to determine the zero crossing of the 50 hrz is that if we can take the median of the group of the stars and then calculate the median of the zero crossings for that particular group. I do not want to have a large set of zero crossing, in this particular case I am getting 45510 number of zero crossing, which I do not need. I need only 50 zero crossings(true).
I am repeating again, I need to grab those bunch of points in my wave for a single point(as i have shown you in the picture above). then i need to perform a median detection among that group and plot a single point. then move to the next group of points and so the same till the last group...
There are numerous bouncing points in the area of zero crossings - I need one point only - that is the median of those group of bouncing points. Here I have tried to explain the whole scenario in the diagram below.
|I do not understand. The signal you illustrated in your original Question and later are pure sine waves. I have no idea what signal you are actually working with, since you did not supply it, so I cannot provide code to solve your problem.
If you want to isolate a 50 Hz signal, the best way is to use a very narrow bandpass filter. Here is a workable design:
Fs = 44100; % Sampling Frequency (Hz)
Fn = Fs/2; % Nyquist Frequency (Hz)
Wp = [49 51]/Fn; % Passband Frequency (Normalised)
Ws = [48 52]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 150; % Stopband Ripple (dB)
[n,Ws] = cheb2ord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = cheby2(n,Rs,Ws); % Filter Design
[sosbp,gbp] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
figure(8)
freqz(sosbp, 2^16, Fs) % Filter Bode Plot
filtered_signal = filtfilt(sosbp, gbp, original_signal); % Filter Signal
Supply the correct sampling frequency for ‘Fs’, and your signal to my ‘original_signal’ variable.
If you want to design a filter to eliminate a 50 Hz signal, This variation of my first design will work:
Fs = 4100; % Sampling Frequency (Hz)
Fn = Fs/2; % Nyquist Frequency (Hz)
Wp = [49 51]/Fn; % Passband Frequency (Normalised)
Ws = [48 52]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 150; % Stopband Ripple (dB)
[n,Ws] = cheb1ord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = cheby1(n,Rs,Ws,'stop'); % Filter Design
[sossb,gsb] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
figure(9)
freqz(sossb, 2^16, Fs) % Filter Bode Plot
Thanks Star. The solution has partially helped me to solve my problem. It at least gave me a new dimension to think. Thanks again to help me out even the things were complicated... :)
As always, my pleasure!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!