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:
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:
const matrix = [sx, ry, rx, sy, tx, ty];
const result = await distort(image, "AffineProjection", matrix);
The 6 floating point arguments,
These in turn form the distortion expressions:
Where
If you already have these coefficients pre-calculated, then you can directly supply them to Lens to distort the image.
Links
- Affine distortion details at ImageMagick docs.
- Affine transform details at ImageMagick docs.
- Affine Transformation at Wikipedia.
- Affine transformations (and cousins) at Leptonica.