scene_flow_uncalib
— Berechnung des unkalibrierten Szenenflusses zwischen zwei
Stereobildpaaren.
scene_flow_uncalib(ImageRect1T1, ImageRect2T1, ImageRect1T2, ImageRect2T2, Disparity : OpticalFlow, DisparityChange : SmoothingFlow, SmoothingDisparity, GenParamName, GenParamValue : )
scene_flow_uncalib
berechnet den unkalibrierten Szenenfluss
zwischen zwei aufeinanderfolgenden rektifizierten Stereobildpaaren.
Der Szenenfluss ist die dreidimensionale Position und Bewegung von
Oberflächenpunkten in einer dynamischen Szene. Die Bewegung in den
Bildern kann dadurch verursacht werden, dass sich Objekte oder die
Kamera (oder beides) in der Welt zwischen den Aufnahmen der beiden
Stereobilder bewegen. Um den kalibrierten Szenenflusses zu
berechnen, kann scene_flow_calib
verwendet werden.
Die aufeinanderfolgenden Stereobildpaare werden in
ImageRect1T1
, ImageRect2T1
, ImageRect1T2
und ImageRect2T2
übergeben. Jedes Stereobildpaar muss
rektifiziert sein. Die Bildpaare können mit den Operatoren
calibrate_cameras
, gen_binocular_rectification_map
und map_image
rektifiziert werden. Außerdem wird ein
einkanaliges Disparitätsbild Disparity
benötigt, welches
für jedes Pixel (r,c1) des Bildes ImageRect1T1
ein
homologes Pixel (r,c2) im Bild ImageRect2T1
festlegt.
Hierbei gilt c2=c1+d(r,c1), wobei d(r,c) die Disparitäit in
Disparity
am Pixel (r,c) ist. Die Disparität kann mit
binocular_disparity
oder binocular_disparity_mg
berechnet werden.
Der berechnete unkalibrierte Szenenfluss wird in
OpticalFlow
und DisparityChange
zurückgegeben.
Die Vektoren im Vektorfeld OpticalFlow
beschreiben die
Bewegung in der Bildebene zwischen ImageRect1T1
und
ImageRect1T2
. Das einkanalige Bild
DisparityChange
beschreibt die Änderung der Disparität
zwischen ImageRect2T1
und ImageRect2T2
. Ein Punkt
in der Welt wird in das Bild ImageRect1T1
an der Position
(r,c) projiziert. Derselbe Punkt wird projiziert in
ImageRect2T1
an Position (r,c+d(r,c)),
ImageRect1T2
an Position (r+u(r,c),c+v(r,c)),
ImageRect2T2
an Position
(r+u(r,c),c+v(r,c)+d(r,c)+dc(r,c)).
Hierbei bezeichnen u(r,c) und v(r,c) die Zeilen- und
Spaltenkoordinaten des Vektorfeldes in OpticalFlow
,
d(r,c) die Disparitäten in Disparity
und dc(r,c) die
Disparitätsänderungen in DisparityChange
, jeweils am Pixel
(r,c).
Die rektifizierten Eingabebilder werden in ImageRect1T1
,
ImageRect2T1
, ImageRect1T2
und
ImageRect2T2
übergeben. Die Berechnung des Szenenflusses
erfolgt auf der Region von ImageRect1T1
. Dies ist auch die
Region des Szenenflusses in OpticalFlow
und
DisparityChange
. Disparity
beinhaltet die
Disparität zwischen den rektifizierten Bildern ImageRect1T1
und ImageRect2T1
.
SmoothingFlow
und SmoothingDisparity
spezifizieren
die Regularisierungsgewichte und
relativ zum Datenterm. Je größer diese
Parameter sind, desto glatter ist der berechnete Szenenfluss. Für
Byte-Bilder mit einem Wertebereich von führen
Werte in der Größenordnung von 40 typischerweise zu guten
Ergebnissen.
Die Parameter für das Iterationsverfahren und für die
Coarse-to-Fine-Warping-Strategie können mit den generischen
Parametern GenParamName
und GenParamValue
festgelegt werden.
Im Normalfall ist es ausreichend, einen der Standardparametersätze
für die Parameter zu verwenden, indem GenParamName
=
'default_parameters' und GenParamValue
=
'very_accurate' , 'accurate' , 'fast' oder
'very_fast' übergeben werden. Falls notwendig, können
einzelne Parameter modifiziert werden, nachdem der
Standardparametersatz gewählt wurde, indem eine Untermenge der
Parameter und entsprechenden Werte nach
'default_parameters' in GenParamName
und
GenParamValue
übergeben werden (z.B. GenParamName
= ['default_parameters','warp_zoom_factor'] und
GenParamValue
= ['accurate',0.6] ). Die Bedeutung
der einzelnen Parameter ist unten detailliert beschrieben. Die
Standardparametersätze sind gegeben durch:
'default_parameters' | 'very_accurate' | 'accurate' | 'fast' | 'very_fast' |
'warp_zoom_factor' | 0.75 | 0.5 | 0.5 | 0.5 |
'warp_levels' | 0 | 0 | 0 | 0 |
'warp_last_level' | 1 | 1 | 1 | 2 |
'outer_iter' | 10 | 7 | 5 | 4 |
'inner_iter' | 2 | 2 | 2 | 2 |
'sor_iter' | 3 | 3 | 3 | 3 |
'omega' | 1.9 | 1.9 | 1.9 | 1.9 |
Falls die Parameter einzeln spezifiziert werden sollen, müssen
GenParamName
und GenParamValue
Tupel derselben
Länge enthalten. Die zu den Parametern in GenParamName
gehörigen Werte müssen an der entsprechenden Position in
GenParamValue
spezifiziert werden. Um ein genaueres
Verständnis der Parameter zu erlangen, wird auf den Abschnitt
Algorithmus unten verwiesen.
Mit GenParamName
= 'warp_zoom_factor' kann
das Auflösungsverhältnis zwischen zwei aufeinanderfolgenden
Warpingebenen in der Coarse-to-Fine-Warping-Hierarchie festgelegt
werden. Dabei muss 'warp_zoom_factor' im offenen
Intervall (0,1) gewählt werden. Aus Performanzgründen wird
üblicherweise 'warp_zoom_factor' = 0.5 gewählt, d.h.
die Pixelanzahl der Eingangsbilder wird von einer Warpingebene zur
nächsten in jede Richtung halbiert. Werte für
'warp_zoom_factor' näher bei 1 können zu qualitativ
leicht besseren Ergebnissen führen, benötigen aber
unverhältnismäßig mehr Rechenzeit.
Mit GenParamName
= 'warp_levels' kann die
Warpinghierarchie auf eine maximale Anzahl von Ebenen beschränkt
werden. Für 'warp_levels' = 0 wird die maximal
mögliche Anzahl von Ebenen gewählt. Sollte die Bildgröße bei
einem gegebenen Auflösungsverhältnis 'warp_zoom_factor'
die gewählte Anzahl an Ebenen nicht zulassen, wird die maximal
mögliche Anzahl an Ebenen verwendet. Im Normalfall sollte
'warp_levels' auf 0 gesetzt werden.
Mit GenParamName
= 'warp_last_level' kann die
Anzahl der Warpingebenen, für die kein Flussinkrement mehr
berechnet werden soll, festgelegt werden. Normalerweise wird
diese Anzahl entweder auf 1 oder 2 gesetzt, d.h. es wird entweder
auf jeder Warpingebene ein Flussinkrement berechnet, oder die
feinste Warpingebene wird bei der Berechnung ausgelassen. Im
letzten Fall wird die Lösung nur auf halber Auflösung gerechnet
wird und dann auf die volle Auflösung interpoliert.
Mit GenParamName
= 'outer_iter' kann die
Anzahl äußerer Iterationen des Minimierungsalgorithmus festgelegt
werden. Typischerweise werden die Ergebnisse genauer, je größer
'outer_iter' gewählt wird. Größere Werte dieses Parameters
führen zu höheren Laufzeiten. Typischerweise wird
'outer_iter' auf Werte zwischen 5 und 10 gesetzt.
Mit GenParamName
= 'inner_iter' kann die
Anzahl innerer Iterationen des Minimierungsalgorithmus festgelegt
werden. Typischerweise werden die Ergebnisse genauer, je größer
'inner_iter' gewählt wird. Größere Werte dieses
Parameters führen zu höheren Laufzeiten. Typischerweise sind zwei
innere Iterationen ausreichend.
Mit GenParamName
= 'sor_iter' kann die
Anzahl der SOR-Iterationen, die zur Lösung des linearen
Gleichungssystems verwendet werden, festgelegt werden.
Typischerweise werden die Ergebnisse genauer, je größer
'sor_iter' gewählt wird. Größere Werte dieses Parameters
führen zu höheren Laufzeiten. Typischerweise sind drei
SOR-Iterationen ausreichend.
Mit GenParamName
= 'omega' kann der
Überrelaxationsfaktor des SOR-Algorithmus
festgelegt werden. 'omega' muss im offenen Intervall
(1,2) gewählt werden. Typischerweise wird 'omega' auf
1.9 gesetzt.
Der Szenenfluss wird berechnet, indem ein geeignetes Energiefunktional minimiert wird:
Hierbei stellt f=(u,v,dc) das optische Flussfeld und die Disparitätsänderung dar. bezeichnet den Datenterm und den Glattheitsterm (Regularisierungsterm). Der Algorithmus basiert auf folgenden Annahmen, die zu den Daten- und Glattheitstermen führen:
Es wir angenommen, dass der Grauwert
eines Punktes in allen vier Bildern konstant bleibt. Daraus folgen
die folgenden vier Bedingungen:
Hierbei bezeichnen , ,
und die Bilder
ImageRect1T1
, ImageRect2T1
, ImageRect1T2
und ImageRect2T2
.
Es wird angenommen, dass die Lösung stückweise glatt ist. Die Glattheit wird erreicht, indem die ersten Ableitungen des Flusses bestraft werden. Die Verwendung einer statistisch robusten (linearen) Straffunktion mit sorgt dafür, dass die Kanten in den Bewegungen im Szenenfluss erhalten bleiben.
Da das Disparitätsbild d gegeben ist, kann die erste Bedingung
vernachlässigt werden. Unter Verwendung aller
obigen Annahmen kann das Energiefunktional wie folgt geschrieben
werden:
Hierbei sind und die
Regularisierungsparameter, die in SmoothingFlow
und
SmoothingDisparity
übergeben werden.
Um große Verschiebungen schätzen zu können, machen Coarse-to-Fine-Warping-Strategien von zwei Konzepten Gebrauch, die beide eng miteinander verzahnt sind: Die sukzessive Verfeinerung der Problemstellung (Coarse-to-Fine) und die fortlaufende Kompensation des aktuelles Bildpaares um bereits berechnete Verschiebungen (Warping). Algorithmisch lässt sich eine solche Coarse-to-Fine-Warping-Strategie wie folgt formulieren:
Zunächst werden beide Bilder des aktuellen Bildpaares auf eine sehr grobe Auflösungsstufe heruntergesampelt.
Dann wird der Szenenfluss auf dieser groben Auflösung berechnet.
Dieser Szenenfluss wird auf der nächstfeineren Auflösungsstufe benötigt: Es wird dort aus dem zweiten Bildpaar der Bildfolge herausgerechnet, d.h. die Problemstellung auf der feineren Auflösungsstufe wird um das bereits berechnete Flussfeld kompensiert. Dieser Schritt wird auch als Warping bezeichnet.
Das so modifizierte Problem (Differenzproblem) wird nun auf der feineren Auflösungsstufe gelöst, d.h. der Szenenfluss wird dort berechnet.
Die Schritte 3-4 werden wiederholt, bis die ursprüngliche Auflösung erreicht wird.
Das letztendliche Ergebnis wird durch Addition des Szenenflusses aller Auflösungsstufen gebildet.
Diese inkrementelle Berechnung des Szenenflusses bietet folgenden Vorteil: Während das Coarse-to-Fine-Konzept sicherstellt, dass die Verschiebungen auf der gröbsten Auflösungsstufe sehr klein sind, sorgt die Warping-Strategie dafür, dass das auch für die zu berechnenden Flussinkremente (Szenenfluss der Differenzprobleme) so bleibt. Da kleine Verschiebungen viel genauer berechnet werden können als größere, nimmt durch den Einsatz einer solchen Coarse-to-Fine-Warping-Strategie die Schätzqualität im allgemeinen deutlich zu. Jedoch muss anstelle eines einzelnen Korrespondenzproblems eine Hierarchie von ebensolchen Problemen gelöst werden.
Die Minimierung von Funktionalen ist aus mathematischer Sicht sehr eng mit der Minimierung von Funktionen verwandt: So wie eine Nullstelle der ersten Ableitung eine notwendige Bedingung für ein Minimum einer Funktion ist, ist die Erfüllung der sogenannten Euler-Lagrange-Gleichungen eine notwendige Bedingung für die minimierende Funktion eines Funktionals (die minimierende Funktion entspricht hier dem gesuchten Szenenfluss). Die Euler-Lagrange-Gleichungen sind partielle Differentialgleichungen. Durch die Diskretisierung dieser Euler-Lagrange-Gleichungen mit Hilfe finiter Differenzen entstehen große dünnbesetzte nichtlineare Gleichungssysteme, die durch den Algorithmus gelöst werden müssen.
Auf jeder Warpingebene muss ein einzelnes Gleichungssystem gelöst werden. Der Algorithmus verwendet ein iteratives Verfahren, dass aus zwei verschachtelten Iterationen (den sog. äußeren und inneren Iterationen) sowie dem SOR-Verfahren (Successive Over-Relaxation) besteht. Die äußere Schleife sorgt für die Linearisierung der nichtlinearen Terme, die aus den Datentermen folgen. Die Nichtlinearität von wird durch die innere Fixpunktiteration beseitigt. Das resultierende lineare Gleichungssystem wird effizient mit dem SOR-Verfahren gelöst.
ImageRect1T1
(input_object) singlechannelimage(-array) →
object (byte / uint2 / real)
Eingabebild 1 zum Zeitpunkt .
ImageRect2T1
(input_object) singlechannelimage(-array) →
object (byte / uint2 / real)
Eingabebild 2 zum Zeitpunkt .
ImageRect1T2
(input_object) singlechannelimage(-array) →
object (byte / uint2 / real)
Eingabebild 1 zum Zeitpunkt .
ImageRect2T2
(input_object) singlechannelimage(-array) →
object (byte / uint2 / real)
Eingabebild 2 zum Zeitpunkt .
Disparity
(input_object) singlechannelimage(-array) →
object (real)
Dispartät zwischen Eingabebild 1 und 2 zum Zeitpunkt .
OpticalFlow
(output_object) singlechannelimage(-array) →
object (vector_field)
Berechneter optischer Fluss.
DisparityChange
(output_object) singlechannelimage(-array) →
object (real)
Berechnete Änderung der Disparität.
SmoothingFlow
(input_control) number →
(real / integer)
Gewicht des Regularisierungsterms relativ zum Datenterm (Ableitungen des optischen Flusses).
Defaultwert: 40.0
Wertevorschläge: 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0
Restriktion: SmoothingFlow > 0.0
SmoothingDisparity
(input_control) number →
(real / integer)
Gewicht des Regularisierungsterms relativ zum Datenterm (Ableitungen der Änderung der Disparität).
Defaultwert: 40.0
Wertevorschläge: 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0
Restriktion: SmoothingDisparity > 0.0
GenParamName
(input_control) attribute.name(-array) →
(string)
Parametername(n) für den Algorithmus.
Defaultwert: 'default_parameters'
Wertevorschläge: 'default_parameters' , 'warp_levels' , 'warp_zoom_factor' , 'warp_last_level' , 'outer_iter' , 'inner_iter' , 'sor_iter' , 'omega'
GenParamValue
(input_control) attribute.value(-array) →
(string / integer / real)
Parameterwert(e) für den Algorithmus.
Defaultwert: 'accurate'
Wertevorschläge: 'very_accurate' , 'accurate' , 'fast' , 'very_fast' , 0, 1, 2, 3, 4, 5, 6, 0.5, 0.6, 0.7, 0.75, 3, 5, 7, 2, 3, 1.9
Sind die Parameterwerte korrekt, dann liefert
scene_flow_uncalib
den Wert 2 (H_MSG_TRUE). Das Verhalten bei leerer
Eingabe (keine Eingabebilder vorhanden) lässt sich mittels
set_system('no_object_result',<Result>)
festlegen.
Gegebenenfalls wird eine Fehlerbehandlung durchgeführt.
binocular_disparity
,
binocular_disparity_mg
threshold
,
vector_field_length
scene_flow_calib
,
optical_flow_mg
A. Wedel, C. Rabe, T. Vaudrey, T. Brox, U. Franke and D. Cremers: „Efficient dense scene flow from sparse or dense stereo data“; In: Proceedings of the 10th European Conference on Computer Vision: Part I, pages 739-751. Springer-Verlag, 2008.
Foundation