Template matching between 1d frequency curves using normxcorr2

9 visualizaciones (últimos 30 días)
David Santos
David Santos el 1 de Jul. de 2024
Comentada: David Santos el 25 de Jul. de 2024
Hi,
I'm trying to use 2d cross correlation between 1d dimensional frequency curves (frequencies between 6000 and 22000 Hz) to find if a template curve is present in a test one which is bigger:
Template curve:
Test curve:
I'm willing to use two dimensional cross correlation between both curves using normxcorr2 but I'm not quite sure the most efficient way to do this.
I've tried to convert both curves to binary image arrays, and then applying nomxcorr2 using:
img_template=bsxfun(@eq, 1:22000,curve_template);
img_test=bsxfun(@eq, 1:22000,curve_test);
c=normxcorr2(img_template,img_test);
but this way the 2d arrays are huge (77x22000 and 5703x22000) and the results are difficult to plot ( because of memory issues) and so to analize:
figure;mesh(img_template');hold on;
view([0 90]);
mesh(img_test);
figure;
surf(c)
Any clue on how to do this template matching between curves in a more efficcient way?
  2 comentarios
Matt
Matt el 1 de Jul. de 2024
Hi,
If you want to detect, in a 1D signal, a certain pattern you can simply use 1D correlation. No need, except if I missed your goal, to convert the data like you are.
% normxcorr2 works on 1d data:
plot(normxcorr2(curve_template,curve_test))
% but it also work on N signals of length M
n = 512;
m=1024;
imagesc(normxcorr2(curve_template,rand(m,n)))
and if you want to go faster on many signals, you can drop the normalisation part and simply do a convolution between your signals, and the pattern.
imagesc(conv2(curve_template,rand(m,n),'valid'))
David Santos
David Santos el 2 de Jul. de 2024
Thanks for you answer @Matt.
I'm talking about a 1D array but as you can see in the pictures the representation is two dimensional and because the template that I'm looking for can be streched in time and frequency I guess that a 2D correlation would get a better matching, don't you?
All the best

Iniciar sesión para comentar.

Respuestas (1)

Milan Bansal
Milan Bansal el 25 de Jul. de 2024
Hi David Santos,
To perform template matching between 1D frequency curves in a more efficient way, you can use 1D cross-correlation instead of converting your curves to 2D arrays. This approach will be much more memory-efficient and easier to handle.
Here's how you can do it:
  1. Normalize the curves: Make sure both curve_template and curve_test are normalized. This can be done by subtracting the mean and dividing by the standard deviation.
  2. Use xcorr: Instead of normxcorr2, you can use xcorr to perform cross-correlation on 1D arrays. Here is the documentation of xcorr:https://www.mathworks.com/help/matlab/ref/xcorr.html
  3. Find the peak: The peak in the cross-correlation result will indicate the best match between the template and the test curve.
Here's an example code to perform these steps:
load curves
% Normalize the curves
curve_template = (curve_template - mean(curve_template)) / std(curve_template);
curve_test = (curve_test - mean(curve_test)) / std(curve_test);
% Perform 1D cross-correlation
[corr_result, lags] = xcorr(curve_test, curve_template);
% Find the peak of the correlation result
[~, peak_index] = max(corr_result);
% The lag corresponding to the peak indicates the best match position
best_match_lag = lags(peak_index);
% Plot the cross-correlation result
figure;
plot(lags, corr_result);
xlabel('Lag');
title('Cross-Correlation between Test Curve and Template Curve');
% Plot the best match
figure;
plot(curve_test(best_match_lag:best_match_lag+length(curve_template)-1));
hold on;
plot(curve_template, 'r');
legend('Test Curve Segment', 'Template Curve');
title('Best Match between Test Curve and Template Curve');
Hope it helps!
  1 comentario
David Santos
David Santos el 25 de Jul. de 2024
Thanks for your answer @milan Im using normxcorr2 with 1d sígnals so Í dont have the need to normalize the signals. Normalization fails sometimes because the only difference between some of the curves is in the amplitude. By other side, I need to use dtw not only correlation because the detected sígnale can suffer some time streching or expansion, that why Im looking for a dtw modification that can find my references in some parts of a detection file without the possibility of the references being warped, that the question indeed, How to find my reference in some parts of a detection file knowing that these detection Could suffer from time warping

Iniciar sesión para comentar.

Categorías

Más información sobre Spectral Estimation en Help Center y File Exchange.

Productos


Versión

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by