[SCS dragon logo]

Programming Assignment #3

15-463: Rendering and Image Processing






Due Date: by 11:59pm, Tu, Nov 9 (NEW!)


In this assignment you will produce a "morph" animation of your face into another student's face. Each of you will generate two seconds of animation, which we will record onto video for you. The final video will thus be a metamorphosis through each of the faces in the class.

A morph is a simultaneous warp of the image shape and a cross-dissolve of the image colors. The cross-dissolve is the easy part; controlling and doing the warp is the hard part. The warp is controlled by defining a correspondence between the two pictures. The correspondence should map eyes to eyes, mouth to mouth, chin to chin, ears to ears, etc., to get the smoothest transformations possible.

Send James a picture of yourself (try to find a picture close to the “passport photo” configuration).  We will give you a starting image ("picture A") and an ending image ("picture B") for your animation sequence. Picture A will be your face. Picture B will be another student or other primate.  Pictures will be stored in the following directory: data/

You'll morph still picture A into still picture B and produce 61 frames of animation numbered 0-60, where frame 0 must be identical to picture A and frame 60 must be identical to picture B. In the video, each frame will be displayed for 1/30 of a second.  Name your frames morph??.tif where ?? is 00 to 60. 

There are a variety of different methods you could use to do your morph. Regardless of which method you use the work typically divides into two parts: writing a program to perform the morph given the correspondence, and using an interactive program to define the correspondence.



You need to write a function:

morphed_im = morph(im1, im1_pts, im2, im2_pts, warp_frac, dissolve_frac);

that produces a warp between im1 and im1 using point correspondences defined in im1_pts and im2_pts (which are both n-by-2 matrices of (x,y) points). The parameters warp_frac and dissolve_frac control warping and cross-dissolve, respectively. They both lie in the range [0,1]. They are the only parameters that will vary from frame to frame in the animation. For your starting frame, they will both equal 0, and for your ending frame, they will both equal 1. When you produce the final frame files, you will want them to be equal for all frames, but during debugging of your morph program, it can be helpful to have independent control of these two parameters.

You are free to use any morphing algorithm you like (except Matlab’s build-in offerings, e.g. imtransform).  One possibility is implementing the Beier & Neely algorithm discussed in class.  In this case, the correspondences should be specified in terms of line segments (two (x,y) pairs per correspondence). You can either try using cpselect or write your own little tool using ginput and plot (with hold on and hold off).

Another morphing approach is to perform a triangulated piecewise affine warp. In this case, you will specify the correspondence in terms of pairs of corresponding points in pictures A and B (cpselect is probably the easiest way to go). Triangulate the points in picture A, use a triangulation with the same topology (connectedness) in picture B. This defines corresponding triangles. Now use an affine warp for each triangle.  The triangulation can be specified either by hand or by using Delaunay triangulation (which is, conveniently, a function in matlab: delaunay).





To get full credit, you will need to implement a warping algorithm and turn in a video morph.  Doing some Bells & Whistles will earn you extra points.