find_box_3d
— Findet Boxen in 3D-Daten.
find_box_3d( : : ObjectModel3DScene, SideLen1, SideLen2, SideLen3, MinScore, GenParam : GrippingPose, Score, ObjectModel3DBox, BoxInformation)
find_box_3d
findet Boxen im 3D-Objektmodell
ObjectModel3DScene
und gibt für jede Box die Pose eines Greifpunktes
GrippingPose
, ein 3D-Objektmodell ObjectModel3DBox
, eine
Bewertung Score
und ein Dictionary BoxInformation
mit
weiteren Informationen zu den gefundenen Boxen zurück.
Die Kantenlängen der zu suchenden Boxen werden in
SideLen1
, SideLen2
und SideLen3
übergeben.
Jede dieser Längen besteht aus einem Tupel
mit zwei Werten, die den möglichen Wertebereich der Kantenlänge angeben.
Wenn zu erwarten ist, dass nur eine Seite der Box zu sehen ist,
kann SideLen3
auch auf -1 gesetzt werden.
Der Parameter MinScore
setzt die Mindestbewertung für die
zurückgegebenen Boxen fest. Boxen, die eine Bewertung unterhalb dieses Wertes
haben, werden nicht zurückgegeben.
ObjectModel3DScene
muss ein XYZ-Mapping aufweisen, was beispielsweise
der Fall ist, wenn das Modell mit xyz_to_object_model_3d
erzeugt
wurde.
Ein üblicher Arbeitsablauf zum Finden von 3D-Boxen in 3D-Daten sieht wie folgt aus:
Die 3D-Daten werden entweder als XYZ-Bilder, oder direkt als 3D-Objektmodell mit XYZ-Mapping erzeugt.
Es muss sichergestellt werden, dass die Koordinatensysteme der Bilder der notwendigen Konvention entsprechen. Details zu den Koordinatensystemen finden sich weiter unten im Abschnitt „Problembehandlung“.
Es sollte so viel wie möglich vom Hintergrund und von anderen
Störobjekten entfernt werden, die nicht Teil einer Box sind.
Dies macht das Auffinden von Boxen robuster und schneller.
Dafür kann z.B. threshold
und reduce_domain
auf die XYZ-Bilder angewendet werden, um im Anschluss das Modell mit
xyz_to_object_model_3d
zu erzeugen.
Andere Möglichkeiten zur Verbesserung der Laufzeit finden sich weiter
unten im dem Abschnitt über Problembehandlung.
Wenn die 3D-Daten als XYZ-Bilder vorliegen, müssen sie
mittels xyz_to_object_model_3d
in ein
3D-Objektmodell konvertiert werden.
Die ungefähren Seitenlängen der zu findenden Boxen müssen
ermittelt werden. Zu beachten ist, dass spätere Änderungen
dieser Seitenlängen möglicherweise auch die Anpassung
anderer Parameter notwendig macht, etwa MinScore
.
find_box_3d
wird aufgerufen. Als Parameter wird
das 3D-Objektmodell der Szene sowie die ungefähren
Seitenlängen übergeben.
Mittels der Prozedur visualize_object_model_3d
können,
wenn notwendig, die Ergebnisse visualisiert werden.
Die gefundenen Boxen werden auf verschiedene Weisen zurückgegeben.
Zunächst wird für jede Box die Pose eines Greifpunktes in
GrippingPose
zurückgegeben.
Ist nur eine Seite der Box sichtbar, dann liegt das Zentrum der Greifpose
in der Mitte dieser Seite und ihre z-Achse ist senkrecht zur Boxseite und
in die gleiche Richtung wie die z-Achse des Koordinatensystems der Szene
ausgerichtet.
Wenn mehrere Seiten der Box sichtbar sind, liegt die Pose des Greifpunkts
in der Mitte der Seite, die am meisten zur z-Achse des Koordinatensystems
der Szene ausgerichtet ist und die z-Achse der Pose ist wieder senkrecht
auf diese Seite und in Richtung der z-Achse des Koordinatensystems der
Szene ausgerichtet.
Für die x-Achse der Pose wird die Boxachse gewählt, die am besten mit
der x-Achse des Szenenkoordinatensystems ausgerichtet ist.
Die y-Achse wird aus der x- und z-Achse berechnet.
Die Boxen werden außerdem in ObjectModel3DBox
als vermaschtes
3D-Objektmodell zurückgegeben.
Dies ermöglicht eine einfache Visualisierung der Ergebnisse.
Für jede gefundene Box wird in Score
eine Bewertung zwischen
0 und 1 zurückgegeben.
Diese gibt an, wie gut die Box und ihre Kanten sichtbar sind,
und wie gut die gefundene Box zu den spezifizierten Kantenlängen
passt.
Schlussendlich wird mit BoxInformation
ein Dictionary zurückgegeben,
welches weitere Informationen über die Ergebnisse enthält.
Diese können mit get_dict_param
und get_dict_tuple
abgerufen werden, oder mit dem Handle Inspect-Fenster in HDevelop
untersucht werden.
Das Dictionary BoxInformation
enthält folgende Schlüssel:
'results'
:
Dieser Schlüssel verweist auf ein Dictionary, das die gefundenen Boxen
enthält. Diese sind absteigend nach Bewertung sortiert und sind durch
aufsteigende Integer-Werte (Startwert 0
) als Schlüssel referenziert.
Für jede gefundene Box wird ein Dictionary mit folgenden Schlüsseln zurückgegeben:
'box_pose'
:Beschreibt die Pose der Box relativ zum Koordinatensystem der Szene. Diese Pose wird zur Visualisierung der Box verwendet.
'box_length_x'
,
'box_length_y'
'box_length_z'
:
Die Kantenlängen der gefundenen Box entsprechend der Pose
'box_pose'
.
box_length_x
und box_length_y
enthalten immer einen
positiven Wert. Wenn nur eine Seite der Box sichtbar ist wird
box_length_z
auf 0 gesetzt.
'gripping_pose'
:
Entspricht der Pose, die in GrippingPose
zurückgegeben wird.
'gripping_length_x'
,
'gripping_length_y'
'gripping_length_z'
:
Die Kantenlängen der gefundenen Box entsprechend der Pose
GrippingPose
.
gripping_length_x
und gripping_length_y
enthalten immer
einen positiven Wert. Wenn nur eine Seite der Box sichtbar ist wird
gripping_length_z
auf 0 gesetzt.
'score'
:
Entspricht der Bewertung, die in Score
zurückgegeben wird.
'one_side_only'
:Gibt an, ob nur eine Seite der Box sichtbar ist ('true' ) oder mehr ('false' ).
'gen_param'
:
Dieses Dictionary enthält die Parameter, die an find_box_3d
übergeben
wurden.
SideLen1
, SideLen2
, und SideLen3
sind in einem
Tupel mit dem Schlüssel 'lengths'
zusammengefasst. Der Schlüssel
'min_score'
verweist auf MinScore
.
Die weiteren Schlüssel sind analog zu den generischen Parametern im
Dictionary GenParam
bezeichnet (siehe unten).
'sampled_edges'
:Dieses 3D-Objektmodell mit abgetasteten Kanten enthält die Blickrichtung der Kantenpunkte als Normalenvektoren.
'sampled_edges_direction'
:
Dieses 3D-Objektmodell mit abgetasteten Kanten (analog zu
'sampled_edges'
) enthält die Kantenrichtungen der
Kantenpunkte als Normalenvektoren.
'sampled_scene'
:Dieser Schlüssel enthält die abgetastete Szene, in der die Boxen gesucht werden. Sie kann zur Visualisierung oder zur Überprüfung der Abtastdistanz verwendet werden.
'sampled_reference_points'
:Dieser Schlüssel enthält ein 3D-Objektmodell mit allen Punkten der 3D-Szene, die als Referenzpunkte für das Matching verwendet wurde. Für jeden dieser Referenzpunkte wird eine optimale Box-Pose berechnet, in der Annahme, dass sich der Punkt auf der Oberfläche der Box befindet.
Weitere generische Parameter können als Schlüssel-Tupeldaten-Paare in das
Dictionary GenParam
übergeben werden um den Matching-Vorgang zu
verbessern. Die folgenden Parameternamen
fungieren als Schlüssel zu den dazugehörigen Tupeldaten (siehe
create_dict
und set_dict_tuple
).
'3d_edges'
:
Mit diesem Schlüssel können die zu verwendenden 3D-Kanten übergeben
werden.
Als Wert muss ein 3D-Objektmodell übergeben werden. Dieses Modell wird
üblicherweise mit edges_object_model_3d
erzeugt , und kann bei
Bedarf noch weiter gefiltert werden um z.B. Ausreißer zu entfernen.
Wenn dieser Parameter nicht angegeben wird, werden die Kanten
intern aus der Szene ähnlich zum Operator edges_object_model_3d
extrahiert.
'3d_edge_min_amplitude'
:
Legt die minimale Amplitude einer Unstetigkeit fest, um als Kante
klassifiziert zu werden.
Falls Kanten manuell in '3d_edges'
übergeben werden ist zu
beachten, dass dieser Parameter ignoriert wird.
Andernfalls verhält sich '3d_edge_min_amplitude'
wie
MinAmplitude
für den Operator edges_object_model_3d
.
Assertion: '3d_edge_min_amplitude'
>= 0
Standardwert: 10% der kleinsten Boxdiagonale.
'viewpoint'
,
'max_gap'
:
Wenn keine 3D-Kanten mittels '3d_edges'
übergeben wurden,
werden diese intern automatisch extrahiert.
Die hier aufgeführten Parameter steuern diese Kantenextraktion.
'viewpoint'
und 'max_gap'
haben die gleiche Bedeutung wie in edges_object_model_3d
.
'remove_outer_edges'
:Entfernt die am äußersten gelegenen Kanten (wenn auf 'true' gesetzt). Für Anwendungen bei denen ein Griff in die Kiste erfolgt kann dies zum Beispiel nützlich sein, um die Kiste aus den 3D-Daten zu entfernen.
Standardwert: 'false'
Mögliche Werte: 'false' , 'true'
'max_num_boxes'
:
Begrenzt die Anzahl an zurückgegebenen Boxen.
Standardmäßig gibt find_box_3d
alle gefundenen Boxen zurück,
deren Bewertung über MinScore
liegt.
Mit diesem Parameter kann die Anzahl entsprechend begrenzt werden.
Standardwert: 0 (alle Boxen zurückgeben)
'box_type'
:Legt die Arten von Boxen fest, die gesucht werden sollen. Es kann nur nach Boxen gesucht werden, bei denen nur eine Seite sichtbar ist ('single_side_visible' ), nach Boxen, bei denen alle drei Kantenlängen sichtbar sind ('full_box_visible' ), oder nach allen Boxen ('all' ).
Standardwert: 'all'
Mögliche Werte: 'all' , 'single_side_visible' , 'full_box_visible'
Um die Ergebnisse der Boxerkennung besser zu verstehen, können einige
der intern verwendeten Daten mittels get_dict_tuple
aus BoxInformation
ausgelesen werden
Die abgetastete Szene kann mit dem Schlüssel
'sampled_scene'
ausgelesen werden.
Das Finden von kleineren Boxen braucht eine dichter abgetastete
Szene, was die Boxerkennung langsamer macht.
Die abgetasteten 3D-Kanten können mit den Schlüsseln
'sampled_edges'
und 'sampled_edges_directions'
.
ausgelesen werden.
Die beiden 3D-Objektmodelle enthalten die gleichen Punkte,
allerdings sind in 'sampled_edges'
die Normalenrichtungen auf die Blickrichtungen der Kanten gesetzt,
während in 'sampled_edges_directions'
die Normalenrichtungen
auf die Kantenrichtung gesetzt werden.
Die Kantenrichtung steht senkrecht auf den Kanten und
zeigt nach außen.
Die 3D-Kantenextraktion wird mit find_box_3d
intern analog
zu edges_object_model_3d
durchgeführt.
Damit die Kantenrichtungen korrekt extrahiert werden,
müssen die Bilder der folgenden Konvention folgen:
Im X-Bild müssen die Werte von links nach rechts aufsteigen,
im Y-Bild müssen die Werte von oben nach unten aufsteigen.
Im Z-Bild müssen die Werte von vorne nach hinten aufsteigen,
weiterhin müssen alle Werte positiv sein (d.h. die z-Achse des
Sensors zeigt nach vorne).
Wenn diese Voraussetzungen nicht erfüllt sind, werden die falschen 3D-Kanten extrahiert, oder die extrahierten 3D-Kanten haben falsche Kantenrichtungen.
Wenn nur ein 3D-Objektmodell mit Mappings zu Verfügung steht,
aber keine Bilder, können die Bilder mittels
object_model_3d_to_xyz
mit dem Modus 'from_xyz_map'
rekonstruiert werden.
Die Koordinatenrichtungen können z.B. durch eine Transformation
des 3D-Objektmodells mittels
rigid_trans_object_model_3d
geändert werden,
oder durch Skalierung der X-, Y- und Z-Bilder mittels scale_image
.
Im letzten Fall ist darauf zu achten, dass die Rechtshändigkeit des
Koordinatensystems nicht geändert wird.
Zur Überprüfung des Koordinatensystems kann der „Automatic Value Check“
in der Prozedur debug_find_surface_model
verwendet werden.
Wenn find_box_3d
zu lange dauert, können die folgenden
Schritte helfen, die Laufzeit zu verringern.
Entfernen von Hintergrund und anderen Störobjekten: Eine deutliche Verbesserung der Laufzeit und Genauigkeit kann i.d.R. durch das Entfernen von möglichst vielen Teilen der Szene erreicht werden, die nicht auf Boxen liegen.
Übliche Ansätze zum Entfernen dieser Daten sind:
Schwellwerte auf den X-, Y- und Z-Koordinaten,
entweder durch threshold
und reduce_domain
auf den XYZ-Bildern vor dem Aufruf von xyz_to_object_model_3d
,
oder durch die Anwendung von
select_points_object_model_3d
direkt auf
das 3D-Objektmodell, welches die Szene beinhaltet.
Einige Sensoren liefern neben den 3D-Daten auch Intensitätsbilder zurück. Filter, die auf diesen Bildern aufbauen, können ggf. ebenfalls verwendet werden um Hintergrund zu entfernen.
Falls die Szene zum Sensor statisch ist und sich der Hintergrund
in seiner Art und Lage nicht ändert, z.B. wenn ein Sensor
fest über einem Laufband verbaut ist, kann der Hintergrund
einmalig in einer Szene ohne Boxen aufgenommen werden,
und in späteren Szenen mittels
sub_image
und threshold
auf den Z-Bildern
entfernt werden.
Erhöhung der Mindestbewertung:
Ein Erhöhen der Mindestbewertung MinScore
kann dazu führen,
dass Boxen während der Erkennung schon früher verworfen werden können.
Vergrößern der kleinstmöglichen Box:
Je kleiner die kleinstmögliche Boxseite ist, desto höher die Laufzeit
von find_box_3d
, da die Szene dichter abgetastet
werden muss.
Kann z.B. eine Box nur von einer Seite gesehen werden, könnte
es sinnvoll sein, SideLen3
auf -1 zu
setzen.
Weiterhin kann mit 'box_type'
eingestellt werden,
welche Arten von Boxen gesucht werden sollen.
Manuelle Suche und Vorverarbeitung der Kanten:
Die 3D-Kanten können manuell mittels edges_object_model_3d
aus der Szene extrahiert werden und über den generischen
Parameter '3d_edges'
an den Operator übergeben
werden.
Eine solche manuelle Extraktion ermöglicht ein weiteres
Filtern der 3D-Kanten.
Dieser Operator unterstützt Cancel-Timeouts und Interrupts.
ObjectModel3DScene
(input_control) object_model_3d →
(handle)
Handle des 3D-Objektmodells, welches die Szene enthält.
SideLen1
(input_control) real-array →
(real)
Länge der ersten Boxkante.
SideLen2
(input_control) real-array →
(real)
Länge der zweiten Boxkante.
SideLen3
(input_control) real-array →
(real)
Länge der dritten Boxkante.
Defaultwert: -1
MinScore
(input_control) real →
(real / integer)
Mindestbewertung der zurückgegebenen Boxen.
Defaultwert: 0.25
Restriktion: 0 <= MinScore <= 1
GenParam
(input_control) dict →
(handle)
Dictionary für generische Parameter.
Defaultwert: []
GrippingPose
(output_control) pose(-array) →
(real / integer)
Greifposen der gefundenen Boxen.
Score
(output_control) real-array →
(real)
Bewertungen der gefundenen Boxen.
ObjectModel3DBox
(output_control) object_model_3d-array →
(handle)
Gefundene Boxen als 3D-Objektmodell.
BoxInformation
(output_control) dict →
(handle)
Weitere Informationen als Dictionary.
Wenn alle Parameter korrekt sind liefert find_box_3d
den
Wert 2 (H_MSG_TRUE).
Gegebenenfalls wird eine Fehlerbehandlung durchgeführt.
read_object_model_3d
,
xyz_to_object_model_3d
gen_box_object_model_3d
,
get_dict_tuple
3D Metrology