Skip to content

Affine Distortion

Affine distortion performs scaling, rotation, translation and shearing of image simultaneously. It supports best fit viewport calculation for output image that will contain whole distorted image.

Affine distortion may be performed in 2 different ways:

Affine distortion using control points

Affine distortion can be performed using an array of control points mapping:

ts
const result = await distort(image, "Affine", controlPoints);

where controlPoints is flat array of control points mappings.

INFO

Control points mapping is 4 numbers: U, V, X, Y, where U and V are corresponding x and y coordinates of source image point, and X and Y are corresponding x and y coordinates of that point in result image.

Behavior of distortion differs according to number of control points.

  • If only one set (4 values) of control points given, only translation will be performed.
  • If 2 sets (8 values) of control points given — scaling (vertical and horizontal simultaneously), rotation and translation can be performed.
  • With 3 sets of control points all affine transformations became available.

When more than 3 sets of control points given, Lens will use Least Squares Fitting to find the best '3 point' affine distortion matching all the coordinate pairs given. That means the source image control points may not map exactly to destination image control points, but a best-fit 'average' of all the points given. For example if you have a scan of a document, you could locate and map all 4 corners of the document for an affine distortion to correct for rotation and scaling of the document. In this way you can get a better 'average' fit based of 4 points rather than 3 points.

Note that while more coordinates can produce a better and more accurate distortion, if one coordinate pair is very bad, then the least squares fit may not produce a very good fit at all. Some check to eliminate 'bad coordinate pairs' may be needed.

When using Control points form of an affine distortion, these control point mappings are mathematically transformed into 6 special numbers which represent the 'coefficients' of an Affine Projection.

Affine distortion using affine matrix

The other form of using affine distortion is by using affine matrix:

ts
const matrix = [sx, ry, rx, sy, tx, ty];
const result = await distort(image, "AffineProjection", matrix);

The 6 floating point arguments, sx,rx,ry,sy,tx,ty are (in the order to be given) the coefficients used for the Forward Mapping of points in the source image to the destination image. That is they are the mathematical values used to map a source image (u, v) to a destination image (x, y).

These in turn form the distortion expressions:

Xd=sxXs+ryYs+txYd=rxXs+syYs+ty

Where Xs, Ys are source image coordinates and Xd, Yd are destination image coordinates. Internally Lens will reverse the above equations so as to do the appropriate Pixel Mapping to map Xd, Yd coordinates to lookup the color at Xs, Ys in the source image.

If you already have these coefficients pre-calculated, then you can directly supply them to Lens to distort the image.