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].

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].

The derivatives are used in practice to build distortion nodes for compositing based on bicubic Hermite splices, like Nuke’s GridWarp.