Skip to content

Commit 22c3b97

Browse files
committed
fix issue with point insertion based on distance, compute how many points are shared between camera pairs
1 parent bc59051 commit 22c3b97

File tree

4 files changed

+120
-48
lines changed

4 files changed

+120
-48
lines changed

modules/python/config/rbt.json

+17
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,23 @@
402402
"returns_ref_ok": true
403403
}
404404
]
405+
},
406+
"vpRBBundleAdjustment": {
407+
"methods": [
408+
{
409+
"static": false,
410+
"signature": "void jacobianSparsityPattern(std::vector<unsigned int>&, std::vector<unsigned int>&)",
411+
"use_default_param_policy": false,
412+
"param_is_input": [
413+
false,
414+
false
415+
],
416+
"param_is_output": [
417+
true,
418+
true
419+
]
420+
}
421+
]
405422
}
406423
},
407424
"enums": {},

modules/tracker/rbt/include/visp3/rbt/vpRBBundleAdjustment.h

+19-8
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,35 @@ class VISP_EXPORT vpRBBundleAdjustment
9393
*
9494
* @param S The Jacobian sparsity matrix, that has the same size as the jacobian
9595
*/
96-
void jacobianSparsity(vpArray2D<int> &S);
96+
void jacobianSparsityPattern(std::vector<unsigned int> &rowIndices, std::vector<unsigned int> &columnIndices);
9797

9898
void computeJacobian(const vpColVector &params, vpMatrix &J)
9999
{
100-
unsigned int numParams = numCameras() * 6 + numPoints3d() * 3;
101-
J.resize(numResiduals(), numParams, true, false);
100+
unsigned int numParams = numParameters();
101+
J.resize(numResiduals(), numParams, false, false);
102102
unsigned int i = 0;
103103
unsigned int cameraIndex = 0;
104+
105+
std::vector<std::tuple<CameraData *, unsigned int, unsigned int>> parallelParams;
106+
104107
for (CameraData &camera: m_cameras) {
105-
camera.jacobian(m_mapView, params, J, cameraIndex, numCameras(), i);
108+
parallelParams.push_back(std::make_tuple(&camera, cameraIndex, i));
106109
i += camera.numResiduals();
107110
++cameraIndex;
108111
}
112+
#pragma omp parallel for
113+
for (unsigned int i = 0; i < parallelParams.size(); ++i) {
114+
CameraData *camera = std::get<0>(parallelParams[i]);
115+
unsigned int cameraIndex = std::get<1>(parallelParams[i]);
116+
unsigned int residualIndex = std::get<2>(parallelParams[i]);
117+
camera->jacobian(m_mapView, params, J, cameraIndex, numCameras(), residualIndex);
118+
}
109119
}
110120

111121

112122
unsigned int numCameras() const { return m_cameras.size(); }
113123
unsigned int numPoints3d() const { return m_mapView.numPoints(); }
124+
unsigned int numParameters() const { return numCameras() * 6 + numPoints3d() * 3; }
114125
unsigned int numResiduals() const
115126
{
116127
unsigned int numResiduals = 0;
@@ -130,17 +141,17 @@ class VISP_EXPORT vpRBBundleAdjustment
130141

131142
unsigned int numResiduals() const { return m_points2d.size() * 2; }
132143
const std::vector<unsigned int> &getPointsIndices() const { return m_indices3d; }
133-
vpPoseVector pose() const { return vpPoseVector(m_cTw); }
134-
void setPose(const vpPoseVector &r) { m_cTw = r; }
144+
vpPoseVector pose() const { return vpPoseVector(m_r); }
145+
void setPose(const vpPoseVector &r) { m_r = r; }
135146

136147
void error(MapIndexView &mapView, const vpColVector &params, vpColVector &e, unsigned int cameraIndex, unsigned int numCameras, unsigned int startResidual) const;
137148
void jacobian(const MapIndexView &mapView, const vpColVector &params, vpMatrix &J, unsigned int cameraIndex, unsigned int numCameras, unsigned int startResidual) const;
138-
void fillJacobianSparsity(const MapIndexView &mapView, vpArray2D<int> &S, unsigned int cameraIndex, unsigned int numCameras, unsigned int startResidual) const;
149+
void jacobianSparsityPattern(const MapIndexView &mapView, std::vector<unsigned int> &rowIndices, std::vector<unsigned int> &columnIndices, unsigned int cameraIndex, unsigned int numCameras, unsigned int startResidual) const;
139150

140151

141152
void filter(const std::vector<unsigned int> &filteredIndices);
142153
private:
143-
vpHomogeneousMatrix m_cTw;
154+
vpPoseVector m_r;
144155
std::vector<unsigned int> m_indices3d;
145156
std::vector<std::array<double, 2>> m_points2d;
146157

modules/tracker/rbt/src/vo/vpPointMap.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,26 @@ void vpPointMap::selectValidNewCandidates(const vpCameraParameters &cam, const v
155155
oX += t;
156156

157157
bool isFarEnoughFromOtherPoints = true;
158-
for (unsigned int j = 0; j < m_X.getRows(); ++j) {
159-
double errSq = vpMath::sqr(oX[0] - m_X[j][0]) + vpMath::sqr(oX[1] - m_X[j][1]) + vpMath::sqr(oX[2] - m_X[j][2]);
160-
if (errSq < farEnoughThresholdSq) {
161-
isFarEnoughFromOtherPoints = false;
162-
break;
158+
if (farEnoughThresholdSq > 0.0) {
159+
for (unsigned int j = 0; j < m_X.getRows(); ++j) {
160+
double errSq = vpMath::sqr(oX[0] - m_X[j][0]) + vpMath::sqr(oX[1] - m_X[j][1]) + vpMath::sqr(oX[2] - m_X[j][2]);
161+
if (errSq < farEnoughThresholdSq) {
162+
isFarEnoughFromOtherPoints = false;
163+
break;
164+
}
163165
}
166+
if (isFarEnoughFromOtherPoints) {
167+
for (vpColVector &other: validoXList) {
168+
double errSq = vpMath::sqr(oX[0] - other[0]) + vpMath::sqr(oX[1] - other[1]) + vpMath::sqr(oX[2] - other[2]);
169+
if (errSq < farEnoughThresholdSq) {
170+
isFarEnoughFromOtherPoints = false;
171+
break;
172+
}
173+
}
174+
}
175+
164176
}
177+
165178
if (isFarEnoughFromOtherPoints) {
166179
validoXList.push_back(oX);
167180
validCandidateIndices.push_back(originalIndices[i][0]);

modules/tracker/rbt/src/vo/vpRBBundleAdjustment.cpp

+66-35
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void vpRBBundleAdjustment::asParamVector(vpColVector &params) const
4242
{
4343

4444
unsigned int numUsedPoints = m_mapView.numPoints();
45-
params.resize(m_cameras.size() * 6 + numUsedPoints * 3, false);
45+
params.resize(numParameters(), false);
4646
unsigned int i = 0;
4747
// First parameters are the camera poses
4848
for (const CameraData &camera: m_cameras) {
@@ -75,7 +75,7 @@ void vpRBBundleAdjustment::updateFromParamVector(const vpColVector &params)
7575
{
7676

7777
#ifdef DEBUG_RB_BA
78-
if (params.size() != m_cameras.size() * 6 + m_mapView.numPoints() * 3) {
78+
if (params.size() != numParameters()) {
7979
throw vpException(vpException::dimensionError, "Mismatch between param vector size and number of points/cameras");
8080
}
8181
#endif
@@ -128,14 +128,15 @@ void vpRBBundleAdjustment::computeError(const vpColVector &params, vpColVector &
128128
}
129129
}
130130

131-
void vpRBBundleAdjustment::jacobianSparsity(vpArray2D<int> &S)
131+
void vpRBBundleAdjustment::jacobianSparsityPattern(std::vector<unsigned int> &rowIndices, std::vector<unsigned int> &columnIndices)
132132
{
133-
unsigned int numParams = numCameras() * 6 + numPoints3d() * 3;
134-
S.resize(numResiduals(), numParams);
133+
rowIndices.reserve(numResiduals() * 9);
134+
columnIndices.reserve(numResiduals() * 9);
135+
135136
unsigned int i = 0;
136137
unsigned int cameraIndex = 0;
137138
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);
139140
i += camera.numResiduals();
140141
++cameraIndex;
141142
}
@@ -144,7 +145,7 @@ void vpRBBundleAdjustment::jacobianSparsity(vpArray2D<int> &S)
144145
////////// Camera data
145146
vpRBBundleAdjustment::CameraData::CameraData(const vpCameraParameters &cam, const vpHomogeneousMatrix &cTw, const std::vector<unsigned int> &indices3d, const vpMatrix &uvs)
146147
{
147-
m_cTw = cTw;
148+
m_r = cTw;
148149
m_indices3d = indices3d;
149150

150151
#ifdef DEBUG_RB_BA
@@ -179,8 +180,8 @@ void vpRBBundleAdjustment::CameraData::error(MapIndexView &mapView, const vpColV
179180
vpColVector wX(3);
180181
vpColVector cX(3);
181182
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;
184185
wX[0] = pp[0];
185186
wX[1] = pp[1];
186187
wX[2] = pp[2];
@@ -209,9 +210,8 @@ void vpRBBundleAdjustment::CameraData::jacobian(const MapIndexView &mapView, con
209210
vpColVector wX(3);
210211
vpColVector cX(3);
211212

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);
215215
unsigned int pointIndex = 0;
216216

217217
for (unsigned int i = startResidual; i < startResidual + numResiduals(); i += 2) {
@@ -225,50 +225,60 @@ void vpRBBundleAdjustment::CameraData::jacobian(const MapIndexView &mapView, con
225225
cX = cRw * wX;
226226
cX += t;
227227

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];
232231

233232
double *Jx = J[i];
234233
double *Jy = J[i + 1];
235234

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;
239243
// 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];
242245

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;
244247

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];
250253

251254
++pointIndex;
252255
}
253256
}
254257

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
256259
{
257260
unsigned int pointIndex = 0;
258261
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;
259264
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);
262271
}
263272

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+
}
266277
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);
269280
}
270281
++pointIndex;
271-
272282
}
273283
}
274284

@@ -342,6 +352,27 @@ void vpRBBundleAdjustment::MapIndexView::update(const std::list<CameraData> &cam
342352
usedPointIndices.insert(cameraIndices.begin(), cameraIndices.end());
343353
}
344354

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+
345376
std::vector<unsigned int> sortedPointIndices(usedPointIndices.begin(), usedPointIndices.end());
346377
std::sort(sortedPointIndices.begin(), sortedPointIndices.end());
347378

0 commit comments

Comments
 (0)