25 #include <Base/Common/BIASpragmaStart.hh>
26 #include <Image/TextureTransformAffine.hh>
27 #include <MathAlgo/SVD.hh>
42 const double a11 = P_[0];
43 const double a12 = P_[1];
44 const double a21 = P_[2];
45 const double a22 = P_[3];
46 const double tx = P_[4];
47 const double ty = P_[5];
50 const double det = a11*a22+a11+a22+1.0-a12*a21;
51 if (fabs(det)<MIN_DET) {
55 const double detdet = det * det;
57 *pD++ = -(a22+1.0)*(a22+1.0)/detdet;
58 *pD++ = (a22+1.0)/detdet*a21;
59 *pD++ = (a22+1.0)/detdet*a12;
60 *pD++ = -a12/detdet*a21;
64 *pD++ = (a22+1.0)/detdet*a12;
65 *pD++ = -(a11*a22+a11+a22+1.0)/detdet;
66 *pD++ = -a12*a12/detdet;
67 *pD++ = a12/detdet*(a11+1.0);
71 *pD++ = (a22+1.0)/detdet*a21;
72 *pD++ = -a21*a21/detdet;
73 *pD++ = -(a11*a22+a11+a22+1.0)/detdet;
74 *pD++ = a21/detdet*(a11+1.0);
78 *pD++ = -a12/detdet*a21;
79 *pD++ = a21/detdet*(a11+1.0);
80 *pD++ = a12/detdet*(a11+1.0);
81 *pD++ = -(a11+1.0)*(a11+1.0)/detdet;
85 *pD++ = (a22+1.0)*(tx*a22+tx-a12*ty)/detdet;
86 *pD++ = -(tx*a21*a22+tx*a21-ty*a11*a22-ty*a11-ty*a22-ty)/detdet;
87 *pD++ = -a12*(tx*a22+tx-a12*ty)/detdet;
88 *pD++ = a12*(tx*a21-ty*a11-ty)/detdet;
89 *pD++ = -(a22+1.0)/det;
92 *pD++ = -a21*(tx*a22+tx-a12*ty)/detdet;
93 *pD++ = a21*(tx*a21-ty*a11-ty)/detdet;
94 *pD++ = (tx*a11*a22+tx*a11+tx*a22+tx-a12*ty*a11-a12*ty)/detdet;
95 *pD++ = -(a11+1.0)*(tx*a21-ty*a11-ty)/detdet;
97 *pD++ = -(a11+1.0)/det;
108 sink[0] = src[0]*A_[0][0] + src[1]*A_[0][1] + tx_;
109 sink[1] = src[0]*A_[1][0] + src[1]*A_[1][1] + ty_;
117 src[0] = sink[0]*Ainv_[0][0] + sink[1]*Ainv_[0][1] + txinv_;
118 src[1] = sink[0]*Ainv_[1][0] + sink[1]*Ainv_[1][1] + tyinv_;
130 Jac[0][0] = src[0]-origin_[0];
131 Jac[0][1] = src[1]-origin_[1];
133 Jac[1][2] = src[0]-origin_[0];
134 Jac[1][3] = src[1]-origin_[1];
144 const double c11 = P_[0];
145 const double c12 = P_[1];
146 const double c21 = P_[2];
147 const double c22 = P_[3];
148 const double c13 = P_[4];
149 const double c23 = P_[5];
150 const double det = c11*c22+c11+c22+1-c21*c12;
151 if (fabs(det)<MIN_DET) {
155 const double detdet = det*det;
156 const double x = sink[0]-origin_[0]-P_[4];
157 const double y = sink[1]-origin_[1]-P_[5];
159 Jac[0][0] = -(c22+1)*(x*c22+x-c12*y+c12*c23-c13*c22-c13)/detdet;
160 Jac[0][1] = (x*c21*c22 + x*c21 - y*c11*c22 - y*c11 - y*c22 - y +
161 c23*c11*c22 + c23*c11 + c23*c22 + c23 - c13*c21*c22 -
164 Jac[0][2] = c12*(x*c22+x-c12*y+c12*c23-c13*c22-c13)/detdet;
165 Jac[0][3] = -c12*(x*c21-y*c11-y+c23*c11+c23-c13*c21)/detdet;
166 Jac[0][4] = -(c22+1)/det;
169 Jac[1][0] = c21*(x*c22+x-c12*y+c12*c23-c13*c22-c13)/detdet;
170 Jac[1][1] = -c21*(x*c21-y*c11-y+c23*c11+c23-c13*c21)/detdet;
171 Jac[1][2] = -(x*c11*c22 + x*c11 + x*c22 + x -c12*y*c11 -c12*y -
172 c13*c11*c22 - c13*c11 - c13*c22 - c13 + c12*c23*c11
174 Jac[1][3] = (c11+1)*(x*c21-y*c11-y+c23*c11+c23-c13*c21)/detdet;
176 Jac[1][5] = -(c11+1)/det;
183 BIASASSERT(p.
Size()==6);
185 for (
unsigned int i=0; i<6; i++) {
190 InterpretParameters(p, A_[0][0], A_[0][1], A_[1][0], A_[1][1], tx_, ty_);
192 if (A_.Invert( Ainv_)!=0) {
193 BIASERR(
"Error inverting A_="<<A_<<
" with det "<<A_.det());
196 txinv_ = -(Ainv_[0][0]*tx_ + Ainv_[0][1]*ty_);
197 tyinv_ = -(Ainv_[1][0]*tx_ + Ainv_[1][1]*ty_);
204 for (
unsigned int i=0; i<6; i++) {
205 INFNANCHECK(deltaP[i]);
210 InterpretParameters(deltaP, A1[0][0], A1[0][1], A1[1][0], A1[1][1],
212 if (A1.GetInverse(A2inv)!=0) {
213 BIASERR(
"Error inverting warp "<<A1);
230 p[0] = A1[0][0] - 1.0;
233 p[3] = A1[1][1] - 1.0;
234 p[4] = A1[0][2] + (A1[0][0]-1.0)*origin_[0] + A1[0][1]*origin_[1];
235 p[5] = A1[1][2] + A1[1][0]*origin_[0] + (A1[1][1]-1.0)*origin_[1];
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
int ParameterJacobianForward(Matrix< double > &Jac, const HomgPoint2D &src)
transformed position change when parameters change
int ParameterJacobianBackward(Matrix< double > &Jac, const HomgPoint2D &sink)
transformed position change when parameters change
Matrix< T > & newsize(Subscript M, Subscript N)
int MapBackward(const HomgPoint2D &sink, HomgPoint2D &src) const
map a point in image "source" to a point in image "sink"
unsigned int Size() const
length of the vector
int MapForward(const HomgPoint2D &src, HomgPoint2D &sink) const
map a point in image "source" to a point in image "sink"
void SetZero()
Sets all values to zero.
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
void ComposeWithInverseDeltaP(const Vector< double > &deltaP)
concatenate *this and an inverse transform with param deltaP and save new parameter vector to *this...
Matrix< double > Invert()
returns pseudoinverse of A = U * S * V^T A^+ = V * S^+ * U^T
int ParameterInversionJacobian(Matrix< double > &Jac) const
compute parameters for inverse operation and obtain the jacobian of the inverse parameters with respe...
void SetParameters(const Vector< double > &p)
a11-1, a12, a21, a22-1, dx, dy