es gibt zwei verschiedene Dinge hier - wie erkennen Sie einen scharfen Übergang, und wie filtern Sie es: dass es so etwas wie folgt aussieht.
Nehmen wir diese nacheinander.
Ein scharfer Übergang ist durch eine große Krümmung gekennzeichnet - wir können dies leicht erkennen, indem wir diff
der Eingangskurve verwenden. Die Verwendung des zweiten Parameters = 2 nimmt zweimal die Zahl diff
an und führt dazu, dass die zweite Ableitung "ähnlich" ist - aber sie wird um eins erhöht. Wenn wir also Punkte finden, wo der diff(sharkfin,2)
groß ist, müssen wir um 1 versetzen, um die Eckpunkte zu erhalten.
Als nächstes die Glättung selbst. Es gibt viele Techniken - ich zeige eine einfache Faltung mit einer Box-Funktion. Dies führt zu einer geglätteten Version der Eingabe. Indem wir das Original "weit weg von der Diskontinuität" und die gefilterte Version "nahe der Diskontinuität" auswählen, erhalten wir genau das, wonach Sie gefragt haben. Wenn Sie wollten, könnten Sie die Punkte "verschmelzen" - mit einer gewichteten Version von gefiltert und ungefiltert, je nachdem, wie nahe Sie den Eckpunkten waren. Das habe ich nicht explizit zeigen, aber es sollte leicht sein, zu sehen, wie Sie den Code erweitern ich schon schrieb:
% 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'
Ausgang:
So sind Sie für einen Algorithmus Schauen scharf zu erkennen Ecken in einem Signal und runden sie ab. Hast du eins gefunden? – Anthony
Beachten Sie, dass Ihre Verwendung von ['convex'] (https://en.wikipedia.org/wiki/Convex_function) wahrscheinlich falsch ist. Das Glätten der Ecke macht es nicht konvexer. – m7913d
Mehr als ein Algorithmus, ein Schritt ist gut genug. Ich habe die Idee, dass ein Moving-Average-Filter um den steilen Anstieg und Fall funktionieren könnte. Aber ich habe von hier aus Hilfe gesucht. Oder etwas Hilfe bei der Implementierung des Filters nur auf einem kleinen Abschnitt der Kurve. –