Open chenliangren opened 9 years ago
thanks! the post link is not chinese, the same as "here",is it wrong? I'm still confused why the regress_target should be transfromed accroding to the mean shape.The paper only point out the index-shape feature should transfrom like this. 2.besides, I'm confused why the threshold should be seleced randomly. and in the code: "(-0.2_max_diff,0.2_max_diff)" what's the purpose of scaling the range by 0.2 factor ? i am wondering sorting the difference between two feature point and select the difference which best fit the data as threshold, does it work?
@soundsilence Hi, I'm confused about the code of SimilarityTransform function. I have read your post and also the appendix of the materials your referred. But I don't understand your method calculating the "scale" in the code.
In the post, we need firstly get a and b, and then using s^2 = a^2 + b^2 to the final result. But you just calculated the covariance matrix and used the ratio of their L2-norm as the scale. Could you explain the underlying principle?
@windpls It's indeed quite confusing. The code snippet is inconsistent with Appendix B of the book
I have no idea what's going on with this function's code, but the output really doesn't make sense. I've tried implementing it as explained in Appendix B and it was simple and yielded a logical output that had lesser MSE than that produced by the current implementation. I suggest re-implementing this function.
Sorry that the code is very old and I am not even sure whether this is the version I use. Feel free to paste the correct code here and I would be happy to correct it. Thanks.
Here is my code, let me know if there's any adjustments to be made.
void SimilarityTransform(const Mat
// center the data
double center_x_1 = 0;
double center_y_1 = 0;
double center_x_2 = 0;
double center_y_2 = 0;
for (int i = 0; i < shape1.rows; i++) {
center_x_1 += shape1(i, 0);
center_y_1 += shape1(i, 1);
center_x_2 += shape2(i, 0);
center_y_2 += shape2(i, 1);
}
center_x_1 /= shape1.rows;
center_y_1 /= shape1.rows;
center_x_2 /= shape2.rows;
center_y_2 /= shape2.rows;
Mat_<double> temp1 = shape1.clone();
Mat_<double> temp2 = shape2.clone();
for (int i = 0; i < shape1.rows; i++) {
temp1(i, 0) -= center_x_1;
temp1(i, 1) -= center_y_1;
temp2(i, 0) -= center_x_2;
temp2(i, 1) -= center_y_2;
}
double num_a = 0;
double num_b = 0;
double den = 0;
for (int i = 0; i < shape1.rows; i++) {
num_a = num_a + temp1(i, 0) * temp2(i, 0) + temp1(i, 1) * temp2(i, 1);
num_b = num_b + temp1(i, 0) * temp2(i, 1) - temp1(i, 1) * temp2(i, 0);
den = den + temp1(i, 0) * temp1(i, 0) + temp1(i, 1) * temp1(i, 1);
}
double a = num_a / den;
double b = num_b / den;
double theta = atan(b / a);
double scale = sqrt(pow(a, 2) + pow(b, 2));
double cos_theta = cos(theta);
double sin_theta = sin(theta);
rotation(0,0) = cos_theta;
rotation(0,1) = -sin_theta;
rotation(1,0) = sin_theta;
rotation(1,1) = cos_theta;
}
Here is my code, let me know if there's any adjustments to be made.
void SimilarityTransform(const Mat& shape1, const Mat& shape2, Mat_& rotation,double& scale){ rotation = Mat::zeros(2,2,CV_64FC1); scale = 0;
// center the data double center_x_1 = 0; double center_y_1 = 0; double center_x_2 = 0; double center_y_2 = 0; for (int i = 0; i < shape1.rows; i++) { center_x_1 += shape1(i, 0); center_y_1 += shape1(i, 1); center_x_2 += shape2(i, 0); center_y_2 += shape2(i, 1); } center_x_1 /= shape1.rows; center_y_1 /= shape1.rows; center_x_2 /= shape2.rows; center_y_2 /= shape2.rows; Mat_<double> temp1 = shape1.clone(); Mat_<double> temp2 = shape2.clone(); for (int i = 0; i < shape1.rows; i++) { temp1(i, 0) -= center_x_1; temp1(i, 1) -= center_y_1; temp2(i, 0) -= center_x_2; temp2(i, 1) -= center_y_2; } double num_a = 0; double num_b = 0; double den = 0; for (int i = 0; i < shape1.rows; i++) { num_a = num_a + temp1(i, 0) * temp2(i, 0) + temp1(i, 1) * temp2(i, 1); num_b = num_b + temp1(i, 0) * temp2(i, 1) - temp1(i, 1) * temp2(i, 0); den = den + temp1(i, 0) * temp1(i, 0) + temp1(i, 1) * temp1(i, 1); } double a = num_a / den; double b = num_b / den; double theta = atan(b / a); double scale = sqrt(pow(a, 2) + pow(b, 2)); double cos_theta = cos(theta); double sin_theta = sin(theta); rotation(0,0) = cos_theta; rotation(0,1) = -sin_theta; rotation(1,0) = sin_theta; rotation(1,1) = cos_theta;
}
There's an error due to redefinition of scale, so remove the double before scale near the end.