il y a deux choses distinctes ici - comment détecter une transition forte, et comment le filtre ne vous il.
Prenons ces éléments.
une transition nette se caractérise par une grande courbure - on peut facilement détecter ceci en prenant la diff
de la courbe d'entrée. L'utilisation du deuxième paramètre = 2 prend deux fois diff
et donne quelque chose de «semblable» à la dérivée seconde - mais elle est décalée d'une unité. Donc, quand nous trouvons des points où le diff(sharkfin,2)
est grand, nous devons compenser par 1 pour obtenir les points de coin.
Ensuite, le lissage lui-même. Il y a beaucoup de techniques - je montre une convolution simple avec une fonction de boîte. Faire cela deux fois donne une version lissée de l'entrée. En choisissant l'original "loin de la discontinuité" et la version filtrée "proche de la discontinuité" nous obtenons exactement ce que vous demandiez. Si vous le souhaitez, vous pouvez "fusionner" les points - en utilisant une version pondérée de filtrée et non filtrée en fonction de la proximité des points d'angle. Je ne montre pas que explicitement mais il devrait être facile de voir comment développer le code je l'ai déjà écrit:
% generate a "shark fin" function:
fin = exp(-linspace(0,4,60));
shark = [fin (1-fin+fin(end))];
shark = repmat(shark, [1 3]);
D2 = diff(shark, 2);
roundMe = find(abs(D2)>0.1*max(D2))+1; % offset by 1 because second derivative
figure;
subplot(3,1,1)
plot(shark); title 'shark plot'
hold on;
plot(roundMe, shark(roundMe),'r*')
legend('input','corners found')
% take N points on either side of the sharp corners:
N = 3;
% boxplot filtered version of the curve
boxFilt = ones(1, 2*N+1)/(2*N+1);
smoothShark1 = convn(shark, boxFilt, 'same'); % box plot
% second filter - smoother
smoothShark2 = convn(smoothShark1, boxFilt, 'same');
% plot the filtered results:
subplot(3,1,2)
plot(shark)
hold on
plot(smoothShark1);
hold on
plot(smoothShark2);
xlim([114 126])
ylim([0.8,1.1])
legend('original','box','box x2')
title 'smoothed everywhere'
% Now apply filtering only to points near the discontinuity
smoothMe = zeros(size(shark));
smoothMe(roundMe)=1;
smoothMe = convn(smoothMe, boxFilt, 'same');
smoothMe(smoothMe>0)=1; % this finds N points on either side of the corner
subplot(3,1,3)
plot(shark)
finalPlot=shark;
hold on
smoothIndx = find(smoothMe);
finalPlot(smoothIndx)=smoothShark2(smoothIndx);
plot(finalPlot,'g')
plot(smoothIndx, finalPlot(smoothIndx), 'r*')
xlim([114 126])
ylim([0.8,1.1])
legend('original','smoothed','changed')
title 'smoothed only near discontinuity'
Sortie:
Vous cherchez un algorithme pour détecter forte coins dans un signal et les arrondir. En avez-vous trouvé un? – Anthony
Notez que votre utilisation de ['convex'] (https://en.wikipedia.org/wiki/Convex_function) est probablement erronée. Lisser le coin ne le rendra pas plus convexe. – m7913d
Plus qu'un algorithme, une étape suffit. J'ai une idée d'un filtre de moyenne mobile autour de la forte hausse et la chute pourrait fonctionner. Mais je cherchais de l'aide d'ici. Ou un peu d'aide dans la mise en œuvre du filtre uniquement sur une petite section de la courbe. –