Find similarities between two signals
35 views (last 30 days)
Show older comments
I'm trying to find similarities between my template signal and a lot of other signals. I have tried to use cross-correlation (xcorr) and also peak detection on the signals to find similarities between the template and the signals. The problem is that the algorithm for finding signals that are similar does not work as a want.
Below are my template signal (Figure 1)
and here is one signal that the cross-correltion fought were similar (Figure 2)
Although the two signals have similarities, figure 2 does not contain the high peaks as in figure 1. I want to find signals that contain those clear peaks. I have tried to solve this by using findpeaks with two conditions "MinPeaksHeights'' and "MinPeakDistance'’ to find those bigger peaks and exclude smaller peaks. Somehow it still manages to sometimes find peaks and similarities between signals that does not look similar and I don't really know why.
Is there a better way to find the same peak characteristics as the template?
Below are the part where I try to perform the algorithm to identify similar signals to the template:
template = (template - mean(template)) / std(template);
signal_normalized = zscore(signal, [], 1); % Normalize along time axis
% Define correlation threshold for component selection
correlation_threshold = 0.4;
matching_components_indices = [];
for k = 1:size(signal, 2)
% Calculate cross-correlation with the template
correlation_with_template = max(xcorr(template, signal_normalized(:, k), 'coeff'));
% Check if correlation is above the threshold
if correlation_with_template > correlation_threshold
matching_components_indices = [matching_components_indices, k];
end
end
% Sets amplitude threshold for peak detection
amplitude_threshold = 25;
min_peak_distance = 100; % Min distance between peaks
% Find peaks in the matching components
selected_components_indices = [];
for k = 1:length(matching_components_indices)
[pks_pos, locs_pos] = findpeaks(signal(:, matching_components_indices(k)), ...
'MinPeakHeight', amplitude_threshold, ...
'MinPeakDistance', min_peak_distance);
[pks_neg, locs_neg] = findpeaks(-signal(:, matching_components_indices(k)), ...
'MinPeakHeight', amplitude_threshold, ...
'MinPeakDistance', min_peak_distance);
% Combine positive and negative peak locations
pks = [pks_pos; pks_neg];
locs = [locs_neg; locs_pos];
% Check if any peak exceeds the threshold
if length(pks) > 2
selected_components_indices = [selected_components_indices, matching_components_indices(1)];
found_signal(:,m) = signal(:, selected_components_indices(1));
m = m + 1;
end
Maybe I can improve the peak detection part?
Thanks for any help. If I was unclear, let me know
5 Comments
Star Strider
on 2 Apr 2024
My pleasure!
It might be necessary to filter the data first, probably with a lowpass filter to eliminate the high-frequency noise. (A bandpass filter would probably eliminate the baseline drift as well, so consider that option if that is the result you want.)
You can determine the optimal frequencies for the filter you choose (if that is what you want to do) by taking the fft of both signals (since you will want to use the same filter for both), and then desiging the filter appropriatel using that information. This also assumes both signals have the same sampling frequency, as they must for this sort of approach.
Answers (2)
Constantino Carlos Reyes-Aldasoro
on 2 Apr 2024
Perhaps this file exchange analysing an ECG signal can give you some ideas:
https://uk.mathworks.com/matlabcentral/fileexchange/68246-visualization-and-analysis-of-an-electrocardiogram-signal?focused=7fbc0610-5e23-435e-a271-ddd80d1065d0&tab=example
Image Analyst
on 2 Apr 2024
The question is really what kind of metric(s) would be useful for you?
How about RMS difference? rms
How about mean absolute deviation or median absolute deviation: mad
How about just locating peaks and finding the distance between peaks of the test signal to the reference signal? findpeaks
How about the correlation coefficient? corrcoef
Are the signals aligned already because some of those metrics need the signals to be aligned if you want to compare the shape of the signal. Or they might be a good metric of how misaligned they are.
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!