segment_contours_xld
— Segment XLD contours into line segments and circular or elliptic arcs.
segment_contours_xld(Contours : ContoursSplit : Mode, SmoothCont, MaxLineDist1, MaxLineDist2 : )
segment_contours_xld
segments the input contours
Contours
into lines if
Mode
='lines' , into lines and circular arcs if
Mode
='lines_circles' , or into lines and elliptic
arcs if Mode
='lines_ellipses' . The segmented
contours are returned in ContoursSplit
. The information on
whether an output contour represents a line or a circular or
elliptic arc is done via the global contour attribute
'cont_approx' (see get_contour_global_attrib_xld
for further information).
If 'cont_approx' =-1, the contour is best approximated by a
line segment, if 'cont_approx' =0, by an elliptic arc, and
if 'cont_approx' =1, by a circular arc.
segment_contours_xld
first approximates the input
contours by polygons. With this, the contours are oversegmented in
curved areas. After this, neighboring line segments are substituted
by circular or elliptic arcs, respectively, if the contour can be
approximated better by an arc. If SmoothCont
is set to a
value > 0, the input contours are first smoothed (see
smooth_contours_xld
). This can be necessary to prevent very
short segments in the polygonal approximation and to achieve a more
robust fit with circular or elliptic arcs, because the smoothing
suppresses outliers on the contours.
The initial polygonal approximation is done by using the Ramer
algorithm (see gen_polygons_xld
) with a maximum distance of
MaxLineDist1
. After this, circular or elliptic arcs are
fit into neighboring line segments. If the maximum distance of the
resulting arc to the contour is smaller than the maximum distance of
the two line segments, the two line segments are replaced with the
arc. This procedure is iterated until no more changes occur.
After this, the parts of the contour that are still approximated by
line segments are again segmented with a polygonal approximation
with maximum distance MaxLineDist2
, and the newly created
line segments are merged to circular or elliptical arcs where
possible. Obviously, this changes the output only if
MaxLineDist2
< MaxLineDist1
. This two-step
approach is more efficient than a one-step approach with
MaxLineDist2
, since fewer line segments are generated in
the first step, and hence the circle or ellipse fit has to be
performed less often. Therefore, parts of the input contours that
can be approximated by long arcs can be found more efficiently. In
the second step, parts of the input contours that can be
approximated by short arcs are found and the end parts of long
arcs are refined.
The resulting contours are at least 3 pixel long and contain at least 6 successive points of the input contour. All input contours with a length less than 3 pixel or with less than 6 contour points are copied to the output contours without modifications.
Contours
(input_object) xld_cont(-array) →
object
Contours to be segmented.
ContoursSplit
(output_object) xld_cont-array →
object
Segmented contours.
Mode
(input_control) string →
(string)
Mode for the segmentation of the contours.
Default value: 'lines_circles'
List of values: 'lines' , 'lines_circles' , 'lines_ellipses'
SmoothCont
(input_control) integer →
(integer)
Number of points used for smoothing the contours.
Default value: 5
Suggested values: 0, 3, 5, 7, 9
Restriction: SmoothCont == 0 || SmoothCont >= 3 && odd(SmoothCont)
MaxLineDist1
(input_control) real →
(real)
Maximum distance between a contour and the approximating line (first iteration).
Default value: 4.0
Suggested values: 1.0, 1.5, 2.0, 2.5, 3.0, 3.5
Restriction: MaxLineDist1 >= 0.0
MaxLineDist2
(input_control) real →
(real)
Maximum distance between a contour and the approximating line (second iteration).
Default value: 2.0
Suggested values: 1.0, 1.5, 2.0, 2.5, 3.0, 3.5
Restriction: MaxLineDist2 >= 0.0
read_image (Image, 'pumpe') edges_sub_pix (Image, Edges, 'canny', 1.5, 15, 40) segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2) count_obj (ContoursSplit, Number) gen_empty_obj (Lines) gen_empty_obj (Circles) for I := 1 to Number by 1 select_obj (ContoursSplit, Contour, I) get_contour_global_attrib_xld (Contour, 'cont_approx', Type) if (Type == -1) concat_obj (Lines, Contour, Lines) else concat_obj (Circles, Contour, Circles) endif endfor fit_line_contour_xld (Lines, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, \ RowEnd, ColEnd, Nr, Nc, Dist) fit_circle_contour_xld (Circles, 'atukey', -1, 2, 0, 3, 2, Row, Column, \ Radius, StartPhi, EndPhi, PointOrder)
gen_contours_skeleton_xld
,
lines_gauss
,
edges_sub_pix
fit_line_contour_xld
,
fit_ellipse_contour_xld
,
fit_circle_contour_xld
,
get_contour_global_attrib_xld
split_contours_xld
,
get_contour_global_attrib_xld
,
smooth_contours_xld
,
gen_polygons_xld
Foundation