**pixmorph**
performs feature-based image metamorphosis between "picA.pix" and "picB.pix". The feature correspondences are specified in the file "linesfile", which can be created using a utility such as
*morphedit.tcl*
(see
*morphedit(1)).*

The output image is computed in the following fashion. First, for each pixel in the output image, we choose a set
*A*
of pixels (and associated weights) from "picA.pix" and another set
*B*
of pixels from "picB.pix" (how these sets and weights are chosen will be described momentarily). The pixel values from
*A*
are then averaged (using the associated weights) to determine the contribution
*cA*
from the original image; the contribution
*cB*
is computed similarly. Then, the values
*cA*
and
*cB*
are interpolated by the value
*dissolvefrac*
to compute the final value of the output pixel.

Now, the contribution
*cA*
from the original image is intended to be the value from
*picA.pix*
that gets "warped to" the location in question. It is this computation (more specifically, the computation of
*A*
and associated weights) that is the heart of the morphing algorithm, and is described briefly here.

First, the linesfile is processed. The linesfile is of the form
a b p n lineseg1_initial lineseg1_final lineseg2_initial lineseg2_final
linesegn_initial linesegn_final
where
*n*
equals the number of line segments, and
*a, b,*
and
*p*
are constants that alter the nature of the morph. A line segment is represented as a list of four real numbers (and is interpreted as a directed line segment.) For example,
0.1 2.0 0.2 2 0.714844 0.560547 0.988281 0.277344 0.347656 0.646484 0.654297 0.896484 0.341797 0.611328 0.757812 0.265625 0.628906 0.519531 0.925781 0.763672
is a valid lines file. Typically, the pairs
*linesegi_initial linesegi_final*
have been placed by the user in the lines file to match up particular features of
*picA.pix*
and
*picB.pix*
(the feature at
*linesegi_initial*
in
*picA.pix*
corresponds to the feature at
*linesegi_final*
in
*picB.pix.)*
For instance,
*lineseg1_initial*
might be a line segment running down the length of the nose of a person displayed in
*picA.pix;*
then
*lineseg1_final*
would be a line segment running down the length of the nose of the person featured in
*picB.pix.*
See
*morphedit(1)*
for more information about creating a lines file.

Now, for each line segment pair
*(s,t),*
we perform the following procedure: We interpolate between
*s*
and
*t*
by factor
*warpfrac*
to yield the interpolated line segment
*s.*
From the change in position, scale, and orientation of a line segment from its initial position
*s*
to its interpolated counterpart
*s*
we may deduce a linear transformation in the image space. More specifically, if the line segment
*s*
must undergo translation, stretching, and rotation to yield
*s,*
we compute a linear transformation
*T*
of the image space that performs the same translation, stretching, and rotation. (So
*T*
applied to
*s*
yields
*s.)*
The inverse
*T**
of this transformation maps
*s*
to
*s;*
for instance,
*T**
will take an endpoint of
*s*
to the corresponding endpoint of
*s,*
and will preserve the relationship of every other point to the line segment. We apply this inverse
*T**
to the coordinates
*(x,y)*
to find an appropriate pixel in the original image. Along with this, we compute a weight based on the length of the line segment
*s*
along with its distance from
*(x,y).*
This weight is equal to
( (length ** p) / (a + dist) ) ** b
(where
****
denotes exponentiation,
*length*
is the length of
*s,*
*dist*
is the distance from
*s*
to
*(x,y), and*
*a, b, p*
are constants chosen by the user and stored in the lines file.)

The set
*A*
of pixels is then collected by performing these computations for each line segment, and the resulting contribution
*cA*
is then computed by averaging over
*A*
with the appropriate weights.

In practice,
*a*
= 0.1,
*b*
= 2.0, and
*p*
= 0.2 seems to work well.

In general, the user will wish to set
*warpfrac*
=
*dissolvefrac.*
Typically, a morph animation will be produced by computing a sequence of images using
*pixmorph,*
each with slightly greater
*warpfrac*
(and
*dissolvefrac)*
(see the example.)
For a clearer and more thorough explanation, see
T. Beier and S. Neely. Feature-Based Image Metamorphosis. "SIGGRAPH 1992 Computer Graphics Proceedings (volume 26 number 2)" (Chicago, July 26-31, 1992). pp 35-42.
which presents the algorithm used by
*pixmorph.*

pixmorph face1.pix face2.pix lf 0.0 0.0 > frame0.pix pixmorph face1.pix face2.pix lf 0.2 0.2 > frame1.pix pixmorph face1.pix face2.pix lf 0.4 0.4 > frame2.pix pixmorph face1.pix face2.pix lf 0.6 0.6 > frame3.pix pixmorph face1.pix face2.pix lf 0.8 0.8 > frame4.pix pixmorph face1.pix face2.pix lf 1.0 1.0 > frame5.pix

Note that the example above will result in
*frame0.pix*
=
*face1.pix*
and
*frame5.pix*
=
*face2.pix.*

pixmorph face1.pix face2.pix lf 0.5 0.0 > out.pix

Note that in this example,
*dissolvefrac*
= 0. This will warp
*face1.pix*
and
*face2.pix*
by the appropriate amount, but will ignore the contributions of
*face2.pix*
at the cross-dissolve stage. So the final image
*out.pix*
will consist entirely of values from
*face1.pix*
warped 50% according to the linesfile
*lf.*

pixmorph face1.pix face2.pix lf 0.0 0.5 > out.pix

In this example,
*warpfrac*
= 0. This will perform a simple 50% cross-dissolve between
*face1.pix*
and
*face2.pix.*