segment_contours_xld
— Segmentieren von Konturen in Liniensegmente und Kreis- oder Ellipsenbögen.
segment_contours_xld(Contours : ContoursSplit : Mode, SmoothCont, MaxLineDist1, MaxLineDist2 : )
segment_contours_xld
segmentiert die Eingabekonturen
Contours
in Linien, falls Mode
='lines' ,
in Linien und Kreisbögen, falls
Mode
='lines_circles' , oder in Linien und
Ellipsenbögen, falls Mode
='lines_ellipses' . Die
segmentierten Konturen werden in ContoursSplit
zurückgegeben. Die Unterscheidung, ob eine Ausgabekontur ein
Liniensegment oder einen Kreis- oder Ellipsenbogen darstellt,
erfolgt über das globale Konturattribut 'cont_approx'
(siehe get_contour_global_attrib_xld
). Falls
'cont_approx' =-1, liegt ein Liniensegment vor, falls
'cont_approx' =0 ein Ellipsenbogen und falls
'cont_approx' =1 ein Kreisbogen.
Intern führt segment_contours_xld
zunächst eine
Polygonapproximation der Eingabekonturen durch. Dadurch werden die
Konturen in gekrümmten Bereichen übersegmentiert. Hierauf werden
iterativ benachbarte Liniensegmente zu Kreis- bzw. Ellipsenbögen
verschmolzen, falls dadurch die Kontur besser approximiert werden
kann. Wenn in SmoothCont
ein Wert > 0 angegeben wird,
werden die Konturen zunächst geglättet (siehe
smooth_contours_xld
). Dies kann erforderlich sein, um sehr
kurze Liniensegmente bei der Polygonapproximation zu verhindern und
eine stabilere Kreis- bzw. Ellipsenanpassung zu erreichen, da durch
die Glättung Ausreißer auf den Konturen unterdrückt werden.
Die initiale Polygonapproximation wird mit dem Algorithmus von Ramer
(siehe gen_polygons_xld
) mit einem Maximalabstand von
MaxLineDist1
durchgeführt. Hierauf werden in benachbarte
Liniensegmente Kreis- bzw. Ellipsenbögen angepasst. Wenn der
Maximalabstand des so entstehenden Bogens zur Kontur kleiner ist als
der Maximalabstand der zwei betrachteten Liniensegmente, werden die
zwei Liniensegmente durch diesen Bogen ersetzt. Dieser Vorgang wird
solange wiederholt, bis keine Veränderungen mehr auftreten.
Hierauf werden die Teile der Kontur, die noch als Liniensegmente
approximiert werden, einer Polygonsegmentation mit dem
Maximalabstand MaxLineDist2
unterzogen, und die neu
entstehenden Liniensegmente wiederum zu Kreis- oder Ellipsenbögen
zusammengefasst. Dies ändert die Ausgabe natürlich nur, falls
MaxLineDist2
< MaxLineDist1
. Dieses zweistufige
Verfahren ist effizienter, als ein einstufiges Verfahren mit
MaxLineDist2
, da im ersten Schritt weniger Liniensegmente
entstehen, und dadurch die Kreis- bzw. Ellipsenanpassung weniger oft
durchgeführt werden muss. Daher können Teile der
Eingabekonturen, die sich durch lange Bögen approximieren lassen,
effizienter gefunden werden. Im zweiten Schritt werden dann Teile
der Kontur gefunden, die sich durch kurze Bögen approximieren
lassen und die Endstücke der im ersten Schritt gefundenen Konturen
werden verfeinert.
Die Ergebniskonturen sind mindestens 3 Pixel lang und umfassen mindestens 6 fortlaufende Konturpunkte der Eingabekontur. Alle Eingabekonturen mit einer Länge von weniger als 3 Pixel oder mit weniger als 6 Konturpunkten werden unverändert in die Ausgabekonturen übernommen.
Contours
(input_object) xld_cont(-array) →
object
Konturen, die segmentiert werden sollen.
ContoursSplit
(output_object) xld_cont-array →
object
Zerlegte Konturen.
Mode
(input_control) string →
(string)
Modus für die Segmentation der Konturen.
Defaultwert: 'lines_circles'
Werteliste: 'lines' , 'lines_circles' , 'lines_ellipses'
SmoothCont
(input_control) integer →
(integer)
Einzugsbereich für die Glättung der Konturen.
Defaultwert: 5
Wertevorschläge: 0, 3, 5, 7, 9
Restriktion: SmoothCont == 0 || SmoothCont >= 3 && odd(SmoothCont)
MaxLineDist1
(input_control) real →
(real)
Maximaler Abstand zwischen einer Kontur und der approximierenden Gerade (erster Durchlauf).
Defaultwert: 4.0
Wertevorschläge: 1.0, 1.5, 2.0, 2.5, 3.0, 3.5
Restriktion: MaxLineDist1 >= 0.0
MaxLineDist2
(input_control) real →
(real)
Maximaler Abstand zwischen einer Kontur und der approximierenden Gerade (zweiter Durchlauf).
Defaultwert: 2.0
Wertevorschläge: 1.0, 1.5, 2.0, 2.5, 3.0, 3.5
Restriktion: 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