radiometric_self_calibrationT_radiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibration (Operator)

Name

radiometric_self_calibrationT_radiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibration — Radiometrische Selbstkalibrierung einer Kamera.

Signatur

radiometric_self_calibration(Images : : ExposureRatios, Features, FunctionType, Smoothness, PolynomialDegree : InverseResponse)

Herror T_radiometric_self_calibration(const Hobject Images, const Htuple ExposureRatios, const Htuple Features, const Htuple FunctionType, const Htuple Smoothness, const Htuple PolynomialDegree, Htuple* InverseResponse)

void RadiometricSelfCalibration(const HObject& Images, const HTuple& ExposureRatios, const HTuple& Features, const HTuple& FunctionType, const HTuple& Smoothness, const HTuple& PolynomialDegree, HTuple* InverseResponse)

HTuple HImage::RadiometricSelfCalibration(const HTuple& ExposureRatios, const HString& Features, const HString& FunctionType, double Smoothness, Hlong PolynomialDegree) const

HTuple HImage::RadiometricSelfCalibration(double ExposureRatios, const HString& Features, const HString& FunctionType, double Smoothness, Hlong PolynomialDegree) const

HTuple HImage::RadiometricSelfCalibration(double ExposureRatios, const char* Features, const char* FunctionType, double Smoothness, Hlong PolynomialDegree) const

HTuple HImage::RadiometricSelfCalibration(double ExposureRatios, const wchar_t* Features, const wchar_t* FunctionType, double Smoothness, Hlong PolynomialDegree) const   (Nur Windows)

static void HOperatorSet.RadiometricSelfCalibration(HObject images, HTuple exposureRatios, HTuple features, HTuple functionType, HTuple smoothness, HTuple polynomialDegree, out HTuple inverseResponse)

HTuple HImage.RadiometricSelfCalibration(HTuple exposureRatios, string features, string functionType, double smoothness, int polynomialDegree)

HTuple HImage.RadiometricSelfCalibration(double exposureRatios, string features, string functionType, double smoothness, int polynomialDegree)

Beschreibung

radiometric_self_calibrationradiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibrationRadiometricSelfCalibration führt eine radiometrische Selbstkalibrierung einer Kamera durch. Dazu müssen in ImagesImagesImagesImagesimages mindestens zwei Bilder übergeben werden, die denselben Bildinhalt zeigen. Alle in ImagesImagesImagesImagesimages übergebenen Bilder müssen mit unterschiedlichen Belichtungen aufgenommen worden sein. Typischerweise werden die unterschiedlichen Belichtungen durch Veränderung der Verschlusszeiten (Belichtungszeiten) an der Kamera erzeugt. Eine Änderung der Belichtung durch Verstellen der Blende ist nicht zu empfehlen, da hier die Belichtungsverhältnisse nicht genau genug bestimmt werden können. Das Verhältnis der Belichtungen aufeinanderfolgender Bilder wird in ExposureRatiosExposureRatiosExposureRatiosExposureRatiosexposureRatios übergeben. Ein Wert von 0.5 bedeutet z.B., dass das zweite Bild des Bildpaares mit der halben Belichtung des ersten Bildes aufgenommen wurde. Das Verhältnis der Belichtungen kann leicht aus den Verschlusszeiten berechnet werden, da die Belichtung proportional zur Verschlusszeit ist. Das Verhältnis der Belichtungen muss größer als 0 und kleiner als 1 sein. Das bedeutet, dass die Bilder nach abnehmender Belichtung sortiert sein müssen. ExposureRatiosExposureRatiosExposureRatiosExposureRatiosexposureRatios muss ein Element weniger enthalten, als die Anzahl der in ImagesImagesImagesImagesimages übergebenen Bilder. Falls alle Verhältnisse der Belichtungen identisch sind, kann zur Vereinfachung auch ein einziger Wert in ExposureRatiosExposureRatiosExposureRatiosExposureRatiosexposureRatios übergeben werden.

Wie oben beschrieben, müssen die in ImagesImagesImagesImagesimages übergebenen Bilder denselben Bildinhalt zeigen. Dazu ist es normalerweise notwendig, dass sich weder die Kamera noch die im Bild enthaltenen Objekte bewegen. Falls sich die Kamera um das optische Zentrum gedreht hat, sollten die Bilder mit proj_match_points_ransacproj_match_points_ransacProjMatchPointsRansacProjMatchPointsRansacProjMatchPointsRansac und projective_trans_imageprojective_trans_imageProjectiveTransImageProjectiveTransImageProjectiveTransImage auf eines der Bilder als Referenzbild ausgerichtet werden. Falls die zur radiometrischen Kalibrierung verwendeten Merkmale aus dem 2D-Grauwerthistogramm von aufeinanderfolgenden Bildpaaren aus ImagesImagesImagesImagesimages bestimmt werden (FeaturesFeaturesFeaturesFeaturesfeatures = '2d_histogram'"2d_histogram""2d_histogram""2d_histogram""2d_histogram"), ist es unerlässlich, dass die Bilder aufeinander ausgerichtet sind und dass sich die Objekte in den Bildern nicht bewegen. Im Modus FeaturesFeaturesFeaturesFeaturesfeatures = '1d_histograms'"1d_histograms""1d_histograms""1d_histograms""1d_histograms" werden die zur radiometrischen Kalibrierung verwendeten Merkmale aus den 1D-Grauwerthistogrammen der Bildpaare berechnet. In diesem Modus kann eine Kalibrierung theoretisch auch dann erfolgen, falls sich die 1D-Histogramme der Bilder durch eine Bewegung von Objekten im Bild nicht ändert. Dies kann z.B. dann der Fall sein, falls sich ein Objekt vor einem gleichmäßig texturierten Hintergrund bewegt. Aufgrund der höheren Genauigkeit ist aber der Modus FeaturesFeaturesFeaturesFeaturesfeatures = '2d_histogram'"2d_histogram""2d_histogram""2d_histogram""2d_histogram" vorzuziehen. Der Modus FeaturesFeaturesFeaturesFeaturesfeatures = '1d_histograms'"1d_histograms""1d_histograms""1d_histograms""1d_histograms" sollte nur verwendet werden, falls es unmöglich ist, den Kameraaufbau so zu konstruieren, dass sich weder die Kamera noch die Bildobjekte bewegen.

Des Weiteren ist darauf zu achten, dass der Grauwertbereich lückenlos überdeckt wird. Hierzu sollte ein geeigneter Bildinhalt gewählt werden. Ob Lücken im Grauwertbereich vorliegen, kann leicht anhand der 1D-Grauwerthistogramme der Bilder und der 2D-Grauwerthistogramme aufeinanderfolgender Bilder überprüft werden. In den 1D-Grauwerthistogrammen (siehe gray_histo_absgray_histo_absGrayHistoAbsGrayHistoAbsGrayHistoAbs) sollten zwischen dem minimalen und maximalen Grauwert keine Bereiche mit einer Häufigkeit von 0 oder einer sehr kleinen Häufigkeit vorkommen. In den 2D-Grauwerthistogrammen (siehe histo_2dimhisto_2dimHisto2dimHisto2dimHisto2dim) sollte nach der Segmentierung mit einem unteren Schwellwert von 1 eine zusammenhängende Region in Form eines „Schlauches“ entstehen. Falls mehrere Zusammenhangskomponenten entstehen, sollte ein geeigneterer Bildinhalt gewählt werden. Falls der Bildinhalt so gewählt werden kann, dass der Grauwertbereich des Bildes (z.B. 0-255 bei Byte-Bildern) mit zwei Bildern mit unterschiedlichen Belichtungen ausgeschöpft werden kann, und keine Lücken in den Histogrammen vorhanden sind, sind diese zwei Bilder zur Kalibrierung ausreichend. Dies ist typischerweise jedoch nicht der Fall, so dass mit mehreren Bildern der Grauwertbereich überdeckt werden muss. Dazu sind, wie oben beschrieben, mehrere Bilder mit unterschiedlichen Belichtungen aufzunehmen, um den Grauwertbereich möglichst vollständig zu überdecken. Dabei sollte das erste Bild im Normalfall so belichtet werden, dass der maximale Grauwert entweder knapp unter der Sättigungsgrenze der Kamera liegt, oder dass das Bild deutlich übersteuert ist. Falls das erste Bild übersteuert aufgenommen wird, ist eine deutliche Übersteuerung notwendig, damit radiometric_self_calibrationradiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibrationRadiometricSelfCalibration die übersteuerten Bereiche sicher erkennen kann. Falls die Kamera ein ungewöhnliches Sättigungsverhalten zeigt (z.B. eine Sättigungsgrenze, die signifikant unter dem maximalen Grauwert liegt), sollten in dem übersteuerten Bild die übersteuerten Bereiche per Hand mit reduce_domainreduce_domainReduceDomainReduceDomainReduceDomain ausmaskiert werden.

radiometric_self_calibrationradiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibrationRadiometricSelfCalibration liefert die inverse Grauwert-Antwortfunktion der Kamera in InverseResponseInverseResponseInverseResponseInverseResponseinverseResponse zurück. Die inverse Antwortfunktion kann dazu verwendet werden, ein Bild mit linearer Grauwert-Antwortfunktion zu erzeugen, indem InverseResponseInverseResponseInverseResponseInverseResponseinverseResponse als LUT in lut_translut_transLutTransLutTransLutTrans verwendet wird. Der Parameter FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType gibt an, welches Funktionsmodell für die Antwortfunktion verwendet werden soll. Für FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'discrete'"discrete""discrete""discrete""discrete" wird die Antwortfunktion durch eine diskrete Funktion mit der relevanten Anzahl von Grauwerten beschrieben (256 bei Byte-Bildern). Für FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'polynomial'"polynomial""polynomial""polynomial""polynomial" wird die Antwortfunktion durch ein Polynom vom Grad PolynomialDegreePolynomialDegreePolynomialDegreePolynomialDegreepolynomialDegree beschrieben. Die Berechnung der Antwortfunktion ist für FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'discrete'"discrete""discrete""discrete""discrete" langsamer. Da aber in den Bereichen, an denen keine Grauwertinformation vorliegt, ein Polynom trotz der unten beschriebenen Glattheitsbedingungen Oszillationen aufweisen kann, ist die diskrete Funktion dem Polynom im Normalfall vorzuziehen.

Die inverse Grauwert-Antwortfunktion wird als Tupel von ganzen Zahlen für FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'discrete'"discrete""discrete""discrete""discrete" und FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'polynomial'"polynomial""polynomial""polynomial""polynomial" zurückgeliefert. In manchen Anwendungen kann es wünschenswert sein, die inverse Grauwert-Antwortfunktion als Gleitkommazahlen zurückzuliefern, um die numerischen Fehler, die durch Runden entstehen, zu vermeiden. Falls z.B. die inverse Grauwert-Antwortfunktion invertiert werden muss, um die tatsächliche Antwortfunktion der Kamera zu berechnen, geht Information durch die Rundung verloren. In diesen Anwendungen kann FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType auf 'discrete_real'"discrete_real""discrete_real""discrete_real""discrete_real" oder 'polynomial_real'"polynomial_real""polynomial_real""polynomial_real""polynomial_real" gesetzt werden, was dazu führt, dass die inverse Grauwert-Antwortfunktion als ein Tupel von Gleitkommazahlen zurückgeliefert wird.

Der Parameter SmoothnessSmoothnessSmoothnessSmoothnesssmoothness definiert (zusätzlich zu den Bedingungen, die aus den Bildern über die Antwortfunktion der Kamera hergeleitet werden können) Bedingungen für die Glattheit der Antwortfunktion. Falls der Grauwertbereich wie oben beschrieben vollständig und lückenlos überdeckt werden kann und falls das Kamerarauschen gering ist, sollte der Standardwert von 1 nicht verändert werden. Ansonsten kann mit Werten > 1 eine stärkere Glättung und mit Werten < 1 eine schwächere Glättung der Antwortfunktion erreicht werden. Die Glättung ist insbesondere in Bereichen wichtig, in denen keine Grauwertinformation aus den Bildern hergeleitet werden kann, also insbesondere in Lücken im Histogramm und für Grauwerte, die kleiner sind als der minimale bzw. größer als der maximale Grauwert aller Bilder. Hier führen die Glattheitsbedingungen zu einer Interpolation bzw. Extrapolation der Antwortfunktion. Durch die Art der intern berechneten Bedingungsgleichungen bevorzugt FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'discrete'"discrete""discrete""discrete""discrete" eine Exponentialfunktion in undefinierten Grauwertbereichen, während FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'polynomial'"polynomial""polynomial""polynomial""polynomial" eine Gerade bevorzugt. Beachten Sie bitte, dass die Interpolation und Extrapolation in jedem Fall unsicherer ist, als den Grauwertbereich vollständig und lückenlos zu überdecken. Deswegen sollte in jedem Fall zuerst versucht werden, die Bilder optimal aufzunehmen, bevor anhand der Glattheitsbedingungen ein Auffüllen der Lücken vorgenommen wird. In jedem Fall sollte die Antwortfunktion nach dem Aufruf von radiometric_self_calibrationradiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibrationRadiometricSelfCalibration auf Plausibilität überprüft werden. Insbesondere sollte überprüft werden, ob InverseResponseInverseResponseInverseResponseInverseResponseinverseResponse monoton ist. Falls dies nicht der Fall ist, sollte ein geeigneterer Bildinhalt verwendet werden, damit nicht interpoliert werden muss, oder SmoothnessSmoothnessSmoothnessSmoothnesssmoothness auf einen größeren Wert gesetzt werden. Für FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'polynomial'"polynomial""polynomial""polynomial""polynomial" kann es auch notwendig sein, PolynomialDegreePolynomialDegreePolynomialDegreePolynomialDegreepolynomialDegree zu verändern. Falls trotz dieser Änderungen immer noch ein wenig plausibles Ergebnis geliefert wird, sollte das Sättigungsverhalten der Kamera überprüft werden, z.B. anhand des 2D-Grauwerthistogramms, und die gesättigten Bereiche wie oben beschrieben per Hand ausmaskiert werden.

Bei der Bestimmung der inversen Grauwert-Antwortfunktion der Kamera kann die absolute Energie, die auf die Kamera fällt, nicht bestimmt werden. Das heißt, dass InverseResponseInverseResponseInverseResponseInverseResponseinverseResponse nur bis auf einen Skalierungsfaktor bestimmt werden kann. Daher wird als Nebenbedingung verwendet, dass der maximale Grauwert, der auftreten kann, am maximalen Eingabegrauwert angenommen werden soll, also z.B. für Byte-Bilder InverseResponseInverseResponseInverseResponseInverseResponseinverseResponse[255] = 255. Diese Nebenbedingung liefert im Normalfall ein intuitives Ergebnis. Falls jedoch ein mehrkanaliges Bild (typischerweise ein RGB-Bild) radiometrisch kalibriert werden soll (hierzu muss jeder Kanal einzeln kalibriert werden), kann es vorkommen, dass durch die obige Nebenbedingung ein unterschiedlicher Skalierungsfaktor für jeden Kanal berechnet wird. Das kann dazu führen, dass Grautöne nach der Korrektur nicht mehr grau erscheinen. In diesem Fall ist ein manueller Weißabgleich durchzuführen, indem ein homogenes graues Gebiet im Originalbild identifiziert wird, und aus den Grauwerten der korrigierten Kanäle Skalierungsfaktoren für zwei der drei Antwortkurven (bzw. allgemein für n-1 der n Kanäle) hergeleitet werden. Dabei sollte die nicht zu ändernde Antwortkurve so gewählt werden, dass alle Skalierungsfaktoren < 1 sind. Mit den so berechneten Skalierungsfaktoren sollten neue Antwortfunktionen durch Multiplikation aller Werte einer Antwortfunktion mit dem jeweiligen Skalierungsfaktor berechnet werden.

Ausführungsinformationen

Parameter

ImagesImagesImagesImagesimages (input_object)  singlechannelimage-array objectHImageHImageHobject (byte / uint2)

Eingabebilder.

ExposureRatiosExposureRatiosExposureRatiosExposureRatiosexposureRatios (input_control)  real(-array) HTupleHTupleHtuple (real) (double) (double) (double)

Verhältnis der Belichtungsenergien aufeinanderfolgender Bildpaare.

Defaultwert: 0.5

Wertevorschläge: 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8

Restriktion: ExposureRatios > 0 && ExposureRatios < 1

FeaturesFeaturesFeaturesFeaturesfeatures (input_control)  string HTupleHTupleHtuple (string) (string) (HString) (char*)

Merkmale, die zur Berechnung der inversen Antwortfunktion der Kamera verwendet werden.

Defaultwert: '2d_histogram' "2d_histogram" "2d_histogram" "2d_histogram" "2d_histogram"

Werteliste: '1d_histograms'"1d_histograms""1d_histograms""1d_histograms""1d_histograms", '2d_histogram'"2d_histogram""2d_histogram""2d_histogram""2d_histogram"

FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType (input_control)  string HTupleHTupleHtuple (string) (string) (HString) (char*)

Typ der inversen Antwortfunktion der Kamera.

Defaultwert: 'discrete' "discrete" "discrete" "discrete" "discrete"

Werteliste: 'discrete'"discrete""discrete""discrete""discrete", 'discrete_real'"discrete_real""discrete_real""discrete_real""discrete_real", 'polynomial'"polynomial""polynomial""polynomial""polynomial", 'polynomial_real'"polynomial_real""polynomial_real""polynomial_real""polynomial_real"

SmoothnessSmoothnessSmoothnessSmoothnesssmoothness (input_control)  real HTupleHTupleHtuple (real) (double) (double) (double)

Glattheit der inversen Antwortfunktion der Kamera.

Defaultwert: 1.0

Wertevorschläge: 0.3, 0.5, 0.7, 0.8, 1.0, 1.2, 1.5, 2.0, 3.0

Restriktion: Smoothness > 0

PolynomialDegreePolynomialDegreePolynomialDegreePolynomialDegreepolynomialDegree (input_control)  integer HTupleHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

Grad des Polynoms falls FunctionTypeFunctionTypeFunctionTypeFunctionTypefunctionType = 'polynomial'"polynomial""polynomial""polynomial""polynomial".

Defaultwert: 5

Wertevorschläge: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Restriktion: PolynomialDegree >= 1 && PolynomialDegree <= 20

InverseResponseInverseResponseInverseResponseInverseResponseinverseResponse (output_control)  number-array HTupleHTupleHtuple (integer / real) (int / long / double) (Hlong / double) (Hlong / double)

Inverse Antwortfunktion der Kamera.

Beispiel (HDevelop)

open_framegrabber ('1394IIDC', 1, 1, 0, 0, 0, 0, 'default', -1, \
                   'default', -1, 'default', 'default', 'default', \
                   -1, -1, AcqHandle)
* Define appropriate shutter times.
Shutters := [1000,750,500,250,125]
Num := |Shutters|
* Grab and accumulate images with the different exposures.  In this
* loop, it must be ensured that the scene remains static.
gen_empty_obj (Images)
for I := 0 to Num-1 by 1
    set_framegrabber_param (AcqHandle, 'shutter', Shutters[I])
    grab_image (Image, AcqHandle)
    concat_obj (Images, Image, Images)
endfor
* Compute the exposure ratios from the shutter times.
ExposureRatios := real(Shutters[1:Num-1])/real(Shutters[0:Num-2])
radiometric_self_calibration (Images, ExposureRatios, '2d_histogram', \
                              'discrete', 1, 5, InverseResponse)
* Note that if the frame grabber supports hardware LUTs, we could
* also call set_framegrabber_lut here instead of lut_trans below.
* This would be more efficient.
while (1)
    grab_image_async (Image, AcqHandle, -1)
    lut_trans (Image, ImageLinear, InverseResponse)
    * Process radiometrically correct image.
    * [...]
endwhile
close_framegrabber (AcqHandle)

Ergebnis

Sind die Parameterwerte korrekt, dann liefert radiometric_self_calibrationradiometric_self_calibrationRadiometricSelfCalibrationRadiometricSelfCalibrationRadiometricSelfCalibration den Wert 2 (H_MSG_TRUE). Gegebenenfalls wird eine Fehlerbehandlung durchgeführt.

Vorgänger

read_imageread_imageReadImageReadImageReadImage, grab_imagegrab_imageGrabImageGrabImageGrabImage, grab_image_asyncgrab_image_asyncGrabImageAsyncGrabImageAsyncGrabImageAsync, set_framegrabber_paramset_framegrabber_paramSetFramegrabberParamSetFramegrabberParamSetFramegrabberParam, concat_objconcat_objConcatObjConcatObjConcatObj, proj_match_points_ransacproj_match_points_ransacProjMatchPointsRansacProjMatchPointsRansacProjMatchPointsRansac, proj_match_points_ransac_guidedproj_match_points_ransac_guidedProjMatchPointsRansacGuidedProjMatchPointsRansacGuidedProjMatchPointsRansacGuided, projective_trans_imageprojective_trans_imageProjectiveTransImageProjectiveTransImageProjectiveTransImage

Nachfolger

lut_translut_transLutTransLutTransLutTrans

Siehe auch

histo_2dimhisto_2dimHisto2dimHisto2dimHisto2dim, gray_histogray_histoGrayHistoGrayHistoGrayHisto, gray_histo_absgray_histo_absGrayHistoAbsGrayHistoAbsGrayHistoAbs, reduce_domainreduce_domainReduceDomainReduceDomainReduceDomain

Modul

Calibration