저는 OpenCV에서 두 점 집합이 주어진 affine 변환을 얻을 수 있음을 알고 있습니다. getAffineTransform()
.주어진 두 세트의 점?
그러나 getRotationMatrix2D()
은 미리 계산 된 천사 및 비율 만 지원합니다.
두 세트의 점이있는 유사성 변환 행렬을 계산하려면 어떻게해야합니까?
저는 OpenCV에서 두 점 집합이 주어진 affine 변환을 얻을 수 있음을 알고 있습니다. getAffineTransform()
.주어진 두 세트의 점?
그러나 getRotationMatrix2D()
은 미리 계산 된 천사 및 비율 만 지원합니다.
두 세트의 점이있는 유사성 변환 행렬을 계산하려면 어떻게해야합니까?
cv::estimateRigidTransform
입니다. 6 자유도 (회전, 평행 이동, 스케일링, 전단) 또는 부분 자유도 (회전, 평행 이동, 균일 한 스케일링)가있는 완전한 아핀 변환 중에서 선택할 수 있습니다.이 변환은 5 자유도입니다.
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는하지만, 대답을 다스 려하는 것은 그것을 잘 작동합니다 :
당신은 유사성이 this answer의 코드 두 vector<Point>
P1과 P2로 변환 계산할 수 있습니다.
어쨌든 cv::estimateRigidTransform
와 함께 사용하고있는 opencv 버전과 관련된 몇 가지 문제가 있습니다. 그래서 나는 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;
}
들이 6 개 및 4 DOF 변환 정밀하지 않을 때, 강성를 호출하기로 결정하는 작은 역설적 엄격한. –
답변 해 주셔서 감사합니다. 왜 4 대신 5 자유도가 있습니까? [그들의 수식] (http://docs.opencv.org/2.4/_images/math/0a22facbc11cdd0f9b8d4658e0c145da2cb8730b.png)에 따르면 단지 4 개의 매개 변수가 있습니다 – dontloo
그래, 혼란스러워. 나는 오리엔테이션을위한 이론적으로 다섯 번째 매개 변수 e가 있다는 것을 알고 있습니다. 그러나 그것을 단단한 것으로 부르며, e는 1과 같아야합니다 (oriantation preserving). – PSchn