26 #include "./PMatrixLinear.hh"
27 #include "./RMatrix.hh"
35 NewDebugLevel(
"PMATRIXLINEAR");
41 const std::vector<HomgPoint2D> &points2D,
44 std::vector<HomgPoint3D *> ptrPoints3D;
45 std::vector<HomgPoint2D *> ptrPoints2D;
46 ptrPoints3D.resize(points3D.size());
47 ptrPoints2D.resize(points2D.size());
49 for (
unsigned int i=0;i<points3D.size();i++)
50 ptrPoints3D[i]= const_cast<HomgPoint3D *>(&(points3D[i]));
51 for (
unsigned int i=0;i<points2D.size();i++)
52 ptrPoints2D[i]= const_cast<HomgPoint2D *>(&(points2D[i]));
54 return Compute(ptrPoints3D,ptrPoints2D,P);
58 const std::vector<HomgPoint2D*> &points2D,
61 if (points2D.size()<points3D.size()) {
62 BIASERR(
"Correspondence lists must have same size.");
65 if (points3D.size() < 6)
66 BIASERR(
"For P-Matrix computation at least 6 points are needed. "<<
67 "Points3D has only "<< points3D.size() <<
" points.");
75 if (!GetPEstSystemHom(A, points3D, points2D)) {
76 BIASERR(
"no eq. system!");
79 BCDOUT(PMATRIXLINEAR,
"A = " << A);
83 BCDOUT(PMATRIXLINEAR,
"A normalized rows = " << A);
103 BCDOUT(PMATRIXLINEAR,
"Singular values in P-Estimation are "<<S
117 const std::vector<HomgPoint3D*>& points3D,
118 const std::vector<HomgPoint2D*>& points2D) {
120 if (points3D.size() != points2D.size()){
122 BIASERR(
"pointlist2D has different length (=" << points2D.size()
123 <<
") than pointlist3D (=" << points3D.size() <<
")");
127 A.
newsize(points3D.size()* 2, 12);
129 for (
unsigned i = 0; i < points3D.size(); i++) {
134 unsigned row_index = i * 2;
135 A[row_index][0] = X[0] * u[2];
136 A[row_index][1] = X[1] * u[2];
137 A[row_index][2] = X[2] * u[2];
138 A[row_index][3] = X[3] * u[2];
143 A[row_index][8] = -X[0] * u[0];
144 A[row_index][9] = -X[1] * u[0];
145 A[row_index][10] = -X[2] * u[0];
146 A[row_index][11] = -X[3] * u[0];
148 row_index = i * 2 + 1;
153 A[row_index][4] = X[0] * u[2];
154 A[row_index][5] = X[1] * u[2];
155 A[row_index][6] = X[2] * u[2];
156 A[row_index][7] = X[3] * u[2];
157 A[row_index][8] = -X[0] * u[1];
158 A[row_index][9] = -X[1] * u[1];
159 A[row_index][10] = -X[2] * u[1];
160 A[row_index][11] = -X[3] * u[1];
169 const std::vector<HomgPoint3D*>& points3D,
170 const std::vector<HomgPoint2D*>& points2D) {
172 if (points3D.size() != points2D.size()){
174 BIASERR(
"pointlist2D has different length (=" << points2D.size()
175 <<
") than pointlist3D (=" << points3D.size() <<
")");
179 A.
newsize(points3D.size()*2, 11);
182 for (
unsigned i = 0; i < points3D.size(); i++) {
187 unsigned row_index = i * 2;
188 A[row_index][0] = X[0] * u[2];
189 A[row_index][1] = X[1] * u[2];
190 A[row_index][2] = X[2] * u[2];
191 A[row_index][3] = X[3] * u[2];
196 A[row_index][8] = -X[0] * u[0];
197 A[row_index][9] = -X[1] * u[0];
198 A[row_index][10] = -X[2] * u[0];
199 b[row_index] = X[3] * u[0];
201 row_index = i * 2 + 1;
206 A[row_index][4] = X[0] * u[2];
207 A[row_index][5] = X[1] * u[2];
208 A[row_index][6] = X[2] * u[2];
209 A[row_index][7] = X[3] * u[2];
210 A[row_index][8] = -X[0] * u[1];
211 A[row_index][9] = -X[1] * u[1];
212 A[row_index][10] = -X[2] * u[1];
213 b[row_index] = X[3] * u[1];
221 const vector<HomgPoint2D*> &points2D,
224 BIASASSERT(points2D.size()>5);
225 BIASASSERT(points3D.size()==points2D.size());
227 for (
unsigned int i=0;i<points3D.size(); i++) {
228 if (!points3D[i]->IsHomogenized()) {
229 BIASERR(
"Unhomogenized point !"<< *points3D[i]);
232 if (!points2D[i]->IsHomogenized()) {
233 BIASERR(
"Unhomogenized point !"<< *points2D[i]);
242 Matrix<double> ModelMatrix(points2D.size()*(points2D.size()-1)/2,9);
244 unsigned int countrow=0;
247 for (
unsigned int i=0; i<points2D.size(); i++) {
249 for (
unsigned int k=i+1; k<points2D.size(); k++) {
251 B.
Set((*points3D[k])[0]- (*points3D[i])[0],
252 (*points3D[k])[1]- (*points3D[i])[1],
253 (*points3D[k])[2]- (*points3D[i])[2]);
262 register double *pMM = ModelMatrix.
GetDataArray()[countrow++];
263 register double *pC = C.
GetData();
264 for (
register unsigned int d=0; d<9; d++) *pMM++ = *pC++;
267 SVD svd(ModelMatrix);
273 BCDOUT(PMATRIXLINEAR,
274 "Detected degenerate case in linear Rotation estimation."
276 <<
" with sing values: "<<S);
295 R.SetFromVector(RVector);
301 if (R.GetDeterminant()<0.0) R *= -1.0;
310 register unsigned int CurRowInM = 0;
311 for (
unsigned int i=0; i<points3D.size(); i++) {
314 for (
unsigned int r=0; r<3; r++) {
315 M[CurRowInM][0] = Rx_cross[r][0];
316 M[CurRowInM][1] = Rx_cross[r][1];
317 M[CurRowInM][2] = Rx_cross[r][2];
318 Vector3<double> X((*points3D[i])[0],(*points3D[i])[1],(*points3D[i])[2]);
320 M[CurRowInM++][3] = -X[r];
329 BCDOUT(PMATRIXLINEAR,
330 "Detected degenerate case in linear center estimation."
332 <<
" with sing values: "<<c);
340 CVector[2]/CVector[3]);
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this->data_
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...
bool Compute(const std::vector< HomgPoint3D * > &points3D, const std::vector< HomgPoint2D * > &points2D, PMatrix &P)
computes a least squares solution P via SVD, if at least 6 2d-3d correspondences (pointers) are provi...
Matrix< T > & newsize(Subscript M, Subscript N)
void OuterProduct(const Vector3< T > &v, Matrix3x3< T > &res) const
outer product, constructs a matrix.
Matrix< T > GetSkewSymmetricMatrix() const
constructs a skew symmetric 3x3 matrix from (*this), which can be used instead of the cross product ...
double GetZeroThreshold() const
return zerothresh currently used
const int RelNullspaceDim() const
compare singular values against greatest, not absolute
Vector< T > & newsize(Subscript N)
Represents 3d pose transformations, parametrized as Euclidean translation and unit quaternion orienta...
bool GetPEstSystemInHom(Matrix< double > &A, Vector< double > &b, const std::vector< HomgPoint3D * > &points3D, const std::vector< HomgPoint2D * > &points2D)
sets up an inhomogeneous equation system A for pmatrix computation using the 2d/3d correspondences pr...
const Matrix< double > & GetVT() const
return VT (=transposed(V))
bool ComputeCalibrated(const std::vector< HomgPoint3D * > &points3D, const std::vector< HomgPoint2D * > &points2D, PMatrix &Pose)
given n>=6 2D/3D correspondences, compute approximate R and C using linear methods (thats why we need...
Vector< T > GetRow(const int &row) const
return a copy of row "row" of this matrix, zero based counting
const Vector< double > & GetS() const
return S which is a vector of the singular values of A in descending order.
void SetFromVector(const Vector< PMATRIX_TYPE > &vals)
Sets P-Matrix from a vector which contains the elements of P row wise.
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
const T ** GetDataArray() const
returns zero based arry for data access
const Matrix< double > & GetU() const
return U U is a m x m orthogonal matrix
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
describes a projective 3D -> 2D mapping in homogenous coordinates
void NormalizeRows()
Normalizes each row to L2 norm one.
bool GetPEstSystemHom(Matrix< double > &A, const std::vector< HomgPoint3D * > &points3D, const std::vector< HomgPoint2D * > &points2D)
sets up the homogeneous equation system A for pmatrix computation using the 2d/3d correspondences pro...
void Compose(const Matrix3x3< double > &K, const Matrix3x3< double > &R, const Vector3< double > &C)
composes this from K, R and C using P = [ K R' | -K R' C ] with R' = transpose(R) ...
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...