cpp
/*
* Compute
* x c -s X t1
* = * +
* y s c Y t2
*
* - every element in _m1 contains (X,Y), which are called source points
* - every element in _m2 contains (x,y), which are called destination points
* - _model is of size 2x3, which contains
* c -s t1
* s c t2
*/
class AffinePartial2DEstimatorCallback : public Affine2DEstimatorCallback
{
public:
int runKernel( InputArray _m1, InputArray _m2, OutputArray _model ) const CV_OVERRIDE
{
Mat m1 = _m1.getMat(), m2 = _m2.getMat();
const Point2f* from = m1.ptr<Point2f>();
const Point2f* to = m2.ptr<Point2f>();
_model.create(2, 3, CV_64F);
Mat M_mat = _model.getMat();
double *M = M_mat.ptr<double>();
// we need only 2 points to estimate transform
double x1 = from[0].x;
double y1 = from[0].y;
double x2 = from[1].x;
double y2 = from[1].y;
double X1 = to[0].x;
double Y1 = to[0].y;
double X2 = to[1].x;
double Y2 = to[1].y;
/*
we are solving AS = B
| x1 -y1 1 0 |
| y1 x1 0 1 |
A = | x2 -y2 1 0 |
| y2 x2 0 1 |
B = (X1, Y1, X2, Y2).t()
we solve that analytically
*/
double d = 1./((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
// solution vector
//a=S0 Scalexcos(theta)=|V|.|v|.cos(theta)/(|V|.|v|.cos(0))
double S0 = d * ( (X1-X2)*(x1-x2) + (Y1-Y2)*(y1-y2) );
//b=Scalexsin(theta)=|V|x|v|.sin(theta)/(|V|.|v|.cos(0))
double S1 = d * ( (Y1-Y2)*(x1-x2) - (X1-X2)*(y1-y2) );
//S2=tx=X1−(ax1−by1),a,b带入验证
double S2 = d * ( (Y1-Y2)*(x1*y2 - x2*y1) - (X1*y2 - X2*y1)*(y1-y2) - (X1*x2 - X2*x1)*(x1-x2) );
//S3=ty=Y1−(bx1+ay1),a,b带入验证
double S3 = d * (-(X1-X2)*(x1*y2 - x2*y1) - (Y1*x2 - Y2*x1)*(x1-x2) - (Y1*y2 - Y2*y1)*(y1-y2) );
// set model, rotation part is antisymmetric
M[0] = M[4] = S0;
M[1] = -S1;
M[2] = S2;
M[3] = S1;
M[5] = S3;
return 1;
}
};
个人感觉deepseek的答案确实更好,但代码注释中的验证理解还是靠自己的仅有的一点数学知识得以完成,特别是S2,S3,虽然AI 都给出了代入方程验证的提示