25 #include <Base/Common/BIASpragmaStart.hh>
26 #include <Image/TextureTransformHomography.hh>
32 if (fabs(sink[0])<1e-10)
return -1;
40 if (fabs(src[0])<1e-10)
return -1;
50 double* pH = H_.GetData();
51 const double c11 = *pH++;
52 const double c12 = *pH++;
53 const double c13 = *pH++;
54 const double c21 = *pH++;
55 const double c22 = *pH++;
56 const double c23 = *pH++;
57 const double c31 = *pH++;
58 const double c32 = *pH;
62 const double minusc1src = -1.0*(c11*src[0]+c12*src[1]+c13);
63 const double minusc2src = -1.0*(c21*src[0]+c22*src[1]+c23);
64 const double oneoverc3src = 1.0/(c31*src[0]+c32*src[1]+1.0);
65 const double oneoverc3src2 = oneoverc3src*oneoverc3src;
69 *pData++ = src[0] * oneoverc3src * AFFINE_SENSITIVITY;
70 *pData++ = src[1] * oneoverc3src * AFFINE_SENSITIVITY;
71 *pData++ = oneoverc3src;
75 *pData++ = minusc1src * oneoverc3src2 * src[0]* PROJECTIVE_SENSITIVITY;
76 *pData++ = minusc1src * oneoverc3src2 * src[1]* PROJECTIVE_SENSITIVITY;
81 *pData++ = src[0] * oneoverc3src * AFFINE_SENSITIVITY;
82 *pData++ = src[1] * oneoverc3src * AFFINE_SENSITIVITY;
83 *pData++ = oneoverc3src;
84 *pData++ = minusc2src * oneoverc3src2 * src[0]* PROJECTIVE_SENSITIVITY;
85 *pData++ = minusc2src * oneoverc3src2 * src[1]* PROJECTIVE_SENSITIVITY;
95 double* pH = H_.GetData();
96 const double c11 = *pH++ -1.0;
97 const double c12 = *pH++;
98 const double c13 = *pH++;
99 const double c21 = *pH++;
100 const double c22 = *pH++ - 1.0;
101 const double c23 = *pH++;
102 const double c31 = *pH++;
103 const double c32 = *pH;
106 const double x = sink[0];
107 const double xx = x*x;
108 const double y = sink[1];
109 const double yy = y*y;
110 const double longterm = (x*c21*c32-x*c31*c22-x*c31-y*c32*c11-y*c32+y*c12*c31+c11*c22+c11+c22+1-c21*c12);
111 const double longtermlongterm =longterm*longterm;
112 const double anothertermx = x*c22+x-x*c23*c32-y*c12+y*c13*c32+c12*c23-c13*c22-c13;
113 const double anothertermy = x*c21-x*c23*c31-y*c11-y+y*c31*c13+c23*c11+c23-c13*c21;
118 *pData++ = -(-y*c32+c22+1)*(anothertermx)/longtermlongterm* AFFINE_SENSITIVITY; ;
119 *pData++ = (-y*c11*c22+c23*c11*c22+yy*c11*c32-c23*c11*y*c32-y*c11+c23*c11+x*c22*c21-x*c23*c31*c22-y*c22+y*c31*c13*c22+c23*c22-c13*c21*c22+y*c31*c13+x*c23*c31*y*c32+yy*c32-x*c23*c31+c13*c21*y*c32-yy*c31*c13*c32-x*c21*y*c32-c13*c21+c23-y-c23*y*c32+x*c21)/longtermlongterm* AFFINE_SENSITIVITY; ;
120 *pData++ = -(-y*c32+c22+1)/(longterm);
121 *pData++ = (-x*c32+c12)*(anothertermx)/longtermlongterm* AFFINE_SENSITIVITY; ;
122 *pData++ = -(c12*c23*c11-c23*c11*x*c32+x*y*c32*c11-y*c12*c11-y*c12+x*y*c32+c13*x*c21*c32+c13*y*c12*c31+c12*c23+x*c21*c12-x*c12*c23*c31-y*c31*c13*x*c32-xx*c21*c32+xx*c23*c31*c32-c13*c21*c12-x*c23*c32)/longtermlongterm* AFFINE_SENSITIVITY; ;
123 *pData++ = (-x*c32+c12)/(longterm);
125 *pData++ = -(y*c12-x*c22-x)*(anothertermx)/longtermlongterm * PROJECTIVE_SENSITIVITY;
126 *pData++ = (y*c12*x*c21-xx*c22*c21-xx*c21-x*c23*y*c12*c31+xx*c23*c31*c22+xx*c23*c31-yy*c11*c12+x*c22*y*c11+x*y*c11-yy*c12+x*c22*y+x*y+yy*c13*c12*c31-y*c31*c13*x*c22-y*c31*c13*x+c23*c11*y*c12-c23*c11*x*c22-c23*c11*x+c23*y*c12-c23*x*c22-x*c23-y*c13*c21*c12+c13*c22*x*c21+c13*x*c21)/longtermlongterm * PROJECTIVE_SENSITIVITY;
131 *pData++ = (y*c31*c13*c22+x*c22*c21-c13*c21*c22-y*x*c31*c22-y*c21*c12+c23*c21*c12+y*c31*c13+c13*c21*y*c32-yy*c31*c13*c32-c13*c21+yy*c12*c31+x*c23*c31*y*c32-y*x*c31-c23*x*c21*c32-c23*y*c12*c31+x*c21)/longtermlongterm* AFFINE_SENSITIVITY; ;
133 *pData++ = -(c21-y*c31)*(anothertermy)/longtermlongterm* AFFINE_SENSITIVITY;
134 *pData++ = (c21-y*c31)/longterm;
137 *pData++ = -(x*c11*c22+x*c11-c23*c11*x*c32-y*c12*c11+c13*c11*y*c32+c12*c23*c11-c13*c11*c22-c13*c11+x*c22-xx*c22*c31-c13*c22+c13*c22*x*c31+x*y*c12*c31-y*c12-x*c12*c23*c31-xx*c31+x+c12*c23-y*c31*c13*x*c32+c13*x*c31-x*c23*c32+y*c13*c32+xx*c23*c31*c32-c13)/longtermlongterm* AFFINE_SENSITIVITY; ;
138 *pData++ = (c11+1-x*c31)*(anothertermy)/longtermlongterm* AFFINE_SENSITIVITY;
140 *pData++ = -(c11+1-x*c31)/longterm;
141 *pData++ = (x*y*c11+c13*x*c21-xx*c21-yy*c12+c13*c22*x*c21-xx*c22*c21+x*c22*y-c12*c23*x*c21+x*c22*y*c11+y*c12*x*c21-y*c13*x*c21*c32-x*c23*y*c32*c11+yy*c13*c32*c11-y*c13*c11*c22+xx*c23*c21*c32-x*c23*y*c32+c23*c11*y*c12-y*c13+yy*c13*c32+c23*y*c12-yy*c11*c12-y*c13*c22-y*c13*c11+x*y)/longtermlongterm * PROJECTIVE_SENSITIVITY;
142 *pData++ = -(-x*c21+y*c11+y)*(anothertermy)/longtermlongterm * PROJECTIVE_SENSITIVITY;
150 H_ = ConstructHFromParameters(p);
151 H_.GetInverse(Hinv_);
152 Hinv_ /= Hinv_[2][2];
157 HMatrix H = ConstructHFromParameters(deltaP);
169 const double c11 = P_[0] * AFFINE_SENSITIVITY;
170 const double c12 = P_[1] * AFFINE_SENSITIVITY;
171 const double c13 = P_[2];
172 const double c21 = P_[3] * AFFINE_SENSITIVITY;
173 const double c22 = P_[4] * AFFINE_SENSITIVITY;
174 const double c23 = P_[5];
175 const double c31 = P_[6] * PROJECTIVE_SENSITIVITY;
176 const double c32 = P_[7] * PROJECTIVE_SENSITIVITY;
179 const double det = c11*c22+c11+c22+1-c21*c12;
180 const double detdet = det*det;
186 *pD++ = -(c22+1-c23*c32)/detdet*(c22+1);
187 *pD++ = (c22+1-c23*c32)/detdet*c21;
189 *pD++ = (c22+1-c23*c32)/detdet*c12;
190 *pD++ = (-c21*c12+c11*c23*c32+c23*c32)/detdet;
195 *pD++ = (c12-c13*c32)/detdet*(c22+1);
196 *pD++ = -(c11*c22+c11+c22+1-c21*c13*c32)/detdet;
198 *pD++ = -(c12-c13*c32)/detdet*c12;
199 *pD++ = (c12-c13*c32)/detdet*(c11+1);
204 *pD++ = -(c12*c23-c13*c22-c13)/detdet*(c22+1);
205 *pD++ = (c23*c11*c22+c23*c11+c23*c22+c23-c13*c21*c22-c13*c21)/detdet;
206 *pD++ = -(c22+1)/(det);
207 *pD++ = (c12*c23-c13*c22-c13)/detdet*c12;
208 *pD++ = -(c23*c11+c23-c13*c21)/detdet*c12;
213 *pD++ = (c21-c23*c31)/detdet*(c22+1);
214 *pD++ = -(c21-c23*c31)/detdet*c21;
216 *pD++ = -(c11*c22+c11+c22+1-c31*c12*c23)/detdet;
217 *pD++ = (c21-c23*c31)/detdet*(c11+1);
222 *pD++ = -(c21*c12-c31*c13*c22-c31*c13)/detdet;
223 *pD++ = (c11+1-c31*c13)/detdet*c21;
225 *pD++ = (c11+1-c31*c13)/detdet*c12;
226 *pD++ = -(c11+1-c31*c13)/detdet*(c11+1);
231 *pD++ = (c12*c23-c13*c22-c13)/detdet*c21;
232 *pD++ = -(c23*c11+c23-c13*c21)/detdet*c21;
234 *pD++ = -(-c13*c11*c22-c13*c11-c13*c22-c13+c12*c23*c11+c12*c23)/detdet;
235 *pD++ = (c23*c11+c23-c13*c21)/detdet*(c11+1);
236 *pD++ = -(c11+1)/(det);
240 *pD++ = -(c21*c32-c31*c22-c31)/detdet*(c22+1);
241 *pD++ = (c21*c32-c31*c22-c31)/detdet*c21;
243 *pD++ = (c32*c11*c22+c32*c11+c32*c22+c32-c12*c31*c22-c12*c31)/detdet;
244 *pD++ = -(c32*c11+c32-c12*c31)/detdet*c21;
246 *pD++ = -(c22+1)/(det);
249 *pD++ = (c21*c32-c31*c22-c31)/detdet*c12;
250 *pD++ = -(-c31*c11*c22-c31*c11-c31*c22-c31+c21*c32*c11+c21*c32)/detdet;
252 *pD++ = -(c32*c11+c32-c12*c31)/detdet*c12;
253 *pD++ = (c32*c11+c32-c12*c31)/detdet*(c11+1);
256 *pD++ = -(c11+1)/(det);
261 for (
unsigned int i=0; i<8; i++) {
267 case 4: factor = AFFINE_SENSITIVITY;
break;
269 case 7: factor = PROJECTIVE_SENSITIVITY;
break;
271 for (
unsigned int j=0; j<8; j++) {
276 case 4: Jac[j][i] *= factor / AFFINE_SENSITIVITY;
break;
278 case 7: Jac[j][i] *= factor / PROJECTIVE_SENSITIVITY;
break;
291 const double norminv = 1.0/H[2][2];
292 for (
unsigned int i=0; i<8; i++) p[i] = H[i/3][i%3]*norminv;
298 p[0] /= AFFINE_SENSITIVITY;
299 p[1] /= AFFINE_SENSITIVITY;
300 p[3] /= AFFINE_SENSITIVITY;
301 p[4] /= AFFINE_SENSITIVITY;
303 p[6] /= PROJECTIVE_SENSITIVITY;
304 p[7] /= PROJECTIVE_SENSITIVITY;
315 H[0][0] = p[0] * AFFINE_SENSITIVITY + 1.0;
316 H[0][1] = p[1] * AFFINE_SENSITIVITY;
318 H[1][0] = p[3] * AFFINE_SENSITIVITY;
319 H[1][1] = p[4] * AFFINE_SENSITIVITY + 1.0;
321 H[2][0] = p[6] * PROJECTIVE_SENSITIVITY;
322 H[2][1] = p[7] * PROJECTIVE_SENSITIVITY;
int MapBackward(const HomgPoint2D &sink, HomgPoint2D &src) const
map a point in image "source" to a point in image "sink"
int ParameterInversionJacobian(Matrix< double > &Jac) const
compute parameters for inverse operation and obtain the jacobian of the inverse parameters with respe...
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
a 3x3 Matrix describing projective transformations between planes
int MapForward(const HomgPoint2D &src, HomgPoint2D &sink) const
map a point in image "source" to a point in image "sink"
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
Matrix< T > & newsize(Subscript M, Subscript N)
void SetParameters(const Vector< double > &p)
h11-1, h12, h13, h21, h22-1, h23, h31, h32 (h33==1 assumed)
int GetInverse(Matrix3x3< T > &inv) const
Matrix inversion: inverts this and stores resulty in argument inv.
BIAS::HMatrix ConstructHFromParameters(const Vector< double > &p) const
given parameters, compute H
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
Vector< double > ExtractParameters(const BIAS::HMatrix &H) const
given H, compute a parameter vector
void ComposeWithInverseDeltaP(const Vector< double > &deltaP)
concatenate *this and an inverse transform with param deltaP and save new parameter vector to *this...
int ParameterJacobianBackward(Matrix< double > &Jac, const HomgPoint2D &src)
transformed position change when parameters change
int ParameterJacobianForward(Matrix< double > &Jac, const HomgPoint2D &src)
transformed position change when parameters change