Fix T38844: Crash if weight track = 0
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 27 Feb 2014 08:27:30 +0000 (14:27 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 27 Feb 2014 08:31:09 +0000 (14:31 +0600)
Avoid zero-sized problem when doing euclidean intersection

Zero-sized problem might occur when intersecting track with
constant zero weight. For such tracks we'll just use result
of algebraic intersection.

TODO: We probably need to have a separate BA step to adjust
positions of tracks with constant zero weight.

extern/libmv/libmv/simple_pipeline/intersect.cc

index 6a098da272db2190b00f232f9bffdc0db094db6a..ddb713684a4e4c78950375c27920efdc200fd9f0 100644 (file)
@@ -100,6 +100,8 @@ bool EuclideanIntersect(const vector<Marker> &markers,
 
   ceres::Problem problem;
 
+  // Add residual blocks to the problem.
+  int num_residuals = 0;
   for (int i = 0; i < markers.size(); ++i) {
     const Marker &marker = markers[i];
     if (marker.weight != 0.0) {
@@ -113,9 +115,27 @@ bool EuclideanIntersect(const vector<Marker> &markers,
               3>(new EuclideanIntersectCostFunctor(marker, camera)),
           NULL,
           &X(0));
+         num_residuals++;
     }
   }
 
+  // TODO(sergey): Once we'll update Ceres to the next version
+  // we wouldn't need this check anymore -- Ceres will deal with
+  // zero-sized problems nicely.
+  LG << "Number of residuals: " << num_residuals;
+  if (!num_residuals) {
+    LG << "Skipping running minimizer with zero residuals";
+
+       // We still add 3D point for the track regardless it was
+       // optimized or not. If track is a constant zero it'll use
+       // algebraic intersection result as a 3D coordinate.
+
+    Vec3 point = X.head<3>();
+    reconstruction->InsertPoint(markers[0].track, point);
+
+    return true;
+  }
+
   // Configure the solve.
   ceres::Solver::Options solver_options;
   solver_options.linear_solver_type = ceres::DENSE_QR;