Python bindings for LDPK¶
Indices and tables¶
Introduction¶
The Lens Distortion Plugin Kit (LDPK) provides a python module which allows to use the five built-in lens distortion models in python. When we use this module, we import it this way:
>>> import lens_distortion_plugins as ldp
Classes¶
There is a class for each of the five built-in lens distortion models. The python classes are:
-
lens_distortion_plugins.
anamorphic_deg_6
¶ alias of
tde4_ldp_py_wrapper
-
lens_distortion_plugins.
anamorphic_deg_4_rotate_squeeze_xy
¶ alias of
tde4_ldp_py_wrapper
-
lens_distortion_plugins.
radial_deg_8
¶ alias of
tde4_ldp_py_wrapper
-
lens_distortion_plugins.
radial_decentered_deg_4_cylindric
¶ alias of
tde4_ldp_py_wrapper
-
lens_distortion_plugins.
classic_3de_mixed
¶ alias of
tde4_ldp_py_wrapper
The human-readable name as it appears in 3DE4 is given by the method
-
any_ldm.
getModelName
()¶ Signature: getModelName() -> string. Name of distortion model as in 3DE4’s GUI.
>>> print ldp.anamorphic_deg_6().getModelName()
3DE4 Anamorphic, Degree 6
>>> print ldp.anamorphic_deg_4_rotate_squeeze_xy().getModelName()
3DE4 Anamorphic - Standard, Degree 4
>>> print ldp.radial_deg_8().getModelName()
3DE4 Radial - Fisheye, Degree 8
>>> print ldp.radial_decentered_deg_4_cylindric().getModelName()
3DE4 Radial - Standard, Degree 4
>>> print ldp.classic_3de_mixed().getModelName()
3DE Classic LD Model
Parameter name¶
Parameters are addressed by their (human-readable) names. The following method maps the index into the parameter name:
-
any_ldm.
getParameterName
()¶ Signature: getParameterName(i) -> string. Name of i-th model-specific parameter
Parameter types¶
In 3DE4 each parameter of a lens distortion model (built-in or plugin) is represented by a widget in Attribute Editor -> Lenses -> Lens Distortion. There are six different widget types, and they are represented by the following symbolic (and numeric) values:
>>> print ldp.TDE4_LDP_STRING
0
>>> print ldp.TDE4_LDP_DOUBLE
1
>>> print ldp.TDE4_LDP_INT
2
>>> print ldp.TDE4_LDP_FILE
3
>>> print ldp.TDE4_LDP_TOGGLE
4
>>> print ldp.TDE4_LDP_ADJUSTABLE_DOUBLE
5
Instead of strings we prefer to have the same numeric values here as we have in C++. The type of a parameter is determined by
-
any_ldm.
getParameterType
()¶ Signature: getParameterType(name) -> int. Type of parameter
>>> ldm = ldp.anamorphic_deg_6()
>>> print ldm.getParameterType("Cx02 - Degree 2")
5
The return value is one of the constants mentioned above.
Default value¶
Each parameter has a default value. The default value is retrieved using the method
-
any_ldm.
getParameterDefaultValue
()¶ Signature: getParameterDefaultValue(name) -> one of double,int,string,bool. Default value of parameter
>>> ldm = ldp.anamorphic_deg_4_rotate_squeeze_xy()
>>> print ldm.getParameterDefaultValue("Squeeze-X")
1.0
Range¶
Parameters of type ADJUSTABLE_DOUBLE have range values which describe the possible values of the parameter. The range values are not strict mathematical limits, they are more some kind of hints for 3DE4’s optimization algorithms.
-
any_ldm.
getParameterRange
()¶ Signature: getParameterRange(name) -> (double,double). Typical/Strict range of parameter
>>> ldm = ldp.radial_decentered_deg_4_cylindric()
>>> print ldm.getParameterRange("Phi - Cylindric Direction")
(-90.0, 90.0)
Setting parameter values¶
There are four methods for setting parameter values individually.
-
any_ldm.
setParameterValueDouble
()¶ Signature: setParameterValueDouble(name,value) -> None. Set value of parameter. The parameter is addressed by its name. This can be one of the seven built-in parameters or one of the model-specific ones. Please note, that all length-unit parameters are given in centimeter.
Parameters of types TDE4_LDP_DOUBLE and TDE4_LDP_ADJUSTABLE_DOUBLE must be set with this method. The seven built-in parameters are of type TDE4_LDP_DOUBLE:
- tde4_focal_length_cm
- tde4_filmback_width_cm
- tde4_filmback_height_cm
- tde4_lens_center_offset_x_cm
- tde4_lens_center_offset_y_cm
- tde4_pixel_aspect
- tde4_focus_distance_cm
-
any_ldm.
setParameterValueBool
()¶ Signature: setParameterValueBool(name,value) -> None. Set value of parameter.
-
any_ldm.
setParameterValueInt
()¶ Signature: setParameterValueInt(name,value) -> None. Set value of parameter.
-
any_ldm.
setParameterValueString
()¶ Signature: setParameterValueString(name,value) -> None. Set value of parameter.
The following methods allow to set and get the seven built-in camera parameters:
-
any_ldm.
setCamera
()¶ Signature: setCamera(double,double,double,double,double,double,double) -> None. Convenience function for setting all seven built-in camera parameters at once. The parameters are (in this order): focal length [cm], filmback width [cm], filmback height [cm], lens center offset x [cm], lens center offset y [cm], pixel aspect, focus distance [cm]. If focus distance is not relevant, it should be set to some non-zero value, say 100 (cm). Currently, no error-checking is done. initializeParameters() is called implicitly.
-
any_ldm.
getCamera
()¶ Signature: getCamera() -> (double,double,double,double,double,double,double). This method returns the seven built-in camera parameters at once. The parameters are (in this order): focal length [cm], filmback width [cm], filmback height [cm], lens center offset x [cm], lens center offset y [cm], pixel aspect, focus distance [cm].
>>> import lens_distortion_plugins as ldp
>>> ldm = ldp.radial_decentered_deg_4_cylindric()
>>> ldm.setCamera(1.0,0.8,0.6,0.1,0.1,1.0,100.0)
>>> print ldm.getCamera()
(1.0, 0.8, 0.6, 0.1, 0.1, 1.0, 100.0)
Initializing for usage¶
When all parameters are set, the instance needs to be initialized for usage. This is done by:
-
any_ldm.
initializeParameters
()¶ Signature: initializeParameters() -> None. Initialize what -er- needs to be initialized (after modifying parameters, important)
Remove and apply lens distortion¶
-
any_ldm.
undistort
()¶ Signature: undistort((x,y)) -> (double,double). remove distortion for point (x,y). The point (x,y) is specified in unit coordinates [0,1]x[0,1], which correspond to the filmback. Please consult the ldpk-documentation for details.
-
any_ldm.
distort
()¶ Signature: distort((x,y)) -> (double,double). apply distortion for point (x,y). Inverse function of undistort(). Usually, this function is iterative, while undistort() is not (i.e. it’s slower).
Bounding box¶
There are methods for getting the bounding box for the undistort- and the distort-function. These methods are quite simple, they surround the domain of the function with some predefined sample density and accumulate minimum and maximum function values. So, please do not expect them to deliver values at precision 1e-15...
-
any_ldm.
getBoundingBoxUndistort
()¶ Signature: getBoundingBoxUndistort(double xa,double ya,double xb,double yb,int nx=32,int ny=32) -> (double xa_out,double ya_out,double xb_out,double yb_out). Bounding box resulting from undistorting the rectangle [xa,ya]x[xb,yb]. The return value is the bounding box (xa_out,ya_out),(xb_out,yb_out).By default, the edges of the rectangle are scanned at nx+1 points horizontally and ny+1 points vertically.
-
any_ldm.
getBoundingBoxDistort
()¶ Signature: getBoundingBoxDistort(double xa,double ya,double xb,double yb,int nx=32,int ny=32) -> (double xa_out,double ya_out,double xb_out,double yb_out). Bounding box resulting from distorting the rectangle [xa,ya]x[xb,yb]. The return value is the bounding box (xa_out,ya_out),(xb_out,yb_out). By default, the edges of the rectangle are scanned at nx+1 points horizontally and ny+1 points vertically.
>>> ldm = ldp.radial_decentered_deg_4_cylindric()
>>> ldm.setParameterValueDouble("tde4_focal_length_cm",1.0)
>>> ldm.setParameterValueDouble("tde4_filmback_width_cm",0.8)
>>> ldm.setParameterValueDouble("tde4_filmback_height_cm",0.6)
>>> ldm.setParameterValueDouble("tde4_pixel_aspect",1.0)
>>> ldm.setParameterValueDouble("Distortion - Degree 2",0.1)
>>> ldm.initializeParameters()
>>> print ldm.getBoundingBoxUndistort(0,0,1,1)
(-0.050000000000000044, -0.050000000000000044, 1.05, 1.05)
>>> print ldm.getBoundingBoxDistort(0,0,1,1)
(0.027077570819212873, 0.016296699052012663, 0.9729224291807872, 0.9837033009479873)
Derivatives¶
The LDPK provides methods for accessing the Jacobian Matrix (first derivatives) and the so-called “Twist Vector” (mixed derivatives). The methods are:
-
any_ldm.
getJacobianMatrix
()¶ Signature: getJacobianMatrix((x,y)) -> (double,double,double,double). Jacobian for point (x,y). Result is (m00,m01,m10,m11) <- this order. This is the Jacobian for the undistort-method, in unit coordinates [0,1]x[0,1]. Invokes getJacobianMatrixDQ(), if the distortion model does not provide an implementation.
-
any_ldm.
getTwistVector
()¶ Signature: getTwistVector((x,y)) -> (double,double). Mixed Derivatives for point (x,y). Result is (t0,t1). These are the mixed derivatives for the undistort-method, in unit coordinates [0,1]x[0,1]. Same as getTwistVectorDQ, if the distortion model does not provide an implementation.
The derivatives are used in practice to build distortion nodes for compositing based on bicubic Hermite splices, like Nuke’s GridWarp.