Measure Angle Between Edges

In diesem Beispiel wird

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:

Measure Angle Between Edges 1:

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:

Measure Angle Between Edges 2:

Ähnliche Beispiele