2016-09-26 5 views

答えて

2

cv::estimateRigidTransformがあります。 6自由度(回転、平行移動、スケーリング、せん断)または部分自由度(回転、平行移動、均一なスケーリング)を持つアフィン変換を5自由度から選択できます。あなたは類似性がthis answerからのコードで2つのvector<Point> P1およびP2で変換を計算することができます

cv::Mat R = cv::estimateRigidTransform(p1,p2,false); 

// extend rigid transformation to use perspectiveTransform: 
cv::Mat H = cv::Mat(3,3,R.type()); 
H.at<double>(0,0) = R.at<double>(0,0); 
H.at<double>(0,1) = R.at<double>(0,1); 
H.at<double>(0,2) = R.at<double>(0,2); 

H.at<double>(1,0) = R.at<double>(1,0); 
H.at<double>(1,1) = R.at<double>(1,1); 
H.at<double>(1,2) = R.at<double>(1,2); 

H.at<double>(2,0) = 0.0; 
H.at<double>(2,1) = 0.0; 
H.at<double>(2,2) = 1.0; 

// compute perspectiveTransform on p1 
std::vector<cv::Point2f> result; 
cv::perspectiveTransform(p1,result,H) 

//warp image with transform 
cv::Mat warped; 
cv::warpPerspective(src,warped,H,src.size()); 

私はそれを試して、それが正常に動作する必要があります答えを参照のうえdidntの。

+1

彼らは6および4 DOF変換が正確でない場合に、剛性を呼び出すことを選択したことを少し逆説硬い。 –

+0

答えてくれてありがとう、どうして4の代わりに5度の自由度があるのですか? [それらの式](http://docs.opencv.org/2.4/_images/math/0a22facbc11cdd0f9b8d4658e0c145da2cb8730b.png)によると、わずか4つのパラメータがあります – dontloo

+0

ええ、私は混乱しています。私は、理論的にオリエンテーションのための5番目のパラメータeがあることを知っています。しかし、それは硬質と呼ばれるので、eは等しくなければならない1(oriantation preserving)。 – PSchn

1

どういうわけか私が使っているopencvバージョンのcv::estimateRigidTransformで問題が起きているので、2点でしか動作しない関数を書いています(これで十分です。

cv::Mat getSimilarityTransform(const cv::Point2f src[], const cv::Point2f dst[]) 
{ 
    double src_d_y = src[0].y - src[1].y; 
    double src_d_x = src[0].x - src[1].x; 
    double src_dis = sqrt(pow(src_d_y, 2) + pow(src_d_x, 2)); 

    double dst_d_y = dst[0].y - dst[1].y; 
    double dst_d_x = dst[0].x - dst[1].x; 
    double dst_dis = sqrt(pow(dst_d_y, 2) + pow(dst_d_x, 2)); 

    double scale = dst_dis/src_dis; 
    // angle between two line segments 
    // ref: http://stackoverflow.com/questions/3365171/calculating-the-angle-between-two-lines-without-having-to-calculate-the-slope 
    double angle = atan2(src_d_y, src_d_x) - atan2(dst_d_y, dst_d_x); 

    double alpha = cos(angle)*scale; 
    double beta = sin(angle)*scale; 

    cv::Mat M(2, 3, CV_64F); 
    double* m = M.ptr<double>(); 

    m[0] = alpha; 
    m[1] = beta; 
    // tx = x' -alpha*x -beta*y 
    // average of two points 
    m[2] = (dst[0].x - alpha*src[0].x - beta*src[0].y + dst[1].x - alpha*src[1].x - beta*src[1].y)/2; 
    m[3] = -beta; 
    m[4] = alpha; 
    // ty = y' +beta*x -alpha*y 
    // average of two points 
    m[5] = (dst[0].y + beta*src[0].x - alpha*src[0].y + dst[1].y + beta*src[1].x - alpha*src[1].y)/2; 

    return M; 
} 

結果の一部(LFWデータセットからの画像)
enter image description here enter image description here enter image description here enter image description here

関連する問題