@@ -42,7 +42,7 @@ void vpRBBundleAdjustment::asParamVector(vpColVector ¶ms) const
42
42
{
43
43
44
44
unsigned int numUsedPoints = m_mapView.numPoints ();
45
- params.resize (m_cameras. size () * 6 + numUsedPoints * 3 , false );
45
+ params.resize (numParameters () , false );
46
46
unsigned int i = 0 ;
47
47
// First parameters are the camera poses
48
48
for (const CameraData &camera: m_cameras) {
@@ -75,7 +75,7 @@ void vpRBBundleAdjustment::updateFromParamVector(const vpColVector ¶ms)
75
75
{
76
76
77
77
#ifdef DEBUG_RB_BA
78
- if (params.size () != m_cameras. size () * 6 + m_mapView. numPoints () * 3 ) {
78
+ if (params.size () != numParameters () ) {
79
79
throw vpException (vpException::dimensionError, " Mismatch between param vector size and number of points/cameras" );
80
80
}
81
81
#endif
@@ -128,14 +128,15 @@ void vpRBBundleAdjustment::computeError(const vpColVector ¶ms, vpColVector &
128
128
}
129
129
}
130
130
131
- void vpRBBundleAdjustment::jacobianSparsity (vpArray2D< int > &S )
131
+ void vpRBBundleAdjustment::jacobianSparsityPattern (std::vector< unsigned int > &rowIndices, std::vector< unsigned int > &columnIndices )
132
132
{
133
- unsigned int numParams = numCameras () * 6 + numPoints3d () * 3 ;
134
- S.resize (numResiduals (), numParams);
133
+ rowIndices.reserve (numResiduals () * 9 );
134
+ columnIndices.reserve (numResiduals () * 9 );
135
+
135
136
unsigned int i = 0 ;
136
137
unsigned int cameraIndex = 0 ;
137
138
for (const CameraData &camera: m_cameras) {
138
- camera.fillJacobianSparsity (m_mapView, S , cameraIndex, m_cameras.size (), i);
139
+ camera.jacobianSparsityPattern (m_mapView, rowIndices, columnIndices , cameraIndex, m_cameras.size (), i);
139
140
i += camera.numResiduals ();
140
141
++cameraIndex;
141
142
}
@@ -144,7 +145,7 @@ void vpRBBundleAdjustment::jacobianSparsity(vpArray2D<int> &S)
144
145
// //////// Camera data
145
146
vpRBBundleAdjustment::CameraData::CameraData (const vpCameraParameters &cam, const vpHomogeneousMatrix &cTw, const std::vector<unsigned int > &indices3d, const vpMatrix &uvs)
146
147
{
147
- m_cTw = cTw;
148
+ m_r = cTw;
148
149
m_indices3d = indices3d;
149
150
150
151
#ifdef DEBUG_RB_BA
@@ -179,8 +180,8 @@ void vpRBBundleAdjustment::CameraData::error(MapIndexView &mapView, const vpColV
179
180
vpColVector wX (3 );
180
181
vpColVector cX (3 );
181
182
for (unsigned int i = startResidual; i < startResidual + numResiduals (); i += 2 ) {
182
- const unsigned int pi = mapView.getViewIndex (m_indices3d[pointIndex]);
183
- const double *pp = pointsParams + 3 * pi ;
183
+ const unsigned int vpi = mapView.getViewIndex (m_indices3d[pointIndex]);
184
+ const double *pp = pointsParams + 3 * vpi ;
184
185
wX[0 ] = pp[0 ];
185
186
wX[1 ] = pp[1 ];
186
187
wX[2 ] = pp[2 ];
@@ -209,9 +210,8 @@ void vpRBBundleAdjustment::CameraData::jacobian(const MapIndexView &mapView, con
209
210
vpColVector wX (3 );
210
211
vpColVector cX (3 );
211
212
212
-
213
- vpMatrix dpDXp (2 , 3 , 0.0 );
214
- vpMatrix dpDX (2 , 3 );
213
+ vpMatrix dxydcX (2 , 3 , 0.0 );
214
+ vpMatrix dxydwX (2 , 3 , 0.0 );
215
215
unsigned int pointIndex = 0 ;
216
216
217
217
for (unsigned int i = startResidual; i < startResidual + numResiduals (); i += 2 ) {
@@ -225,50 +225,60 @@ void vpRBBundleAdjustment::CameraData::jacobian(const MapIndexView &mapView, con
225
225
cX = cRw * wX;
226
226
cX += t;
227
227
228
- double x = cX[0 ] / cX[2 ];
229
- double y = cX[1 ] / cX[2 ];
230
-
231
- double Zinv = 1.0 / cX[2 ];
228
+ const double x = cX[0 ] / cX[2 ];
229
+ const double y = cX[1 ] / cX[2 ];
230
+ const double Zinv = 1.0 / cX[2 ];
232
231
233
232
double *Jx = J[i];
234
233
double *Jy = J[i + 1 ];
235
234
236
- // Camera jacobian for x
237
- Jx[ci + 0 ] = -Zinv; Jx[ci + 1 ] = 0.0 ; Jx[ci + 2 ] = x * Zinv;
238
- Jx[ci + 3 ] = x * y; Jx[ci + 4 ] = -(1.0 + x * x); Jx[ci + 5 ] = y;
235
+ // Jacobian of the 2D projection of a 3D point (already in camera frame)
236
+ dxydcX[0 ][0 ] = Zinv; dxydcX[0 ][2 ] = -(x * Zinv);
237
+ dxydcX[1 ][1 ] = Zinv; dxydcX[1 ][2 ] = -(y * Zinv);
238
+
239
+ // Camera Jacobian for x
240
+ Jx[ci + 0 ] = dxydcX[0 ][0 ]; Jx[ci + 1 ] = dxydcX[0 ][1 ]; Jx[ci + 2 ] = dxydcX[0 ][2 ];
241
+
242
+ Jx[ci + 3 ] = -(x * y); Jx[ci + 4 ] = (1.0 + x * x); Jx[ci + 5 ] = -y;
239
243
// Camera Jacobian for y
240
- Jy[ci + 0 ] = 0.0 ; Jy[ci + 1 ] = -Zinv; Jy[ci + 2 ] = y * Zinv;
241
- Jy[ci + 3 ] = 1.0 + y * y; Jy[ci + 4 ] = -(x * y); Jy[ci + 5 ] = -x;
244
+ Jy[ci + 0 ] = dxydcX[1 ][0 ]; Jy[ci + 1 ] = dxydcX[1 ][1 ]; Jy[ci + 2 ] = dxydcX[1 ][2 ];
242
245
243
- unsigned int pi = numCameras * 6 + vpi * 3 ;
246
+ Jy[ci + 3 ] = -( 1.0 + y * y); Jy[ci + 4 ] = (x * y); Jy[ci + 5 ] = x ;
244
247
245
- dpDXp[ 0 ][ 0 ] = -Zinv; dpDXp[ 0 ][ 2 ] = x * Zinv;
246
- dpDXp[ 1 ][ 1 ] = -Zinv; dpDXp[ 1 ][ 2 ] = y * Zinv ;
247
- dpDX = dpDXp * cRw;
248
- Jx[pi + 0 ] = dpDX [0 ][0 ]; Jx[pi + 1 ] = dpDX [0 ][1 ]; Jx[pi + 2 ] = dpDX [0 ][2 ];
249
- Jy[pi + 0 ] = dpDX [1 ][0 ]; Jy[pi + 1 ] = dpDX [1 ][1 ]; Jy[pi + 2 ] = dpDX [1 ][2 ];
248
+ // Point Jacobian
249
+ unsigned int pi = numCameras * 6 + vpi * 3 ;
250
+ vpMatrix::mult2Matrices (dxydcX, cRw, dxydwX) ;
251
+ Jx[pi + 0 ] = dxydwX [0 ][0 ]; Jx[pi + 1 ] = dxydwX [0 ][1 ]; Jx[pi + 2 ] = dxydwX [0 ][2 ];
252
+ Jy[pi + 0 ] = dxydwX [1 ][0 ]; Jy[pi + 1 ] = dxydwX [1 ][1 ]; Jy[pi + 2 ] = dxydwX [1 ][2 ];
250
253
251
254
++pointIndex;
252
255
}
253
256
}
254
257
255
- void vpRBBundleAdjustment::CameraData::fillJacobianSparsity (const MapIndexView &mapView, vpArray2D< int > &S , unsigned int cameraIndex, unsigned int numCameras, unsigned int startResidual) const
258
+ void vpRBBundleAdjustment::CameraData::jacobianSparsityPattern (const MapIndexView &mapView, std::vector< unsigned int > &rowIndices, std::vector< unsigned int > &columnIndices , unsigned int cameraIndex, unsigned int numCameras, unsigned int startResidual) const
256
259
{
257
260
unsigned int pointIndex = 0 ;
258
261
for (unsigned int i = startResidual; i < startResidual + numResiduals (); i += 2 ) {
262
+ unsigned int pi = mapView.getViewIndex (m_indices3d[pointIndex]);
263
+ unsigned pIndex = numCameras * 6 + pi * 3 ;
259
264
for (unsigned int j = 0 ; j < 6 ; ++j) {
260
- S[i][cameraIndex * 6 + j] = 1 ;
261
- S[i + 1 ][cameraIndex * 6 + j] = 1 ;
265
+ rowIndices.push_back (i);
266
+ columnIndices.push_back (cameraIndex * 6 + j);
267
+ }
268
+ for (unsigned int j = 0 ; j < 3 ; ++j) {
269
+ rowIndices.push_back (i);
270
+ columnIndices.push_back (pIndex + j);
262
271
}
263
272
264
-
265
- unsigned int pi = mapView.getViewIndex (m_indices3d[pointIndex]);
273
+ for (unsigned int j = 0 ; j < 6 ; ++j) {
274
+ rowIndices.push_back (i + 1 );
275
+ columnIndices.push_back (cameraIndex * 6 + j);
276
+ }
266
277
for (unsigned int j = 0 ; j < 3 ; ++j) {
267
- S[i][numCameras * 6 + pi * 3 + j] = 1 ;
268
- S[i + 1 ][numCameras * 6 + pi * 3 + j] = 1 ;
278
+ rowIndices. push_back (i + 1 ) ;
279
+ columnIndices. push_back (pIndex + j) ;
269
280
}
270
281
++pointIndex;
271
-
272
282
}
273
283
}
274
284
@@ -342,6 +352,27 @@ void vpRBBundleAdjustment::MapIndexView::update(const std::list<CameraData> &cam
342
352
usedPointIndices.insert (cameraIndices.begin (), cameraIndices.end ());
343
353
}
344
354
355
+ unsigned int index1 = 0 ;
356
+ for (const CameraData &c1: cameras) {
357
+ unsigned int index2 = 0 ;
358
+ for (const CameraData &c2: cameras) {
359
+ if (&c1 != &c2) {
360
+ std::vector<unsigned int > sharedPoints;
361
+ const std::vector<unsigned int > &cameraIndices = c1.getPointsIndices ();
362
+ const std::vector<unsigned int > &cameraIndices2 = c2.getPointsIndices ();
363
+ std::set_intersection (cameraIndices.begin (), cameraIndices.end (), cameraIndices2.begin (), cameraIndices2.end (), std::back_inserter (sharedPoints));
364
+ std::cout << " Camera " << index1 << " and camera " << index2 << " share " << sharedPoints.size () << " points." ;
365
+ std::cout << " Camera " << index1 << " has " << cameraIndices.size () << " observed points." ;
366
+ std::cout << " Camera " << index2 << " has " << cameraIndices2.size () << " observed points." << std::endl;
367
+
368
+
369
+ }
370
+
371
+ ++index2;
372
+ }
373
+ ++index1;
374
+ }
375
+
345
376
std::vector<unsigned int > sortedPointIndices (usedPointIndices.begin (), usedPointIndices.end ());
346
377
std::sort (sortedPointIndices.begin (), sortedPointIndices.end ());
347
378
0 commit comments