Measure Angle Between Edges
In this sample,
- the function F_VN_MeasureAngleBetweenEdgesExp is used to measure the angle between two edges of an object
- and the execution time is monitored with a watchdog and limited if necessary.
Explanation
After defining the search windows, the search direction was set to TCVN_ED_LIGHT_TO_DARK
, because in this sample the search is performed from the inside to the outside and the objects are lighter than the background.
The parameter nMaxThickness
, which defines the number of pixels with which fMinStrength
must be reached, was set to "7
".
Variables
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);
Results
For visualization purposes, aInnerPoint
is first displayed as a green circle, aOuterPoint1
as a red x and aOuterPoint2
as a yellow x. The corresponding edge points ipEdgePoints1
and ipEdgePoints2
that were found are also drawn in red or yellow. The lines approximated from the edge points are drawn in green. The calculated angle fAngle
in degrees and the required computing time in µs are displayed on the left in the image. For the parameters used in this sample, the result looks like this:
To get a more accurate result, eAlgorithm
can be changed to TCVN_EDA_APPROX_ERF
and nSubpixIter
to 50
. However, this also significantly increases the computing time required: