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.

SPLINE


Draws a spline curve on an image based upon supplied points

Download Script

last modified: June 23, 2022



USAGE: spline [-s spline] [-t tension] [-b bias] [-e endmode] [-c curvecolor] [-p pointcolor] [-l linecolor] [-i interiorcolor] [-sw strokewidth] [-d widthxheight] [-bg bgcolor] "x1,y1 x2,y2 ..." [infile] outfile
USAGE: spline [-s spline] [-t tension] [-b bias] [-e endmode] [-c curvecolor] [-p pointcolor] [-l linecolor] [-i interiorcolor] [-sw strokewidth] [-d widthxheight] [-bg bgcolor] -f point_file [infile] outfile
USAGE: spline [-s spline] [-t tension] [-b bias] [-e endmode] [-c curvecolor] [-p pointcolor] [-l linecolor] [-i interiorcolor] [-sw strokewidth] [-d widthxheight] [-bg bgcolor] -j point_file [infile] outfile
USAGE: spline [-h or -help]

"x1,y1 x2,y2 ..." ....... break point values of piece-wise linear transformation
......................... enclosed in quotes; minimum of one (x,y) break point pair;
......................... x corresponds to the graylevel in the input image;
......................... y corresponds to the graylevel in the outut image;
......................... x,y non-negative floats enclosed in quotes;
......................... number of points must be >= 4; MUST be specified
......................... just prior to infile outfile in the command line.
......................... list must be specified just prior to lutfile
-f ... point_file ....... text file containing list of break points;
......................... one x,y pair per line
-j ... point_file ....... ImageJ "pointpicker" plugin text file containing list of
......................... break points;
......................... one x,y pair per line
-s ... spline ........... spline type; bezier, bspline, cubic, hermite, kbs;
......................... default=kbs
-t ... tension .......... tension parameter for kbs spline; float; default=0
-b ... bias ............. bias parameter for kbs spline; float; default=0
-e ... endmode .......... end mode for the curve; choices are: none (N),
......................... duplicate (D), extend (E), close (C); default=N
-c ... curvecolor ....... color for drawing spline curve; default=red
-p ... pointcolor ....... color for drawing original points; if not supplied,
......................... original points will not be drawn
-l ... linecolor ........ color for drawing lines between original points;
......................... if not supplied, lines will not be drawn
-i ... interiorcolor .... interior fill color; only allowed for closed curves;
......................... if not supplied, then the closed curve will not be filled
-sw .. strokewidth ...... strokewidth for the curve; default=1
-d ... widthxheight ..... if no input image is supplied, then widthxheight will
......................... create an empty canvas of of size width x height with
......................... background color specified the -bg bgcolor option
-bg .. bgcolor .......... background color to use when no input image is supplied

PURPOSE: To draw a spline curve on an image based upon supplied points.

DESCRIPTION: SPLINE draws a spline curve on an image based upon user supplied points from a supplied list in the command line or from a file with one point per line. Several spline types are available which include both interpolating splines that pass through the supplied points and approximating splines that do not pass through the points. The spline types are: bezier (approximating), bspline (approximating), cubic (interpolating), hermite (interpolating) and kbs (interpolating). Options allow the original points and/or lines between the original points to be drawn in addition to the splined curve.

ARGUMENTS:

"x1,y1 x2,y2" ... List of x,y points that define either the knots or the control points for the knots. The x,y coordinates allow float values. The number of supplied points must be at least 4. For most splines (except bezier) they are processed four at a time, then shifted by one and that set of four processed. Within each set of four the curve is drawn for the middle two points. For bezier, they are again processed in groups of four, but the curve is drawn between the first and fourth point, then shifted by 3 to get the next set of four, such that the fourth point of the previous set becomes the first point in the current set. For the bezier spline the number of points must be 4 or a multiple of 4 less 1. IMPORTANT: the sequence of points MUST be specified just prior to infile outfile in the command line.

-f point_file ... point-file is a text file containing the list of break points, one x,y pair per line.

-j point_file ... point-file is a text file containing the list of break points, one x,y pair per line in the imageJ "pointpicker" plugin format.

-s spline ... SPLINE is the type of spline to use. All but the cubic are derived from the fundamental Hermite spline that uses 2 knots and 2 tangent values at the knots. The various splines below (except cubic) convert the tangent into either control points or other knot values in order to avoid having to specify a tangent directly. The choices are:

1) bezier: an approximating spline that does not pass through the supplied points. The supplied points are specified as combinations of knots (start and end points) and control points whose vectors (Cb-Kb) and (Ke-Ce) determine the tangent direction at the given knots. A group of 4 points must be specified in the order of Kb Cb Ce Ke and 7 or more points as K C C K C C K ... where Kb is the begining knot, Cb is the beginning control point for that knot, Ke is the end knot and Ce is the end control point for that knot.

2) bspline: an approximating spline that does not pass through the supplied points. All supplied points are knots and the curve will pass near the knots. This spline has first and second derivative continuity at the knots. Therefore this is a very good interpolating spline to use if you want little user interaction to control shape and curvature and still get a very smooth curve, but it will not pass through the supplied points.

3) cubic: an interpolating spline that does pass through the supplied points. All supplied points are knots. This spline has only first derivative continuity at the knots and thus can have rather strange curvature.

4) hermite: an interpolating spline that does pass through the supplied points. All supplied points are knots. This is a special case of the general hermite spline such that the tangent at the knots is determined by the direction between successive knots. Thus, this spline will not generally have first derivative continuity at the knots, i.e. it will not have smooth continuity at the knots.

5) kbs (Kochaneck-Bartels Spline): an interpolating spline that does pass through the supplied points. In addition this spline has optional tension and bias controls. Positive tension makes the spline tighter (approaches straight lines) and negative tension makes the spline broader or more rounded. Positive bias shifts the curve counter clockwise relative the knot. Negative bias shifts the curve clockwise relative to the knot. With zero bias, the kbs spline is identical to the cardinal spline (which also allows tension). With both zero bias and zero tension, the kbs spline is identical to the Catmull-Rom spline. The kbs spline has only first derivative continuity at the knots, but is generally a good interpolating spline to use if you want little user interaction and still get a smooth curve that does pass through the supplied points.

-t tension ... TENSION is use only with the kbs spline and controls the degree of tightness or roundness of the spline curve. Positive tension makes the curve tighter (i.e. approaches straight lines) and negative tension makes the curve broader or rounder. The default is 0.

-b bias ... BIAS is used only with the kbs spline and controls the shift of the curve relative the the supplied point. Positive bias shifts the curve forward relative to the supplied points and negative bias shifts the curve backward relative to the supplied points. The default is 0.

-e endmode ... ENDMODE defines how to treak the region near the first and last knot in the list of supplied points. The default=none and is the only option allowed for the bezier spline. For the other splines, the choices are:

1) none or N: this will lead to the region between the first and second points being ignored and likewise the region between the next to last and last points being ignored. For all but the bezier spline, users should augment the point list with their own extra beginning and ending point in order to allow the curve to be drawn through all the un-augmented list of points. As the bezier spline draws between the first and last point of each group of four points, augmenting is not needed and this option should be used. This is the default value.

2) duplicate or D: this will duplicate the first point and add it to the very beginning of the sequence of supplied points and also duplicate the last point and add it to the very end of the sequence of supplied points. The result will differ only slightly from the extend option only on the first and last segment.

3) extend or E: this will add an extra point at the beginning and end of the sequence of supplied points by extending the line between the first two points backward behind the first point and likewise by extending the line between the last two points forward beyond the last point. The result will differ only slightly from the duplicate option only on the first and last segment.

4) close or C: this means that the curve should be closed. Thus the region between the first and last supplied points should be drawn.

-c curvecolor ... CURVECOLOR is the color to use to draw the splined curve. Any valid IM color is allowed. Enclose the color in double quotes if not a color name. The default is red.

-p pointcolor ... POINTCOLOR is the color to use to draw the supplied points (in addition to the curve). Points will be drawn as 3-pixel diameter circles. If this option is not suppled, then no points will be drawn. Thus there is no default color for this option. Any valid IM color is allowed. Enclose the color in double quotes if not a color name.

-l linecolor ... LINECOLOR is the color to use to draw the lines between the supplied points (in addition to the curve). If this option is not suppled, then no points will be drawn. Thus there is no default color for this option. Any valid IM color is allowed. Enclose the color in double quotes if not a color name.

-i interiorcolor ... INTERIORCOLOR is the color to use to fill the inside of closed curves. If this option is not suppled, the closed curve will not be filled. Thus there is no default color for this option. Any valid IM color is allowed. Enclose the color in double quotes if not a color name.

-sw strokewidth ... STROKEWIDTH is the width of the line used to draw the curve. The value may be a float > 0. The default is 1.

-d widthxheight ... WIDTHxHEIGHT is the desired width and height to use for the canvas when no input image is provided. This parameter MUST be provided if no input image is supplied.

-bg bgcolor ... BGCOLOR is the color to use for the canvas background when no input image is provided. Any valid IM color is allowed. Enclose the color in double quotes if not a color name. The default is white.

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.


Thanks to Anthony Thyssen for the technique used to draw the blue point circles efficiently


EXAMPLES


KBS: Tension=0; Bias=0 --- Variation In End Mode --- Point Set 1

End Mode = None arguments:
-s kbs -p blue -e none -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Duplicate arguments:
-s kbs -p blue -e duplicate -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s kbs -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s kbs -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



KBS: Variation In Tension (Bias=0) --- Point Set 1

Negative Tension arguments:
-s kbs -t -0.5 -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

Neutral Tension arguments:
-s kbs -t 0 -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

Positive Tension arguments:
-s kbs -t 0.5 -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



KBS: Variation In Bias (Tension=0) --- Point Set 1

Negative Bias arguments:
-s kbs -b -1 -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

Neutral Bias arguments:
-s kbs -b 0 -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

Positive Bias arguments:
-s kbs -b 1 -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



Hermite --- Variation In End Mode --- Point Set 1

End Mode = None arguments:
-s hermite -p blue -e none -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Duplicate arguments:
-s hermite -p blue -e duplicate -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s hermite -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s hermite -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



Cubic --- Variation In End Mode --- Point Set 1

End Mode = None arguments:
-s cubic -p blue -e none -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Duplicate arguments:
-s cubic -p blue -e duplicate -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s cubic -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s cubic -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



B-Spline --- Variation In End Mode --- Point Set 1

End Mode = None arguments:
-s bspline -p blue -e none -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Duplicate arguments:
-s bspline -p blue -e duplicate -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s bspline -p blue -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

End Mode = Extend arguments:
-s bspline -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



Spline Comparison --- Point Set 1 --- End Mode Extend

kbs arguments:
-s kbs -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

hermite arguments:
-s hermite -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

cubic arguments:
-s cubic -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"

bspline arguments:
-s bspine -e extend -d 141x101
"20,50 32.5,75 45,50 57.5,25
70,50 82.5,75 95,50 107.5,25 120,50"



KBS: Variation In Tension (Bias=0) --- Point Set 2: Closed (Counter Clockwise) Square

Negative Tension arguments:
-s kbs -t -0.5 -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

Neutral Tension arguments:
-s kbs -t 0 -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

Positive Tension arguments:
-s kbs -t 0.5 -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

Neutral Tension arguments:
-s kbs -t 0
-e close -d 101x101
"25,25 25,75 75,75 75,25"



KBS: Variation In Bias (Tension=0) --- Point Set 2: Closed (Counter Clockwise) Square

Negative Bias arguments:
-s kbs -b -0.5 -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

Neutral bias arguments:
-s kbs -b 0 -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

Positive Bias arguments:
-s kbs -b 0.5 -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

Neutral Bias arguments:
-s kbs -b 0
-e close -d 101x101
"25,25 25,75 75,75 75,25"



Hermite: --- Point Set 2: Closed Square

arguments:
-s hermite -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

arguments:
-s hermite
-e close -d 101x101
"25,25 25,75 75,75 75,25"



Cubic: --- Point Set 2: Closed Square

arguments:
-s cubic -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

arguments:
-s cubic
-e close -d 101x101
"25,25 25,75 75,75 75,25"



B-Spline: --- Point Set 2: Closed Square

arguments:
-s bspline -p blue -l green1
-e close -d 101x101
"25,25 25,75 75,75 75,25"

arguments:
-s bspline
-e close -d 101x101
"25,25 25,75 75,75 75,25"



Spline Comparison --- Point Set 2 --- End Mode Closed

kbs arguments:
-s kbs -e close -d 101x101
"25,25 25,75 75,75 75,25"

hermite arguments:
-s hermite -e close -d 101x101
"25,25 25,75 75,75 75,25"

cubic arguments:
-s cubic -e close -d 101x101
"25,25 25,75 75,75 75,25"

bspline arguments:
-s bspine -e close -d 101x101
"25,25 25,75 75,75 75,25"



Bezier: --- Point Set 3 --- Comparison To IM MVG Bezier

arguments:
-s bezier -p blue -l green1 -d 141x101
"20,50 45,100 95,0 120,50"

arguments:
-s bezier -d 141x101
"20,50 45,100 95,0 120,50"

IM MVG -draw
arguments:
-size 141x101 xc:white -fill none -stroke red
-draw "bezier 20,50 45,100 95,0 120,50"
-draw "fill none stroke green1
line 20,50 45,100 line 95,0 120,50"

IM MVG -draw
arguments:
-size 141x101 xc:white
-draw "fill none stroke red
bezier 20,50 45,100 95,0 120,50"



Bezier: --- Point Set 4 --- Comparison To IM MVG Bezier

(MVG bezier segments must be drawn individually, not as one long linked list)

arguments:
-s bezier -p blue -l green1 -d 141x101
"20,50 45,100 45,0 70,50 95,100 95,0 120,50"

(note linked segments point sequence: K C C K C C K)

arguments:
-s bezier -d 141x101
"20,50 45,100 45,0 70,50 95,100 95,0 120,50"

(note linked segments point sequence: K C C K C C K)

IM MVG -draw
arguments:
-size 141x101 xc:white
-draw "fill none stroke red
bezier 20,50 45,100 45,0 70,50
bezier 70,50 95,100 95,0 120,50"
-draw "fill none stroke green1
line 20,50 45,100 line 45,0 70,50
line 70,50 95,100 line 95,0 120,50"

(note point sequence: K C C K for each segment)

IM MVG -draw
arguments:
-size 141x101 xc:white
-draw "fill none stroke red
bezier 20,50 45,100 45,0 70,50
bezier 70,50 95,100 95,0 120,50"

(note point sequence: K C C K for each segment)



Bezier: --- Variation In Control Points

arguments:
-s bezier -p blue -l green1 -d 141x101
"20,50 45,100 45,0 70,50 95,100 95,0 120,50"

arguments:
-s bezier -p blue -l green1 -d 141x101
"20,50 20,100 70,100 70,50 70,0 120,0 120,50"

arguments:
-s bezier -p blue -l green1 -d 141x101
"20,50 20,100 70,0 70,50 70,100 120,0 120,50"

arguments:
-s bezier -d 141x101
"20,50 45,100 45,0 70,50 95,100 95,0 120,50"

arguments:
-s bezier -d 141x101
"20,50 20,100 70,100 70,50 70,0 120,0 120,50"

arguments:
-s bezier -d 141x101
"20,50 20,100 70,0 70,50 70,100 120,0 120,50"



KBS: Tension=0; Bias=0 --- Closed Points On Image

Image

arguments:
-s kbs -t 0 -b 0 -e close -p skyblue
-f im_logo_star.txt
(see file below)

arguments:
-s kbs -t 0 -b 0 -e close
-f im_logo_star.txt
(see file below)

arguments:
-s kbs -t 0 -b 0 -e close
-c purple -i purple
-j im_logo_star_ij.txt
(see file below)

  (Plain Text File:)

58,87
64,98
66,112
87,115
95,122
90,134
75,146
82,163
79,174
64,174
48,159
22,176
10,174
 7,161
18,140
11,119
11,108
17,103
32,103
44,92
(ImageJ "pointpicker" file)
  point   x    y    slice color
    0    58    87     1     0
    1    64    98     1     1
    2    66   112     1     2
    3    87   115     1     3
    4    95   122     1     4
    5    90   134     1     5
    6    75   146     1     6
    7    82   163     1     7
    8    79   174     1     8
    9    64   174     1     9
   10    48   159     1    10
   11    22   176     1    11
   12    10   174     1    12
   13     7   161     1    13
   14    18   140     1    14
   15    11   119     1    15
   16    11   108     1    16
   17    17   103     1    17
   18    32   103     1    18
   19    44    92     1    19
ImageJ and
pointpicker plugin


KBS Spline --- Point Set 5: Closed Square --- Extreme Changes In Negative Tension

tension=0
arguments:
-s kbs -t 0 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=-0.6 (circle)
arguments:
-s kbs -t -0.6 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=-1
arguments:
-s kbs -t -1 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=-2
arguments:
-s kbs -t -2 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=-3
arguments:
-s kbs -t -3 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=-4
arguments:
-s kbs -t -4 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"



KBS Spline --- Point Set 5: Closed Square --- Extreme Changes In Positive Tension

tension=0
arguments:
-s kbs -t 0 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=0.6
arguments:
-s kbs -t 0.6 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=1 (square)
arguments:
-s kbs -t 1 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=2
arguments:
-s kbs -t 2 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=3
arguments:
-s kbs -t 3 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"

tension=4
arguments:
-s kbs -t 4 -e close -d 100x60
-c firebrick -i red -sw 2
"32.3,12.3 32.3,47.7 67.7,47.7 67.7,12.3"



What the script does is as follows:

  • Reads data points
  • Spline interpolates
  • Draws interpolated polyline