Pages

Jan 1, 2012

Image Morphing

Happy new year. I've started this blog today with an article about computer vision.

Introduction

In this article, I will explain about "Image Morphing" which means changing the shape of a object gradually into the shape of another object. I wrote a program code using OpenCV. My algorithm is based on this slide. My code morph myself into "dragon". Why dragon? In Japan, each year is associated with an animal according to a 12-year mathematical cycle, and 2012 is a year-of-dragon. So, this program is a kind of new year greeting to readers :)

Overview

Image Morphing needs two images and mapping between their feature point as input, and is composed of two phase. First, images need to be warped so that their corresponding feature point is at the same position. Second, blend two images into one image using cross-dissolving. So images are warped and cross-dissolving into one image while time parameter is increasing. I will explain the detail about these methods.

Warping

Warping is required to make corresponding pixels in two images be at the same position. To do so, we have to prepare pairs of lines. In this experiment, I use these two images. the left is a source image, and the right is a destination image.

source image

destination image

Pairs of lines for these images are below.
First, lines of the source image.

The first line is the number of lines n. Next n lines contains four integers - Px, Py, Qx, Qy which represent the coordinate of the starting point and the ending point. For example, the first line or left image is from (74, 130) to (122, 1) which means from left ear to top of the head, and the first line of right image is the corresponding one.

We need to get warped image from the pairs. If the location of X' on the destination image is given, how to calculate the location of X on the source image which is corresponding to X'?

First, we calculate u and v. The value u goes from 0 to 1 as the pixel moves from P' to Q'. The value v is the perpendicular distance from the line to X'. Once we get u and v, we can apply them to the source image, and so X coordinate will be acquired.

In this case, we have multiple pairs of lines, so we need to average the sum of X coordinate weighted by a kind of factor. The factor is set to be inversely proportional to the distance from line and directly proportional to the length of the line. (the details are described in the slide mentioned in "Instruction".)

By calculating source pixels for each pixels in the destination image, we can get warped image whose shape is closer to the destination image.

Cross-dissolving

Cross-dissolving is simpler than warping. We already have similar-shape images. For each pixel in the destination image, we mix the values of corresponding source pixel and destination pixel. The ratio of mixture depends on the time parameter. Time parameter goes from 0 to 1, so at the beginning point(t=0) the ratio of the source image is 1 and the other is 0, and at the end point (t=1) vice versa.

Warping+cross-dissolving=Morphing

As I mentioned above, the time parameter goes from 0 to 1. To complete morphing the source image into the destination image, at first we compute the intermediate image at each time. This means that both the source image and the destination image are warped into the intermediate image. So, for each pixels in intermediate image, we can also compute the corresponding pixels in the source image and the destination image. After that, apply cross-dissolving to these pixels.

Result

Source code

Notice: This source code requires OpenCV 2.0 or later, and this only outputs image files corresponding to each frame. I used ffmpeg to combine those image files into a movie file.

Just check your code once again...i think the problem is that it has not been posted correctly. You for loops are not closing.eg: for (int i=0; i> x1 >> y1 >> x2 >> y2; CvPoint p1=cvPoint(x1,y1); CvPoint p2=cvPoint(x2,y2); srcFeatures.pb(mp(p1,p2)); }There are many more...so just update the post

In my dragon example, argv[2] is srcFeature.txt and argv[4] is destFeature.txt described in this article. In these files, first line is a number of "lines" after the first line and each lines after the first line represents the x-y axis of the line on the image. Each line consists of 4 integer, x-axis/y-axis of the start point and x-axis/y-axis of the end point. The line of srcFeature.txt corresponds to destFeature.txt. For example, in my dragon example, The line between (74, 130) and (122, 1) on the src image corresponds to the line between (84, 83) and (147, 20) on the dest image. "correspond" means the lines on the src image is morphed into the line on the dest image.

Labels

Blog Archive

About Me

Software Engineer with strong experience of Mobile Development. Developed FireMobileSimulator which is one of the most popular mobile simulator in Japan. Also Interested in Computer Vision, Virtual Reality, 3D, Optics, Algorithm, Machine Learning.