Fred's ImageMagick Scripts



    Licensing:

    Copyright © Fred Weinhaus

    My scripts are available free of charge for non-commercial (non-profit) use, ONLY.

    For use of my scripts in commercial (for-profit) environments or non-free applications, please contact me (Fred Weinhaus) for licensing arrangements. My email address is fmw at alink dot net.

    If you: 1) redistribute, 2) incorporate any of these scripts into other free applications or 3) reprogram them in another scripting language, then you must contact me for permission, especially if the result might be used in a commercial or for-profit environment.

    Usage, whether stated or not in the script, is restricted to the above licensing arrangements. It is also subject, in a subordinate manner, to the ImageMagick license, which can be found at: http://www.imagemagick.org/script/license.php

    Please read the Pointers For Use on my home page to properly install and customize my scripts.

BILINEARWARP


Applies or four corner true bilinear warp of an image.

Download Script

last modified: March 02, 2020



USAGE: bilinearwarp [-f format] [-v vpmode] [-b bgcolor] "x1,y1 x2,y2 x3,y3 x4,y4" infile outfile
USAGE: bilinearwarp [-h or -help]

"x1,y1 ... x4,y4" ....... four and only four control point x,y coordinates;
......................... these are where the corners of input image are
......................... desired in the output image; must be ordered clockwise
......................... starting with the point corresponding to the upper
......................... left corner of input image; floats>=0;
......................... list must be specified just prior to infile
-f ... format ........... format for output size; B or box (for bounding box)
......................... or I or input (for same as input); default=box
-v ... vpmode ........... any valid IM virtual-pixel mode; default=black
-b ... bgcolor .......... background color when virtual-pixel is set to
......................... background; Any valid IM color; default=black

PURPOSE: To generate a proper four-point bilinear warp of the input image.

DESCRIPTION: BILINEARWARP generate a proper four-point bilinear warp of the input image using the corners of the input image and the specified corresponding coordinates where it is desire that those corner points be located in the output image. The input coordinates are not specified as they will be found from the image dimensions. The four output x,y coordinates must be specified in clockwise order starting with the corresponding point to the upper left corner of the input image.

ARGUMENTS:

"x1,y1 x2,y2 x3,y3 x4,y4" ... LIST of x,y coordinates in the output image that correspond to where the corners of the input image are desired to be located. The input coordinates are not specified as they will be found from the image dimensions. The four output x,y coordinates must be specified in clockwise order starting with the corresponding point to the upper left corner of the input image. Values may be floats>=0.

-f format ... FORMAT for output size. The choices are to make the output the same size as the input (value=I or input) or to make the output the size of the bounding box around the set of specified output control point coordinates (value=B or box). The default is B (bounding box).

-v vpmode ... VPMODE is any valid IM virtual-pixel method. The default is black.

-b bgcolor... BGCOLOR is the fill color for the background area outside of the warped image when the virtual-pixel method is specified as background. Any valid IM color may be used. Values should be enclosed in quotes if not color names. See http://imagemagick.org/script/color.php

Mathematical Background (600KB PDF)

NOTE: This script may be slow due to the use of -fx.

CAVEAT: No guarantee that this script will work on all platforms, nor that trapping of inconsistent parameters is complete and foolproof. Use At Your Own Risk.


EXAMPLES


Various Bilinear Warps Of Mandril Image

Original Image

Arguments:
-f input "0,0 182,28 255,198 21,255"

Arguments:
-f input "0,56 232,0 255,255 70,226"

Arguments:
-f input "8,63 152,71 255,165 0,190"

Arguments:
-f box "8,63 152,71 255,165 0,190"



Comparison Of 1.5 Order Polynomial vs Bilinear vs Perspective Warps
For more details see Four Corner Image Warping (388KB PDF)

Original Image

1.5 Order Polynomial Warp
Arguments:
-virtual-pixel black \
-distort bilinear \
"0,0 52,0 255,0 228,46 \
255,255 255,229 0,255 0,246"

Bilinear Warp
Arguments:
-f input "52,0 228,46 255,229 0,246"

Perspective Warp
Arguments:
-virtual-pixel black \
-distort perspective \
"0,0 52,0 255,0 228,46 \
255,255 255,229 0,255 0,246"

The 1.5 order polynomial warp does not preserve straight lines. Thus all the grid lines, the edges of the image and diagonal lines are curved in the quadrilateral.

The bilinear warp preserves straight lines parallel to the coordinate axes. Thus all the grid lines and the edges of the image remain straight. But the diagonal lines are not preserved and are curved in the quadrilateral. lines curve.

The perspective warp preserves all straight lines.

 

Inverse Distance Squared Weighted Warp
(Shepard's Interpolation Method)
Arguments:
-virtual-pixel black \
-distort shepards \
"0,0 52,0 255,0 228,46 \
255,255 255,229 0,255 0,246"

 

   

 

Inverse Distance Warp produces strange curvature.

 



What the script does is as follows:

  • Inverts the following 1.5 order transformation which involves solving a quadratic equation
  • x = a0 + (a1 * u) + (a2 * v) + (a3 * u * v)
  • y = b0 + (b1 * u) + (b2 * v) + (b3 * u * v)

This is equivalent to the following IM commands for the case
of an arcsin warp onto a sphere:

  • A=`convert xc: -format "%[fx:($b2 * $a3) - ($b3 * $a2)]" info:`
  • B1=`convert xc: -format "%[fx:(($b0 * $a3) - ($b3 * $a0)) + (($b2 * $a1) - ($b1 * $a2))]" info:`
  • C1=`convert xc: -format "%[fx:($b0 * $a1) - ($b1 * $a0)]" info:`
  • convert $infile -virtual-pixel $vpmode \
    -background $bgcolor -monitor \
    -fx "bb=$B1+($b3*i)-($a3*j); cc=$C1+($b1*i)-($a1*j); rt=(bb*bb)-(4*$A*cc); \
    il=(-bb+sqrt(rt))/(2*$A); is=(i-$a0-($a2*il))/($a1+($a3*il)); u.p{is,il}" \
    $outfile