KlassenKlassenKlassenKlassen | | | | Operatoren

edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix (Operator)

Name

edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix — Sub-pixel-genaue Kantendetektion mit Deriche-, Lanser-, Shen- oder Canny-Filtern.

Signatur

edges_sub_pix(Image : Edges : Filter, Alpha, Low, High : )

Herror edges_sub_pix(const Hobject Image, Hobject* Edges, const char* Filter, double Alpha, const Hlong Low, const Hlong High)

Herror T_edges_sub_pix(const Hobject Image, Hobject* Edges, const Htuple Filter, const Htuple Alpha, const Htuple Low, const Htuple High)

Herror edges_sub_pix(Hobject Image, Hobject* Edges, const HTuple& Filter, const HTuple& Alpha, const HTuple& Low, const HTuple& High)

HXLDContArray HImage::EdgesSubPix(const HTuple& Filter, const HTuple& Alpha, const HTuple& Low, const HTuple& High) const

void EdgesSubPix(const HObject& Image, HObject* Edges, const HTuple& Filter, const HTuple& Alpha, const HTuple& Low, const HTuple& High)

HXLDCont HImage::EdgesSubPix(const HString& Filter, double Alpha, const HTuple& Low, const HTuple& High) const

HXLDCont HImage::EdgesSubPix(const HString& Filter, double Alpha, Hlong Low, Hlong High) const

HXLDCont HImage::EdgesSubPix(const char* Filter, double Alpha, Hlong Low, Hlong High) const

void HOperatorSetX.EdgesSubPix(
[in] IHUntypedObjectX* Image, [out] IHUntypedObjectX*Edges, [in] VARIANT Filter, [in] VARIANT Alpha, [in] VARIANT Low, [in] VARIANT High)

IHXLDContX* HImageX.EdgesSubPix(
[in] BSTR Filter, [in] double Alpha, [in] VARIANT Low, [in] VARIANT High)

static void HOperatorSet.EdgesSubPix(HObject image, out HObject edges, HTuple filter, HTuple alpha, HTuple low, HTuple high)

HXLDCont HImage.EdgesSubPix(string filter, double alpha, HTuple low, HTuple high)

HXLDCont HImage.EdgesSubPix(string filter, double alpha, int low, int high)

Beschreibung

edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix dient der Detektion von Stufenkanten mittels rekursiver Filter (nach Deriche, Lanser und Shen) bzw. mittels des konventionell über Filtermasken realisierten „Derivative of Gaussian“ Filter, den auch Canny verwendet. Konkret stehen somit die Kantenoperatoren

'deriche1', 'lanser1', 'deriche2', 'lanser2', 'shen', 'mshen', 'canny', 'sobel' und 'sobel_fast'

zur Verfügung (Parameter FilterFilterFilterFilterFilterfilter).

Die extrahierten Kanten werden als sub-pixel-genaue XLD-Konturen in EdgesEdgesEdgesEdgesEdgesedges zurückgeliefert. Für alle Kantenoperatoren außer 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" werden für jeden Kantenpunkt die folgenden Attribute definiert (siehe get_contour_attrib_xldget_contour_attrib_xldGetContourAttribXldget_contour_attrib_xldGetContourAttribXldGetContourAttribXld):

'edge_direction'"edge_direction""edge_direction""edge_direction""edge_direction""edge_direction" Die Kantenrichtung
'angle'"angle""angle""angle""angle""angle" Richtung der Normalenvektoren der Kontur (so orientiert, dass die Normalenvektoren auf die rechte Seite der Kontur in Durchlaufrichtung der Kontur zeigen; die Winkel sind bzgl. der Zeilenachse des Bildes angegeben.)
'response'"response""response""response""response""response" Die Amplitude der Kante

Die „Filterbreite“ (bzw. das Einzugsgebiet der Filter) ist für alle Kantenoperatoren außer 'sobel'"sobel""sobel""sobel""sobel""sobel" und 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" frei wählbar und lässt sich mittels info_edgesinfo_edgesInfoEdgesinfo_edgesInfoEdgesInfoEdges für konkrete Werte des Parameters AlphaAlphaAlphaAlphaAlphaalpha abschätzen. Bei allen Filtern (Deriche-, Lanser- und Shen-Filtern) bewirkt eine Vergrößerung von AlphaAlphaAlphaAlphaAlphaalpha eine Verkleinerung der „Filterbreite“. Die einzige Ausnahme bildet der Canny-Filter, bei dem sich für größer werdende Werte für AlphaAlphaAlphaAlphaAlphaalpha auch die „Filterbreite“ vergrößert. „Breite“ Filter weisen eine höhere Rauschinvarianz, aber auch ein verringertes Auflösungsvermögen für Bilddetails auf. Nicht-rekursive Filter, wie hier die Canny-Filter, werden häufig mittels Filtermasken realisiert. In diesem Fall erhöht sich die Laufzeit natürlich mit wachsender Filterbreite. Die Laufzeit der rekursiven Filter ist hingegen konstant. Das Einzugsgebiet der Deriche-, Lanser bzw. Shen-Filter ist also ohne Mehraufwand beliebig vergrößerbar. Der daraus resultierennde Laufzeitvorteil gegenüber dem Canny-Operator nimmt naturgemäß mit wachsender „Filterbreite“ zu. Zur Randbehandlung wird bei den rekursiven Filtern angenommen, das Bildsignal falle außerhalb des Bildes auf Null ab. Beim Canny-Operator wird hingegen das Bild durch „Vervielfachung“ der Randpunkte fortgesetzt. Das Signal-Rausch-Verhältnis der FilterFilterFilterFilterFilterfilter ist vergleichbar, wenn AlphaAlphaAlphaAlphaAlphaalpha wie folgt gewählt wird:

     Alpha('lanser1')   = Alpha('deriche1'),
     Alpha('deriche2')  = Alpha('deriche1') / 2,
     Alpha('lanser2')   = Alpha('deriche2'),
     Alpha('shen')      = Alpha('deriche1') / 2,
     Alpha('mshen')     = Alpha('shen'),
     Alpha('canny')     = 1.77 / Alpha('deriche1').

Die hier eingesetzten rekursiven Filter verzerren in ihrer ursprünglichen Form ('deriche1', 'deriche2', 'shen') die Amplituden diagonaler Kanten. Diese Fehler sind in den zugehörigen modifizierten Operatoren 'lanser1', 'lanser2' und 'mshen' (bei unveränderter Laufzeit) beseitigt.

Bei relativ kleinem Einzugsgebiet der Filter (11 x 11) Bildpunkte, etwa für Alpha ('lanser2' = 0.5) liefern alle (modifizierten) Operatoren praktisch identische Ergebnisse. Erst bei „breiteren“ Filtern zeigen sich Unterschiede: Insbesondere fallen dann die Shen-basierten Operatoren qualitativ ab. Allerdings sind sie die schnellsten der implementierten Operatoren, die eine freie Wahl der Filterbreite erlauben, dicht gefolgt von den Deriche-Operatoren. Die beiden Sobel-Filter, die eine feste Maskengröße von (3 x 3) verwenden, sind schneller als die anderen Filter, wobei der Filter 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" erheblich schneller ist als der Filter 'sobel'"sobel""sobel""sobel""sobel""sobel".

edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix verknüpft die einzelnen Kantenpunkte mit einem Hysterese-Schwellenwert-artigem Verfahren zu Kanten, wie es auch in lines_gausslines_gaussLinesGausslines_gaussLinesGaussLinesGauss verwendet wird. Dabei werden Punkte, deren Amplitude größer als HighHighHighHighHighhigh ist, sofort als sichere Kantenpunkte akzeptiert. Punkte, deren Amplitude kleiner als LowLowLowLowLowlow ist, werden sofort verworfen. Alle Punkte, die eine zweite Ableitung zwischen diesen zwei Werten besitzen, werden akzeptiert, wenn sie durch einen Pfad mit sicheren Punkten verbunden sind (siehe lines_gausslines_gaussLinesGausslines_gaussLinesGaussLinesGauss und hysteresis_thresholdhysteresis_thresholdHysteresisThresholdhysteresis_thresholdHysteresisThresholdHysteresisThreshold).

Da Kantenextraktoren oftmals bestimmte Kreuzungspunkte nicht extrahieren können, kann durch Anhängen von '_junctions'"_junctions""_junctions""_junctions""_junctions""_junctions" an die oben beschriebenen Werte von FilterFilterFilterFilterFilterfilter versucht werden, diese mit anderen Mitteln zu extrahieren. Dieser Modus ist analog zu dem bei lines_gausslines_gaussLinesGausslines_gaussLinesGaussLinesGauss verfügbaren Modus zur Vervollständigung von Kreuzungspunkten.

Der Kantenoperator 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" hat dieselbe Semantik wie alle anderen Kantenoperatoren, basiert intern aber auf einer stark vereinfachten Variante der einzelnen Schritte (Hysterese-Schwellenwert-Operation, Verknüpfung der Kantenpunkte, Extraktion der Subpixel-Position). Daher können die Ergebnisse von 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" in manchen Fällen eine geringere Genauigkeit als die Ergebnisse der anderen Filter aufweisen und andere Kantenteile selektieren.

edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix kann für die Filtertypen 'canny'"canny""canny""canny""canny""canny" und 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" auf OpenCL Geräten ausgeführt werden. Dazu werden bis zu Breite*Höhe*29 Bytes pinned Speicher benötigt. Daher sollte der pinned Speichercache auf mindestens diese Größe gesetzt werden (mit set_compute_device_paramset_compute_device_paramSetComputeDeviceParamset_compute_device_paramSetComputeDeviceParamSetComputeDeviceParam und dem Parameter 'pinned_mem_cache_capacity'"pinned_mem_cache_capacity""pinned_mem_cache_capacity""pinned_mem_cache_capacity""pinned_mem_cache_capacity""pinned_mem_cache_capacity", oder die Verwendung von pinned Speicher komplett abzuschalten (mit set_compute_device_paramset_compute_device_paramSetComputeDeviceParamset_compute_device_paramSetComputeDeviceParamSetComputeDeviceParam und dem Parameter 'alloc_pinned'"alloc_pinned""alloc_pinned""alloc_pinned""alloc_pinned""alloc_pinned") - dann wird der normale Speichercache verwendet. Die Ergebnisse können dabei von dem der CPU-Implementierung abweichen.

Achtung

Da edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix für den 'canny'"canny""canny""canny""canny""canny"-Filter intern Gauss-Faltung verwendet, gelten dieselben Einschränkungen wie für derivate_gaussderivate_gaussDerivateGaussderivate_gaussDerivateGaussDerivateGauss: AlphaAlphaAlphaAlphaAlphaalpha muss so gewählt werden, dass die resultierende Filtermaske kleiner als 129 Pixel ist.

In HALCON XL kann edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix gar nicht auf OpenCL-Geräten ausgeführt werden, da dafür doppelt genaue Fließkommaarithmetik notwendig wäre, OpenCL-Geräte aber nur für einfach genaue Fließkommaarithmetik optimiert sind.

Beachten Sie, dass Filteroperatoren eventuell unerwartete Resultate ausgeben, wenn ein Bild mit einer reduzierten Domäne als Input übergeben wird. Weitere Informationen können im Kapitel Filter gefunden werden.

Parallelisierung

Parameter

ImageImageImageImageImageimage (input_object)  singlechannelimage objectHImageHImageHImageHImageXHobject (byte / uint2 / real)

Eingabebild.

EdgesEdgesEdgesEdgesEdgesedges (output_object)  xld_cont-array objectHXLDContHXLDContHXLDContArrayHXLDContXHobject *

Extrahierte Kanten.

FilterFilterFilterFilterFilterfilter (input_control)  string HTupleHTupleHTupleVARIANTHtuple (string) (string) (HString) (char*) (BSTR) (char*)

Gewünschter Kanten-Operator.

Defaultwert: 'canny' "canny" "canny" "canny" "canny" "canny"

Werteliste: 'canny'"canny""canny""canny""canny""canny", 'canny_junctions'"canny_junctions""canny_junctions""canny_junctions""canny_junctions""canny_junctions", 'deriche1'"deriche1""deriche1""deriche1""deriche1""deriche1", 'deriche1_junctions'"deriche1_junctions""deriche1_junctions""deriche1_junctions""deriche1_junctions""deriche1_junctions", 'deriche2'"deriche2""deriche2""deriche2""deriche2""deriche2", 'deriche2_junctions'"deriche2_junctions""deriche2_junctions""deriche2_junctions""deriche2_junctions""deriche2_junctions", 'lanser1'"lanser1""lanser1""lanser1""lanser1""lanser1", 'lanser1_junctions'"lanser1_junctions""lanser1_junctions""lanser1_junctions""lanser1_junctions""lanser1_junctions", 'lanser2'"lanser2""lanser2""lanser2""lanser2""lanser2", 'lanser2_junctions'"lanser2_junctions""lanser2_junctions""lanser2_junctions""lanser2_junctions""lanser2_junctions", 'mshen'"mshen""mshen""mshen""mshen""mshen", 'mshen_junctions'"mshen_junctions""mshen_junctions""mshen_junctions""mshen_junctions""mshen_junctions", 'shen'"shen""shen""shen""shen""shen", 'shen_junctions'"shen_junctions""shen_junctions""shen_junctions""shen_junctions""shen_junctions", 'sobel'"sobel""sobel""sobel""sobel""sobel", 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast", 'sobel_junctions'"sobel_junctions""sobel_junctions""sobel_junctions""sobel_junctions""sobel_junctions"

Werteliste (für Compute Devices): 'canny'"canny""canny""canny""canny""canny", 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast"

AlphaAlphaAlphaAlphaAlphaalpha (input_control)  real HTupleHTupleHTupleVARIANTHtuple (real) (double) (double) (double) (double) (double)

Filterparameter: kleine Werte bewirken starke Glättung, also auch weniger Bilddetails (bei 'canny' umgekehrt).

Defaultwert: 1.0

Wertevorschläge: 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 0.9, 1.1

Typischer Wertebereich: 0.2 ≤ Alpha Alpha Alpha Alpha Alpha alpha ≤ 50.0

Minimale Schrittweite: 0.01

Empfohlene Schrittweite: 0.1

Restriktion: Alpha > 0.0

LowLowLowLowLowlow (input_control)  integer HTupleHTupleHTupleVARIANTHtuple (integer / real) (int / long / double) (Hlong / double) (Hlong / double) (Hlong / double) (Hlong / double)

Untere Schwelle für Hysterese-Schwellenwertoperation.

Defaultwert: 20

Wertevorschläge: 5, 10, 15, 20, 25, 30, 40

Typischer Wertebereich: 1 ≤ Low Low Low Low Low low ≤ 255

Minimale Schrittweite: 1

Empfohlene Schrittweite: 5

Restriktion: Low > 0

HighHighHighHighHighhigh (input_control)  integer HTupleHTupleHTupleVARIANTHtuple (integer / real) (int / long / double) (Hlong / double) (Hlong / double) (Hlong / double) (Hlong / double)

Obere Schwelle für Hysterese-Schwellenwertoperation.

Defaultwert: 40

Wertevorschläge: 10, 15, 20, 25, 30, 40, 50, 60, 70

Typischer Wertebereich: 1 ≤ High High High High High high ≤ 255

Minimale Schrittweite: 1

Empfohlene Schrittweite: 5

Restriktion: High > 0 && High >= Low

Beispiel (HDevelop)

read_image(Image,'fabrik')
edges_sub_pix(Image,Edges,'lanser2',0.5,20,40)

Beispiel (C)

read_image(&Image,"fabrik");
edges_sub_pix(Image,&Edges,"lanser2",0.5,20,40);

Beispiel (HDevelop)

read_image(Image,'fabrik')
edges_sub_pix(Image,Edges,'lanser2',0.5,20,40)

Beispiel (HDevelop)

read_image(Image,'fabrik')
edges_sub_pix(Image,Edges,'lanser2',0.5,20,40)

Beispiel (HDevelop)

read_image(Image,'fabrik')
edges_sub_pix(Image,Edges,'lanser2',0.5,20,40)

Beispiel (HDevelop)

read_image(Image,'fabrik')
edges_sub_pix(Image,Edges,'lanser2',0.5,20,40)

Komplexität

Sei A die Anzahl von Pixeln in der Region von ImageImageImageImageImageimage. Dann ist die Laufzeitkomplexität O(A*Alpha) für den Canny-Filter und O(A) für die rekursiven Lanser-, Deriche- und Shen-Filter.

Der Bedarf an temporären Speicher ist abhängig von der Höhe H der Region von ImageImageImageImageImageimage und der Breite W von ImageImageImageImageImageimage. Sei S = W*H, dann benötigt edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix mindestens 60*S Bytes an temporärem Speicher bei der Ausführung für alle Kantenoperatoren außer 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast". Für 'sobel_fast'"sobel_fast""sobel_fast""sobel_fast""sobel_fast""sobel_fast" werden mindestens 9*S Bytes an temporärem Speicher benötigt.

Ergebnis

Sind die Parameterwerte korrekt und tritt kein Fehler während der Berechnung auf, liefert edges_sub_pixedges_sub_pixEdgesSubPixedges_sub_pixEdgesSubPixEdgesSubPix den Wert 2 (H_MSG_TRUE). Das Verhalten bei leerer Eingabe (keine Eingabebilder vorhanden) lässt sich mittels set_system('no_object_result',<Result>)set_system("no_object_result",<Result>)SetSystem("no_object_result",<Result>)set_system("no_object_result",<Result>)SetSystem("no_object_result",<Result>)SetSystem("no_object_result",<Result>) festlegen. Gegebenenfalls wird eine Fehlerbehandlung durchgeführt.

Nachfolger

segment_contours_xldsegment_contours_xldSegmentContoursXldsegment_contours_xldSegmentContoursXldSegmentContoursXld, gen_polygons_xldgen_polygons_xldGenPolygonsXldgen_polygons_xldGenPolygonsXldGenPolygonsXld, select_shape_xldselect_shape_xldSelectShapeXldselect_shape_xldSelectShapeXldSelectShapeXld

Alternativen

sobel_dirsobel_dirSobelDirsobel_dirSobelDirSobelDir, frei_dirfrei_dirFreiDirfrei_dirFreiDirFreiDir, kirsch_dirkirsch_dirKirschDirkirsch_dirKirschDirKirschDir, prewitt_dirprewitt_dirPrewittDirprewitt_dirPrewittDirPrewittDir, robinson_dirrobinson_dirRobinsonDirrobinson_dirRobinsonDirRobinsonDir, edges_imageedges_imageEdgesImageedges_imageEdgesImageEdgesImage

Siehe auch

info_edgesinfo_edgesInfoEdgesinfo_edgesInfoEdgesInfoEdges, hysteresis_thresholdhysteresis_thresholdHysteresisThresholdhysteresis_thresholdHysteresisThresholdHysteresisThreshold, bandpass_imagebandpass_imageBandpassImagebandpass_imageBandpassImageBandpassImage, lines_gausslines_gaussLinesGausslines_gaussLinesGaussLinesGauss, lines_facetlines_facetLinesFacetlines_facetLinesFacetLinesFacet

Literatur

S.Lanser, W.Eckstein: „Eine Modifikation des Deriche-Verfahrens zur Kantendetektion“; 13. DAGM-Symposium, München; Informatik Fachberichte 290; Seite 151 - 158; Springer-Verlag; 1991.
S.Lanser: „Detektion von Stufenkanten mittels rekursiver Filter nach Deriche“; Diplomarbeit; Technische Universität München, Institut für Informatik, Lehrstuhl Prof. Radig; 1991.
J.Canny: „Finding Edges and Lines in Images“; Report, AI-TR-720; M.I.T. Artificial Intelligence Lab., Cambridge; 1983.
J.Canny: „A Computational Approach to Edge Detection“; IEEE Transactions on Pattern Analysis and Machine Intelligence; PAMI-8, vol. 6; S. 679-698; 1986.
R.Deriche: „Using Canny's Criteria to Derive a Recursively Implemented Optimal Edge Detector“; International Journal of Computer Vision; vol. 1, no. 2; S. 167-187; 1987.
R.Deriche: „Optimal Edge Detection Using Recursive Filtering“; Proc. of the First International Conference on Computer Vision, London; S. 501-505; 1987.
R.Deriche: „Fast Algorithms for Low-Level Vision“; IEEE Transactions on Pattern Analysis and Machine Intelligence; PAMI-12, no. 1; S. 78-87; 1990.
S.Castan, J.Zhao und J.Shen: „Optimal Filter for Edge Detection Methods and Results“; Proc. of the First European Conference on Computer Vision, Antibes; Lecture Notes on computer Science; no. 427; S. 12-17; Springer-Verlag; 1990.

Modul

2D Metrology


KlassenKlassenKlassenKlassen | | | | Operatoren