Locate Ellipse
In diesem Beispiel wird
- mit Hilfe der Funktion F_VN_LocateEllipseExp ein kreisförmiges Objekt in einem definierten Suchbereich lokalisiert
- und die Ausführungszeit mit einem Watchdog überwacht und bei Bedarf begrenzt.
Erläuterung
Für ein Grundverständnis der Vermessungsfunktionen und deren Parameter sehen Sie sich zuerst das Locate Edge Beispiel an. Die Funktion F_VN_LocateEllipseExp unterscheidet sich von der Funktion F_VN_LocateEdgeExp dadurch, dass sie ein kreisförmiges statt rechteckiges Suchfenster verwendet. In diesem Beispiel ist ein großes, ungenaues Suchfenster parametriert, da sich in diesem Beispiel die Position der kreisförmigen Objekte etwas ändert. So können mit dem gleichen Suchfenster in allen Bildern die Kreise bestimmt werden.
Mit dem Parameter bInvertSearchDirection
- der in diesem Beispiel auf TRUE
gesetzt wurde - ist definiert worden, dass die Suchrichtung umgekehrt wird, d. h. von außen in Richtung aCenter
. Das ist notwendig, da sich in den Beispielbildern innerhalb der gesuchten Ellipse ebenfalls Kanten befinden.
Da in diesem Beispiel die Objekte dunkler sind als der Hintergrund, wurde die Suchrichtung auf TCVN_ED_LIGHT_TO_DARK
festgelegt.
Der Parameter nMaxThickness
, der definiert, innerhalb von wie vielen Pixeln fMinStrength
erreicht werden muss, wurde auf den Wert „7
“ gesetzt.
Variablen
hr : HRESULT;
hrFunc : HRESULT;
ipImageIn : ITcVnImage;
ipImageInDisp : ITcVnDisplayableImage;
ipImageRes : ITcVnImage;
ipImageResDisp : ITcVnDisplayableImage;
// result
stEllipse : TcVnRotatedRectangle;
ipContourPoints : ITcVnContainer;
// input parameters
aCenter : TcVnPoint2_REAL := [650, 400];
fRadius : REAL := 300;
fMinRadius : REAL := 100;
fMinStrength : REAL := 30;
nSubPixIter : UDINT := 10;
nSearchLines : UDINT := 40;
eAlgorithm : ETcVnEdgeDetectionAlgorithm := TCVN_EDA_INTERPOLATION;
// Watchdog
hrWD : HRESULT;
tStop : DINT := 15000;
tRest : DINT;
nFraction : UDINT;
// drawing
aColorRed : TcVnVector4_LREAL := [200, 0, 0];
aColorGreen : TcVnVector4_LREAL := [0, 175, 0];
sText : STRING(255);
Code
hrWD := F_VN_StartRelWatchdog(tStop, hr);
hrFunc := F_VN_LocateEllipseExp(
ipSrcImage := ipImageIn,
stEllipse := stEllipse,
aCenter := aCenter,
fSearchRadius := fRadius,
eEdgeDirection := TCVN_ED_LIGHT_TO_DARK,
fMinStrength := fMinStrength,
nMaxThickness := 7,
bInvertSearchDirection := TRUE,
fMinSearchRadius := fMinRadius,
nSubpixelsIterations := nSubpixIter,
nSearchLines := nSearchLines,
fApproxPrecision := 0.0001,
eAlgorithm := eAlgorithm,
ipContourPoints := ipContourPoints,
hrPrev := hr);
hrWD := F_VN_StopWatchdog(hrWD, nFractionProcessed=>nFraction, tRest=>tRest);
// Draw result for visualization
hr := F_VN_ConvertColorSpace(ipImageIn, ipImageRes, TCVN_CST_GRAY_TO_RGB, hr);
sText := CONCAT(CONCAT('Processed ', UDINT_TO_STRING(nFraction)), '%');
hr := F_VN_PutTextExp(sText, ipImageRes, 25, 50, TCVN_FT_HERSHEY_SIMPLEX, 1.3, aColorGreen, 2, TCVN_LT_8_CONNECTED, FALSE, hr);
sText := CONCAT(CONCAT('Time ', DINT_TO_STRING(tStop - tRest)), 'us');
hr := F_VN_PutTextExp(sText, ipImageRes, 25, 100, TCVN_FT_HERSHEY_SIMPLEX, 1.3, aColorGreen, 2, TCVN_LT_8_CONNECTED, FALSE,hr);
hr := F_VN_DrawCircle(REAL_TO_UDINT(aCenter[0]), REAL_TO_UDINT(aCenter[1]), REAL_TO_UDINT(fMinRadius), ipImageRes, aColorRed, 2, hr);
hr := F_VN_DrawCircle(REAL_TO_UDINT(aCenter[0]), REAL_TO_UDINT(aCenter[1]), REAL_TO_UDINT(fRadius), ipImageRes, aColorRed, 2, hr);
hr := F_VN_DrawPoints(ipContourPoints, ipImageRes, TCVN_DS_X, aColorGreen, hr);
hr := F_VN_DrawPoint(REAL_TO_UDINT(stEllipse.aCenter[0]), REAL_TO_UDINT(stEllipse.aCenter[1]), ipImageRes, TCVN_DS_PLUS, aColorGreen, hr);
hr := F_VN_DrawEllipse(stEllipse, ipImageRes, aColorGreen, 1, hr);
// Display source and result image
hr := F_VN_TransformIntoDisplayableImage(ipImageIn, ipImageInDisp, S_OK);
hr := F_VN_TransformIntoDisplayableImage(ipImageRes, ipImageResDisp, S_OK);
Ergebnisse
Die Funktion liefert die TcVnRotatedRectangle
-Struktur stEllipse
zurück, die die gefundene Ellipse anhand ihres Mittelpunkts aCenter
, ihrer Höhe und Breite stSize.fHeight
bzw. stSize.fWidth
und ihres Winkels fAngle
definiert.
Optional kann zusätzlich ein Kantenpunkt pro Suchlinie ipContourPoints
zurückgegeben werden, aus denen die Ellipse approximiert wurde.
Zur Visualisierung wird zunächst der Suchbereich durch 2 rote Kreise um den vorgegebenen Mittelpunkt ins Bild eingezeichnet. Die gefundene Ellipse wird als grüne Linie eingezeichnet und der zugehörige Mittelpunkt als grünes „+“. Die einzelnen Messpunkte aus ipContourPoints
werden als grüne x eingezeichnet. Zudem stehen oben links der Bearbeitungsanteil und die benötigte Rechenzeit. Für die vorgegebenen Parameter sieht das Ergebnis für das Eingangsbild LocateEllipse_T.bmp folgendermaßen aus:
Erhöht man nun die Anzahl der Suchlinien von 40 auf 180, wird die benötigte Rechenzeit wie erwartet linear dazu erhöht:
Da die Rechenzeit in der Praxis je nach Eingangsbild etwas schwankt, ist es oftmals sinnvoll, die benötigte Rechenzeit von außen mittels Watchdog zu begrenzen. Setzt man z. B. die Anzahl der Suchlinien auf 120 und den Watchdog timeout tStop
auf 2000 (abhängig von der verwendeten CPU), so wird die Funktion bei etwa 85% Bearbeitungsanteil abgebrochen und die bis dahin verfügbaren Teilergebnisse zurückgeliefert:
Da der Algorithmus nur an dezidierten Stellen unterbrochen werden und die Teilergebnisse zurückgegeben werden können, bricht die Funktion nicht exakt nach 2000µs ab, sondern benötigt etwas länger, was es bei der Wahl der Abbruchzeit zu berücksichtigen gilt. Die maximal zusätzlich benötigte Zeit ist generell abhängig von dem Algorithmus und der Parametrierung.
Obwohl aufgrund des Abbruchs die Ergebnisse einiger Suchlinien fehlen (4 größere Lücken zwischen den grünen x), konnte die Ellipse trotzdem korrekt approximiert werden, d. h. die Teilergebnisse können sinnvoll weiterverwendet werden, so als wäre die Funktion zu 100% abgearbeitet worden.
In begrenztem Maße ist dies ebenfalls möglich, wenn die Position eines Objekts zum Teil außerhalb des definierten Suchbereichs liegt, z. B. weil ein vorheriger Positionierungsschritt fehlerhaft war. Setzt man z. B. fMinRadius
auf 180, so liegt bei einigen Beispielbildern ein Teil der Außenkontur außerhalb des vorgegebenen Bereichs. Trotzdem sind noch genügend Suchpunkte vorhanden, um daraus eine Ellipse zu approximieren. In der Praxis sollte man sich allerdings nicht darauf verlassen und den Suchbereich groß genug wählen: