photometric_stereo
— Rekonstruieren einer Oberfläche mittels photometrischer Stereomessung.
photometric_stereo(Images : HeightField, Gradient, Albedo : Slants, Tilts, ResultType, ReconstructionMethod, GenParamName, GenParamValue : )
photometric_stereo
kann dazu genutzt werden, die dreidimensionale
Form eines Objekts von seiner zweidimensionalen Textur zu trennen, z.B. von
seinem Druckbild. Der Operator benötigt mindestens drei Bilder des gleichen
Objekts, aufgenommen mit unterschiedlichen bekannten
Beleuchtungsrichtungen. Die Ausrichtung der Kamera zum Objekt muss
für alle Bilder gleich sein.
Die dreidimensionale Form des Objekts wird in erster Linie in Form von lokalen Gradienten der dreidimensionalen Oberfläche berechnet. Diese Gradienten können weiter integriert werden, so dass ein Höhenmodell entsteht, d.h., ein Bild, in dem jeder Pixelwert einer relativen Höhe entspricht. Die zweidimensionale Textur wird als Albedo bezeichnet und entspricht der lokalen Lichtabsorption und Reflexionscharakteristik der Oberfläche ohne Einfluss von Schatten.
Typische Anwendungen des photometrischen Stereoverfahrens
Typische Anwendungen des photometrischen Stereoverfahrens sind das Erkennen kleiner Inkonsistenzen in einer Oberfläche, z.B. Defekten, oder das Ausschließen des Einflusses der Beleuchtungsrichtung auf Bilder, die z.B. für die Druckbildinspektion von nicht flachen Zeichen genutzt werden. Photometrisches Stereo ist nicht geeignet für die Rekonstruktion absoluter Höhen, d.h., es ist keine Alternative zu typischen 3D Rekonstruktionsansätzen wie Depth from Focus oder das Lichtschnittverfahren.
Einschränkungen des photometrischen Stereoverfahrens
photometric_stereo
basiert auf dem Algorithmus von Woodham und setzt
daher zum einen eine orthoskopische Projektion der Kamera voraus, d.h., es
muss eine telezentrische Linse oder eine Linse mit einer großen Brennweite
benutzt werden. Zum anderen wird vorausgesetzt, dass jede der Lichtquellen
parallele und gleichförmige Lichtstrahlen produziert, d.h., es müssen
telezentrische Lichtquellen mit gleichförmiger Intensität oder, als
Alternative, sehr weit entfernte Lichtquellen benutzt werden. Zusätzlich muss
das Objekt Lambertsche Oberflächeneigenschaften aufweisen, d.h., es muss
hereinkommendes Licht diffus reflektieren. Objekte oder Regionen eines
Objekts, die spiegelnde Reflexionseigenschaften aufweisen (spiegelnde oder
glänzende Oberflächen) können nicht korrekt verarbeitet werden und führen
daher zu fehlerhaften Ergebnissen.
Der Aufbau
Die Kamera mit der telezentrischen Linse wird orthogonal, d.h., rechtwinklig, zu der zu konstruierenden Szene angebracht. Die Orientierung der Kamera in Bezug auf die Szene darf sich während der Bildaufnahme nicht verändern. Im Gegensatz dazu muss sich die Orientierung der Lichtquelle in Bezug auf die Kamera in mindestens drei Bildern ändern.
Spezifizieren der Beleuchtungsrichtungen
Für jedes Bild werden die Beleuchtungsrichtungen in Form von Winkeln
innerhalb der Parameter Slants
und Tilts
angegeben. Diese
beschreiben die Richtung der Beleuchtung in Bezug auf die Szene. Zum besseren
Verständnis dieser Parameter ist zu bedenken, dass der Ansatz davon ausgeht,
dass die Lichtquelle parallele Lichtstrahlen erzeugt, die Kamera eine
telezentrische Linse hat und die Kamera orthogonal zu der zu konstruierenden
Szene angeordnet ist:
Slants
Slants
) ist der Winkel zwischen der optischen
Achse der Kamera und der Beleuchtungsrichtung.
Tilts
Tilts
wird innerhalb der
Objektebene oder einer beliebigen parallelen Ebene, z.B. der Bildebene,
gemessen. Insbesondere beschreibt er den Winkel zwischen der Richtung,
die von der Mitte des Bildes nach rechts zeigt, und der in das Bild
projizierten Beleuchtungsrichtung. D.h., beim Blick auf das Bild (oder
die korrespondierende Szene), entspricht eine Beleuchtung von rechts
einem Winkel von 0°, eine Beleuchtung von oben einem Winkel von 90°, eine
Beleuchtung von links einem Winkel von 180°, usw.
Wie oben erwähnt benötigt das photometrische Stereoverfahren mindestens drei
Bilder mit verschiedenen Beleuchtungsrichtungen. Allerdings führt die
dreidimensionale Geometrie der Objekte typischerweise zu einem
Schattenwurf. In den Schattenregionen ist die Anzahl der effektiv verfügbaren
Beleuchtungsrichtungen reduziert, so dass Mehrdeutigkeiten entstehen. Um
trotzdem ein robustes Ergebnis zu erhalten, ist Redundanz nötig. Deshalb
sollten normalerweise mehr als drei Lichtquellen mit unterschiedlichen
Beleuchtungsrichtungen gewählt werden. Eine steigende Anzahl von
Beleuchtungsrichtungen führt aber auch zu einer höheren Anzahl von zu
verarbeitenden Bildern und somit zu einer höheren Verarbeitungszeit. In den
meisten Anwendungen ist eine Anzahl von vier bis sechs Beleuchtungsrichtungen
sinnvoll. Als Faustregel sollten die Winkel in Slants
zwischen 30°
und 60° betragen. Die Winkel in Tilts
sollten gleichmäßig rund um
das zu vermessende Objekt angeordnet sein. Es ist zu beachten, dass die
Beleuchtungsrichtungen so gewählt werden müssen, dass sie nicht in der
gleichen Ebene liegen, d.h., sie müssen unabhängig sein. Ist dies nicht der
Fall, wird eine Exception-Behandlung durchgeführt.
Eingabebilder und Domänen
Die Eingabebilder müssen als Bildarray in dem Parameter Images
übergeben werden. Jedes Bild muss dabei, wie bereits erwähnt, mit
unterschiedlichen Beleuchtungsrichtungen aufgenommen worden sein. Liegen die
Bilder in einem Mehrkanalbild vor, können sie mit Hilfe von
image_to_channels
in einen Bildarray konvertiert werden. Alternativ
kann ein Bildarray mittels concat_obj
erzeugt werden.
photometric_stereo
stützt sich auf die Auswertung "photometrischer
Information", d.h., den Grauwerten, die in den Bildern gespeichert
sind. Diese Information sollte möglichst unverzerrt und genau sein. Es sollte
daher sicher gestellt sein, dass die für die Bildaufnahme verwendete Kamera
eine lineare Charakteristik aufweist. Mit dem Operator
radiometric_self_calibration
kann die Charakteristik der Kamera
bestimmt werden und mit lut_trans
können die Grauwerte im Falle
einer nicht-linearen Charakteristik korrigiert werden. Wenn genaue Messungen
benötigt werden, sollte außerdem der volle Dynamikumfang der Kamera genutzt
werden, da hierdurch genauere Grauwertinformationen erzielt werden. Aus dem
selben Grund führen Bilder mit einer Bit-Tiefe von mehr als 8 (z.B. uint2
Bilder statt Byte Bilder) zu einer besseren Genauigkeit.
Die gewählte Domäne der Eingabebilder legt fest, welcher Algorithmus intern zur Verarbeitung der Bilder benutzt wird. Es stehen drei verschiedene Algorithmen zur Verfügung:
Hat jedes Bild die volle Domäne, wird der schnellste Algorithmus verwendet. Dieser Fall ist der Standardfall und sollte für die meisten Anwendungen verwendet werden.
Teilen sich die Bilder die gleiche aber reduzierte Domäne, werden nur die Pixel der entsprechenden Domäne verarbeitet. Dieser Fall dient dazu, Bereiche des Objekts für alle Bilder auszuschließen. Typischerweise werden Bereiche ausgeschlossen, die keine Lambertschen Reflexionseigenschaften aufweisen oder die nicht von weiterem Interesse sind, z.B. dunkle Löcher in der Oberfläche.
Haben die Bilder unterschiedliche Domänen, werden nur die Grauwerte der entsprechenden Domänen verwendet. Dabei ist zu beachten, dass nur diejenigen Pixel verarbeitet werden, die in mindesten drei Bildern unabhängige Beleuchtungsrichtungen aufweisen. Dieser Fall dient dazu, Bereiche für einzelne Bilder auszuschließen. Dies können z.B. Bereiche des Objekts sein, die verfälschte photometrische Informationen enthalten, z.B. Schatten. Das Ausschließen dieser Regionen führt zu einer höheren Genauigkeit. Allerdings ist der hier benutzte Algorithmus signifikant langsamer als die Algorithmen, die bei voller Domäne oder einer identischen Domäne für alle Bilder verwendet werden.
Die Ausgabebilder
Der Operator kann Bilder für die rekonstruierten Gradienten (Gradient
),
den Albedo (Albedo
) und das Höhenmodell (HeightField
) der
Oberfläche zurückgeben:
Das Gradient
-Bild ist ein Vektorfeld, das die partiellen
Ableitungen der Oberfläche beinhaltet. Es kann z.B. als Eingabe für
reconstruct_height_field_from_gradient
verwendet werden. Für eine
Visualisierung kann man statt der Oberflächengradienten die normalisierten
Oberflächengradienten berechnen, indem man ResultType
auf
'normalized_gradient' setzt. Hierbei entsprechen die Zeilen- und Spalten-
Komponenten den Zeilen- und Spalten-Komponenten der normalisierten
Oberflächengradienten. Falls ResultType
auf 'all' gesetzt ist,
wird die Standardeinstellung von Gradient
verwendet und nicht
'normalized_gradient' .
Das Albedo
-Bild beschreibt die Relation des reflektierten Lichts
zum einfallenden Licht und hat einen Wertebereich zwischen eins (weisse
Oberfläche) und null (schwarze Oberfläche). Somit beschreibt das
Albedo-Bild eine Charakteristik der Oberfläche. Zum Beispiel bei einer
bedruckten Oberfläche entspricht es dem Druckbild mit Ausschluss des
Einflusses durch einfallendes Licht (Schatten).
Das Bild für das Höhenmodell HeightField
ist ein Bild, in dem die
Pixelwerte einer relativen Höhe entsprechen.
Im Standardfall werden alle diese ikonischen Objekte zurückgeliefert, d.h.,
der Parameter ResultType
ist auf 'all' gesetzt. Falls nur bestimmte
Ausgabebilder benötigt werden, kann ResultType
auf ein Tupel gesetzt
werden, das festlegt, welche der Ausgabebilder benötigt werden. Zur Auswahl
stehen die Werte 'gradient' , 'albedo' und 'height_field' . In bestimmten
Anwendungen, z.B. zur Oberflächeninspektion, werden nur die Bilder für
Gradient
und Albedo
benötigt. Dann kann das Ausschließen
der Oberflächenrekonstruktion die Verarbeitungszeit deutlich beschleunigen,
d.h., hier würden für ResultType
nur die Werte 'gradient' und
'albedo' , aber nicht 'height_field' , übergeben werden.
Intern ermittelt photometric_stereo
zunächst die Gradienten und, falls
benötigt, integriert diese Werte dann, um ein Höhenmodell zu erhalten. Diese
Integration wird mit den gleichen Algorithmen ausgeführt, die für den Operator
reconstruct_height_field_from_gradient
zur Verfügung stehen und mit
den Parametern ReconstructionMethod
, GenParamName
und
GenParamValue
kontrolliert werden. Für weitere Informationen zu den
Parametern verweisen wir auf die Beschreibung des Operators
reconstruct_height_field_from_gradient
. Ist ResultType
so
gesetzt, dass kein Höhenmodell zurückgegeben wird, werden diese Parameter
ignoriert.
photometric_stereo
setzt quadratische Pixel voraus. Außerdem wird
vorausgesetzt, dass die Höhen auf einem Gitter der Schrittweite 1 im
Objektraum vorliegen. Ist das nicht der Fall, d.h., wenn die Pixelgröße der
Kamera projiziert in den Objektraum von 1 abweicht, müssen die zurückgegebenen
Höhen mit der tatsächlichen Gitterschrittweite (Wert der Pixelgröße projiziert
in den Objektraum) multipliziert werden. Die Größe des Pixels im Objektraum
wird berechnet, indem die Größe des Pixels in der Kamera durch die
Vergrößerung der (telezentrischen) Linse geteilt wird.
Images
(input_object) singlechannelimage(-array) →
object (byte / uint2)
Array mit mindestens drei Bildern mit unterschiedlicher Beleuchtungsrichtung.
HeightField
(output_object) image →
object (real)
Rekonstruiertes Höhenmodell.
Gradient
(output_object) image →
object (vector_field)
Gradientenfeld der Oberfläche.
Albedo
(output_object) image →
object (real)
Albedo der Oberfläche.
Slants
(input_control) angle.deg-array →
(real / integer)
Winkel zwischen der Kamera und der Richtung der Lichtquelle (im Gradmaß).
Defaultwert: 45.0
Wertevorschläge: 1.0, 5.0, 10.0, 20.0, 40.0, 60.0, 90.0
Typischer Wertebereich: 0.0
≤
Slants
≤
180.0
(lin)
Minimale Schrittweite: 0.01
Empfohlene Schrittweite: 10.0
Tilts
(input_control) angle.deg-array →
(real / integer)
Winkel der Richtung der Lichtquelle innerhalb der Objektebene (im Gradmaß).
Defaultwert: 45.0
Wertevorschläge: 1.0, 5.0, 10.0, 20.0, 40.0, 60.0, 90.0
Typischer Wertebereich: 0.0
≤
Tilts
≤
360.0
(lin)
Minimale Schrittweite: 0.01
Empfohlene Schrittweite: 10.0
ResultType
(input_control) string-array →
(string)
Zu berechnende ikonische Ergebnisse.
Defaultwert: 'all'
Werteliste: [], 'albedo' , 'all' , 'gradient' , 'height_field' , 'normalized_gradient'
ReconstructionMethod
(input_control) string →
(string)
Typ der Rekonstruktionsmethode.
Defaultwert: 'poisson'
Werteliste: 'fft_cyclic' , 'poisson' , 'rft_cyclic'
GenParamName
(input_control) string-array →
(string)
Namen der generischen Parameter.
Defaultwert: []
Werteliste: 'caching' , 'optimize_speed'
GenParamValue
(input_control) integer-array →
(integer / real / string)
Werte der generischen Parameter.
Defaultwert: []
Werteliste: 'exhaustive' , 'free_cache' , 'no_cache' , 'patient' , 'standard' , 'use_cache'
Sind die Parameterwerte korrekt, dann liefert
photometric_stereo
den Wert TRUE, sonst eine Fehlermeldung.
3D Metrology