Measure Angle Between Edges
In diesem Beispiel wird
- mit Hilfe der Funktion F_VN_MeasureAngleBetweenEdgesExp der Winkel zwischen zwei Kanten eines Objekts vermessen
- und die Ausführungszeit mit einem Watchdog überwacht und bei Bedarf begrenzt.
Erläuterung
Nach der Festlegung der Suchfenster wurde die Suchrichtung auf TCVN_ED_LIGHT_TO_DARK
festgelegt, da in diesem Beispiel von innen nach außen gesucht wird und die Objekte heller sind als der Hintergrund.
Der Parameter nMaxThickness
, der definiert, innerhalb von wie vielen Pixeln fMinStrength
erreicht werden muss, wurde in diesem Beispiel auf den Wert „7
“ gesetzt.
Variablen
hr : HRESULT;
hrFunc : HRESULT;
ipImageIn : ITcVnImage;
ipImageInDisp : ITcVnDisplayableImage;
ipImageRes : ITcVnImage;
ipImageResDisp : ITcVnDisplayableImage;
// result
fAngle : REAL;
ipEdgePoints1 : ITcVnContainer;
ipEdgePoints2 : ITcVnContainer;
// parameters
aInnerPoint : TcVnPoint2_REAL := [635, 350];
aOuterPoint1 : TcVnPoint2_REAL := [530, 280];
aOuterPoint2 : TcVnPoint2_REAL := [790, 280];
fMinStrength : REAL := 50;
nSearchLines : UDINT := 41;
fSearchLineDist : REAL := 1;
nSubpixIter : UDINT := 10;
eAlgorithm : ETcVnEdgeDetectionAlgorithm := TCVN_EDA_INTERPOLATION;
// Watchdog
hrWD : HRESULT;
tStop : DINT := 15000;
tRest : DINT;
nFraction : UDINT;
// drawing
aLine1 : TcVnVector4_LREAL;
aLine2 : TcVnVector4_LREAL;
aColorRed : TcVnVector4_LREAL := [255, 0, 0];
aColorGreen : TcVnVector4_LREAL := [0, 175, 0];
aColorYellow : TcVnVector4_LREAL := [255, 255, 0];
sText : STRING(255);
Code
hrWD := F_VN_StartRelWatchdog(tStop, hr);
hrFunc := F_VN_MeasureAngleBetweenEdgesExp(
ipSrcImage := ipImageIn,
fAngle := fAngle
aInnerPoint := aInnerPoint,
aOuterPoint1 := aOuterPoint1
aOuterPoint2 := aOuterPoint2,
eEdgeDirection := TCVN_ED_LIGHT_TO_DARK,
fMinStrength := fMinStrength,
nSearchLines := nSearchLines,
fSearchLineDist := fSearchLineDist,
nMaxThickness := 7,
nSubpixelsIterations := nSubpixIter,
bAngleInDegrees := TRUE,
fApproxPrecision := 0.0001,
eAlgorithm := eAlgorithm,
ipEdgePoints1 := ipEdgePoints1,
ipEdgePoints2 := ipEdgePoints2,
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('Angle ', REAL_TO_STRING(fAngle));
hr := F_VN_PutTextExp(sText, ipImageRes, 25, 200, 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, 250, TCVN_FT_HERSHEY_SIMPLEX, 1.3, aColorGreen, 2, TCVN_LT_8_CONNECTED, FALSE,hr);
hr := F_VN_DrawPointExp(REAL_TO_UDINT(aInnerPoint[0]), REAL_TO_UDINT(aInnerPoint[1]), ipImageRes, TCVN_DS_CIRCLE, aColorGreen, 3, 2, TCVN_LT_8_CONNECTED, hr);
hr := F_VN_DrawPointExp(REAL_TO_UDINT(aOuterPoint1[0]), REAL_TO_UDINT(aOuterPoint1[1]), ipImageRes, TCVN_DS_X, aColorRed, 3, 2, TCVN_LT_8_CONNECTED, hr);
hr := F_VN_DrawPointExp(REAL_TO_UDINT(aOuterPoint2[0]), REAL_TO_UDINT(aOuterPoint2[1]), ipImageRes, TCVN_DS_X, aColorYellow, 3, 2, TCVN_LT_8_CONNECTED, hr);
hr := F_VN_FitLine(ipEdgePoints1, aLine1, hr);
hr := F_VN_FitLine(ipEdgePoints2, aLine2, hr);
hr := F_VN_DrawLine_TcVnVector4_LREAL(aLine1, ipImageRes, aColorGreen, 2, hr);
hr := F_VN_DrawLine_TcVnVector4_LREAL(aLine2, ipImageRes, aColorGreen, 2, hr);
hr := F_VN_DrawPointsExp(ipEdgePoints1, ipImageRes, TCVN_DS_PLUS, aColorRed, 1, 1, TCVN_LT_8_CONNECTED, hr);
hr := F_VN_DrawPointsExp(ipEdgePoints2, ipImageRes, TCVN_DS_PLUS, aColorYellow, 1, 1, TCVN_LT_8_CONNECTED, hr);
// Display source and result image
hr := F_VN_TransformIntoDisplayableImage(ipImageIn, ipImageInDisp, S_OK);
hr := F_VN_TransformIntoDisplayableImage(ipImageRes, ipImageResDisp, S_OK);
Ergebnisse
Zur Visualisierung werden zunächst aInnerPoint
als grüner Kreis, aOuterPoint1
als rotes x und aOuterPoint2
als gelbes x dargestellt. Die zugehörigen gefundenen Kantenpunkte ipEdgePoints1
, ipEdgePoints2
werden entsprechend ebenfalls in Rot bzw. Gelb eingezeichnet. Die aus den Kantenpunkten approximierten Geraden werden in Grün eingezeichnet. Links im Bild werden der berechnete Winkel fAngle
in Grad und die benötigte Rechenzeit in µs angezeigt. Für die vorgegebenen Parameter sieht das Ergebnis folgendermaßen aus:
Um ein genaueres Ergebnis zu erhalten, kann eAlgorithm
auf TCVN_EDA_APPROX_ERF
geändert werden und passend dazu nSubpixIter
auf 50
. Allerdings wird dadurch auch die benötigte Rechenzeit deutlich erhöht: