Image processing (10) Image deformation based on feature line-siggraph 1992

Source: Internet
Author: User
Tags pow relative getv

We're going to share it with you. Paper is based on feature line image morphing, corresponding English literature for "feature-based image Metamorphosis", is a siggraph on paper in 1992, an older paper, However, this paper citation rate is very high, for image distortion effect is very good, this algorithm is generally used for image morphing. Because this paper algorithm principle is simple, easy to implement, so don't be afraid to learn how long this algorithm takes.

Before you begin, this post is mainly for reference from: Http://www.csie.ntu.edu.tw/~b97074/vfx_html/hw1.html at the same time with my own understanding, with you to share the algorithm, to help more enthusiasts learn, non-commercial use.

first, related theories

We know that the essence of image deformation, in fact, is to obtain the optical flow field, is to obtain the target image of each pixel point in the original image corresponding to the location point, and then the same over bilinear interpolation method can be obtained target image.

1, single segment constraint deformation:


Given the original image source images, we want to the original image of the pixel point P ', Q ' position to the P, Q position, then the location of the other pixels to how to move to make the resulting image destination images will not be severely distorted, This is the research content of image distortion. As shown in the figure, if the deformation method of the reverse mapping, for any point on the target image X, we only need to take the source image on the corresponding point x ' on it, of course, the inverse map X ' is often not an integer, need to be linearly interpolated, to obtain the pixel value of x '.

Known pq,p ' Q ', X-point, how do we find the X ' corresponding point x '?


In fact, it is very simple, the principle is to ensure that the two-dimensional (u,v) coordinates of the diagram can be the same, that is, we can through the above three formula, to find out X '. The simple point is to ensure that the proportional position coordinates (U,V) of x relative to the PQ are unchanged.

2, multi-segment constrained deformation

The above is for single-line constraint, for the case of multi-segment, mainly through the method of weighted average.


As shown in figure, now known as P1q1,p2q2,x, as well as the source image of P1 ' Q1 ', P2 ' Q2 ', we ask for X ' point.

At this point, we can first use the single-segment constraint method

(1) by p1q1, P1 ' Q1 ', X calculated X1 ';

(2) by P2Q2, P2 ' Q2 ', X calculated X2 ';

Then, by means of weighted averaging, we find X ':


The calculation of the weight w is calculated by the inverse of the distance from the point x to the line segment:


Where length represents the length of the segment, Dist represents the shortest distance from the point x to the segment. A,b,p are constants, we can choose P = 0 for their values, a = 1, b = 2.

OK, by the end of the algorithm, it feels loose, and we can calculate the X ' point,


Because X ' is generally not calculated to be exactly where the pixel of the original image is, we need to use bilinear interpolation to find the pixel value of x '.

You should know how to calculate X ' point after reading it. Then we have to go into the algorithm implementation phase.

Second, the implementation of the algorithm

Description The following code is referenced from: http://www.csie.ntu.edu.tw/~b97074/vfx_html/hw1.html

Algorithm:

1, according to Equation 1, 2, calculates the position of X point relative to each segment (u,v) coordinates.


Double New_u = dst_line. Getu (X);
Double New_v = dst_line. Getv (X);
Equation 1
Double line::getu (Vector2 X)
{
	double x_p_x = x.x-p.x; 
	Double x_p_y = x.y-p.y;
	Double q_p_x = q.x-p.x;
	Double q_p_y = q.y-p.y;
	Double U = ((x_p_x * q_p_x) + (x_p_y * q_p_y))/(Len * len)  ;
	return u;
}
Equation 2
Double Line::getv (Vector2 X) {
	double x_p_x = x.x-p.x;
	Double x_p_y = x.y-p.y;
	Double q_p_x = q.x-p.x;
	Double q_p_y = q.y-p.y;
	Double perp_q_p_x = q_p_y;  
	Double perp_q_p_y =-q_p_x;
	Double v = ((x_p_x * perp_q_p_x) + (x_p_y * perp_q_p_y))/len; 
	return v; 
}

2, according to Equation 3, and then inverse the x point in the location of the source image corresponding to the point X '.

Vector2 src_point = Src_line. Get_point (New_u, New_v);
The corresponding point of the PQ segment can be calculated according to u,v coordinates x
Vector2 line::get_point (Double U, double v)
{
	double q_p_x = q.x-p.x;
	Double q_p_y = q.y-p.y;
	Double perp_q_p_x = q_p_y;  
	Double perp_q_p_y =-q_p_x;
	Double point_x = p.x + u * (q.x-p.x) + ((v * perp_q_p_x)/len);
	Double point_y = p.y + u * (q.y-p.y) + ((v * perp_q_p_y)/len);
	Vector2 X;
	x.x = point_x;
	x.y = point_y;
	return X;
}

3. Calculate the weights of each segment.

Double src_weight = dst_line. Get_weight (Dst_point);

Double Line::get_weight (Vector2 X)
{
	Double A = parameter_a;
	Double b = parameter_b;
	Double p = parameter_p;
	Double d = 0.0;

	Double u = getu (X);
	if (U > 1.0)
		d = sqrt ((x.x-q.x) * (x.x-q.x) + (X.Y-Q.Y) * (X.Y-Q.Y));
	else if (U < 0)
		d = sqrt ((x.x-p.x) * (x.x-p.x) + (X.Y-P.Y) * (X.Y-P.Y));
	else
		d = ABS (Getv (X));


	Double Weight =pow (pow (float) len, (float) p)/(A + D), b);
	return weight; 
}

Then the weighted sum of all the X ' points is available.

OK, the code for the above procedure is combined to traverse each constrained segment. 4, the last bilinear interpolation.

bilinear interpolation functions are as follows:

void bilinear (BitmapData *psrcimgdata,float x, float y,byte*resultpiexl) {int x_floor = (int) x;
	int y_floor = (int) y;
	int X_ceil = X_floor + 1;
	int Y_ceil = Y_floor + 1;
	float a = X-x_floor;

	float B = y-y_floor;
	if (X_ceil >= psrcimgdata->width-1) X_ceil =psrcimgdata->width-1;
	if (Y_ceil >= psrcimgdata->height-1) Y_ceil = psrcimgdata->height-1; 
	BYTE leftdown[3]; 
	BYTE lefttop[3]; 
	BYTE rightdown[3]; 
    BYTE righttop[3];
	GET2D (Psrcimgdata,y_floor,x_floor,leftdown);
	GET2D (Psrcimgdata,y_ceil,x_floor,lefttop);
	GET2D (Psrcimgdata,y_floor,x_ceil,rightdown);
	GET2D (Psrcimgdata,y_ceil,x_ceil,righttop); for (int i = 0; i < 3; i + +) {Resultpiexl[i] = (1-a) * (1-b) *leftdown[i] + A * (1-b) *rightdown[i] + a*b*righttop[i] +
	(1-a) *b*lefttop[i]; }} void Get2d (BitmapData *psrcimgdata, int y,int X, Byte*piexl) {byte*pdata= (byte*) psrcimgdata->scan0+ (psrcimgdata-
	&GT;WIDTH*Y+X);
	for (int i=0;i<3;i++) {piexl[i]=pdata[i]; }

}


Finally, post the code for the entire process:

	int nwidth=prightimgdata->width;
    int nheight=prightimgdata->height;
			for (int x = 0; x < nwidth; + +) {for (int y = 0; y < nheight; y++) {Vector2 dst_point; 
			dst_point.x= x;
			Dst_point.y= y;
			Double leftxsum_x = 0.0;
			Double leftxsum_y = 0.0;
			Double leftweightsum = 0.0;
			Double rightxsum_x = 0.0;
			Double rightxsum_y = 0.0;
			Double rightweightsum = 0.0;	
				for (int i = 0; i < pairs.size (), i++) {line src_line = Pairs[i].leftline;

				Line dst_line = Pairs[i].rightline; Double New_u = dst_line. Getu (X);//calculation (u,v) coordinates double new_v = dst_line.

				Getv (X); Vector2 src_point = Src_line. Get_point (New_u, new_v);//compute the corresponding point of the source image x ' Double src_weight = dst_line.  Get_weight (dst_point);//Calculate weight leftxsum_x = leftxsum_x + (double) src_point.x * src_weight;//weighted X ' average position leftxsum_y =
				Leftxsum_y + (Double) src_point.y * src_weight;
			Leftweightsum = Leftweightsum + src_weight; } Double left_src_x = LEFTXSUM_X/LEFTWEightsum;
			Double left_src_y = leftxsum_y/leftweightsum;
			Double right_src_x = x;


			Double right_src_y = y;
			if (left_src_x<0)//Judge whether cross-border left_src_x=0;
			if (left_src_y<0) left_src_y=0;
			if (left_src_x>=pleftimgdata->width) left_src_x=pleftimgdata->width-1;

			if (left_src_y>=pleftimgdata->height) left_src_y=pleftimgdata->height-1; Byte leftimg[3];//stores the pixel value of the last (x, y) point bilinear (PLEFTIMGDATA,LEFT_SRC_X,LEFT_SRC_Y,LEFTIMG);//linear interpolation for (int i=0;i<3;i


			+ +) {float newpiexl=leftimg[i]; }
        }
    }

This article address: http://blog.csdn.net/hjimce/article/details/45531039 Author: hjimce Contact qq:1393852684 More resources please follow my blog: Http://blog. Csdn.net/hjimce original articles, reproduced please retain our information.

Finally, take a look at this algorithm to achieve the transformation of fusion:

Original Image:


Morph Fusion Results:


Reference documents:

1,http://www.csie.ntu.edu.tw/~b97074/vfx_html/hw1.html
2, "Feature-based Image Metamorphosis"


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.