[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54849] branches/soc-2011-tomato/extern/ libmv/libmv: Oh bummer, it's too early for this patch to be in!

Sergey Sharybin sergey.vfx at gmail.com
Mon Feb 25 11:19:02 CET 2013


Revision: 54849
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54849
Author:   nazgul
Date:     2013-02-25 10:19:02 +0000 (Mon, 25 Feb 2013)
Log Message:
-----------
Oh bummer, it's too early for this patch to be in!

Modified Paths:
--------------
    branches/soc-2011-tomato/extern/libmv/libmv/multiview/euclidean_resection.cc
    branches/soc-2011-tomato/extern/libmv/libmv/simple_pipeline/bundle.cc

Modified: branches/soc-2011-tomato/extern/libmv/libmv/multiview/euclidean_resection.cc
===================================================================
--- branches/soc-2011-tomato/extern/libmv/libmv/multiview/euclidean_resection.cc	2013-02-25 10:14:40 UTC (rev 54848)
+++ branches/soc-2011-tomato/extern/libmv/libmv/multiview/euclidean_resection.cc	2013-02-25 10:19:02 UTC (rev 54849)
@@ -653,8 +653,8 @@
   
   // Finally, with all three solutions, select the (R, t) with the best RMSE.
   VLOG(2) << "RMSE for solution 0: " << rmse(0);
-  VLOG(2) << "RMSE for solution 1: " << rmse(1);
-  VLOG(2) << "RMSE for solution 2: " << rmse(2);
+  VLOG(2) << "RMSE for solution 1: " << rmse(0);
+  VLOG(2) << "RMSE for solution 2: " << rmse(0);
   size_t n = 0;
   if (rmse(1) < rmse(0)) {
     n = 1;

Modified: branches/soc-2011-tomato/extern/libmv/libmv/simple_pipeline/bundle.cc
===================================================================
--- branches/soc-2011-tomato/extern/libmv/libmv/simple_pipeline/bundle.cc	2013-02-25 10:14:40 UTC (rev 54848)
+++ branches/soc-2011-tomato/extern/libmv/libmv/simple_pipeline/bundle.cc	2013-02-25 10:19:02 UTC (rev 54849)
@@ -18,10 +18,10 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 // IN THE SOFTWARE.
 
+#define V3DLIB_ENABLE_SUITESPARSE 1
+
 #include <map>
 
-#include "ceres/ceres.h"
-#include "ceres/rotation.h"
 #include "libmv/base/vector.h"
 #include "libmv/logging/logging.h"
 #include "libmv/multiview/fundamental.h"
@@ -31,327 +31,218 @@
 #include "libmv/simple_pipeline/bundle.h"
 #include "libmv/simple_pipeline/reconstruction.h"
 #include "libmv/simple_pipeline/tracks.h"
+#include "third_party/ssba/Geometry/v3d_cameramatrix.h"
+#include "third_party/ssba/Geometry/v3d_metricbundle.h"
+#include "third_party/ssba/Math/v3d_linear.h"
+#include "third_party/ssba/Math/v3d_linear_utils.h"
 
 namespace libmv {
 
-// The intrinsics need to get combined into a single parameter block; use these
-// enums to index instead of numeric constants.
-enum {
-  OFFSET_FOCAL_LENGTH,
-  OFFSET_PRINCIPAL_POINT_X,
-  OFFSET_PRINCIPAL_POINT_Y,
-  OFFSET_K1,
-  OFFSET_K2,
-  OFFSET_K3,
-  OFFSET_P1,
-  OFFSET_P2,
-};
+void EuclideanBundle(const Tracks &tracks,
+                     EuclideanReconstruction *reconstruction) {
+  CameraIntrinsics intrinsics;
+  EuclideanBundleCommonIntrinsics(tracks,
+                                  BUNDLE_NO_INTRINSICS,
+                                  reconstruction,
+                                  &intrinsics);
+}
 
-namespace {
+void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
+                                     int bundle_intrinsics,
+                                     EuclideanReconstruction *reconstruction,
+                                     CameraIntrinsics *intrinsics) {
+  LG << "Original intrinsics: " << *intrinsics;
+  vector<Marker> markers = tracks.AllMarkers();
 
-struct OpenCVReprojectionError {
-  OpenCVReprojectionError(double observed_x, double observed_y)
-      : observed_x(observed_x), observed_y(observed_y) {}
-
-  template <typename T>
-  bool operator()(const T* const intrinsics,
-                  const T* const R,  // Rotation 3x3 column-major.
-                  const T* const t,  // Translation 3x1.
-                  const T* const X,  // Point coordinates 3x1.
-                  T* residuals) const {
-    // Unpack the intrinsics.
-    const T& focal_length      = intrinsics[OFFSET_FOCAL_LENGTH];
-    const T& principal_point_x = intrinsics[OFFSET_PRINCIPAL_POINT_X];
-    const T& principal_point_y = intrinsics[OFFSET_PRINCIPAL_POINT_Y];
-    const T& k1                = intrinsics[OFFSET_K1];
-    const T& k2                = intrinsics[OFFSET_K2];
-    const T& k3                = intrinsics[OFFSET_K3];
-    const T& p1                = intrinsics[OFFSET_P1];
-    const T& p2                = intrinsics[OFFSET_P2];
-
-    // Compute projective coordinates: x = RX + t.
-    T x[3];
-    x[0] = R[0]*X[0] + R[3]*X[1] + R[6]*X[2] + t[0];
-    x[1] = R[1]*X[0] + R[4]*X[1] + R[7]*X[2] + t[1];
-    x[2] = R[2]*X[0] + R[5]*X[1] + R[8]*X[2] + t[2];
-
-    // Compute normalized coordinates: x /= x[2].
-    T xn = x[0] / x[2];
-    T yn = x[1] / x[2];
-
-    T predicted_x, predicted_y;
-
-    // XXX: EuclideanBundle uses empty intrinsics, which would make
-    //      undistortion code below behave wrong
-    //
-    //      Further, bundling currently happens with undistorted
-    //      normalized tracks.
-    //
-    //      We need to reconsider pipelien, for now we'll keep
-    //      debugging with refinement disabled
-    if (focal_length != T(0)) {
-      // Apply distortion to the normalized points to get (xd, yd).
-      // TODO(keir): Do early bailouts for zero distortion; these are expensive
-      // jet operations.
-      T r2 = xn*xn + yn*yn;
-      T r4 = r2 * r2;
-      T r6 = r4 * r2;
-      T r_coeff = T(1) + k1*r2 + k2*r4 + k3*r6;
-      T xd = xn * r_coeff + T(2)*p1*xn*yn + p2*(r2 + T(2)*xn*xn);
-      T yd = yn * r_coeff + T(2)*p2*xn*yn + p1*(r2 + T(2)*yn*yn);
-
-      // Apply focal length and principal point to get the final
-      // image coordinates.
-      predicted_x = focal_length * xd + principal_point_x;
-      predicted_y = focal_length * yd + principal_point_y;
-    } else {
-      predicted_x = xn;
-      predicted_y = yn;
+  // "index" in this context is the index that V3D's optimizer will see. The
+  // V3D index must be dense in that the cameras are numbered 0...n-1, which is
+  // not the case for the "image" numbering that arises from the tracks
+  // structure. The complicated mapping is necessary to convert between the two
+  // representations.
+  std::map<EuclideanCamera *, int> camera_to_index;
+  std::map<EuclideanPoint *, int> point_to_index;
+  vector<EuclideanCamera *> index_to_camera;
+  vector<EuclideanPoint *> index_to_point;
+  int num_cameras = 0;
+  int num_points = 0;
+  for (int i = 0; i < markers.size(); ++i) {
+    const Marker &marker = markers[i];
+    EuclideanCamera *camera = reconstruction->CameraForImage(marker.image);
+    EuclideanPoint *point = reconstruction->PointForTrack(marker.track);
+    if (camera && point) {
+      if (camera_to_index.find(camera) == camera_to_index.end()) {
+        camera_to_index[camera] = num_cameras;
+        index_to_camera.push_back(camera);
+        num_cameras++;
+      }
+      if (point_to_index.find(point) == point_to_index.end()) {
+        point_to_index[point] = num_points;
+        index_to_point.push_back(point);
+        num_points++;
+      }
     }
+  }
 
-    // The error is the difference between the predicted and observed position.
-    residuals[0] = predicted_x - T(observed_x);
-    residuals[1] = predicted_y - T(observed_y);
-
-    return true;
+  // Convert libmv's K matrix to V3d's K matrix.
+  V3D::Matrix3x3d v3d_K;
+  for (int i = 0; i < 3; ++i) {
+    for (int j = 0; j < 3; ++j) {
+      v3d_K[i][j] = intrinsics->K()(i, j);
+    }
   }
 
-  double observed_x;
-  double observed_y;
-};
+  // Convert libmv's distortion to v3d distortion.
+  V3D::StdDistortionFunction v3d_distortion;
+  v3d_distortion.k1 = intrinsics->k1();
+  v3d_distortion.k2 = intrinsics->k2();
+  v3d_distortion.p1 = intrinsics->p1();
+  v3d_distortion.p2 = intrinsics->p2();
 
-struct RotationMatrixPlus {
-  template<typename T>
-  bool operator()(const T* R_array, // Rotation 3x3 col-major.
-                  const T* delta,   // Angle-axis delta
-                  T* R_plus_delta_array) const {
-    T angle_axis[3];
+  // Convert libmv's cameras to V3D's cameras.
+  std::vector<V3D::CameraMatrix> v3d_cameras(index_to_camera.size());
+  for (int k = 0; k < index_to_camera.size(); ++k) {
+    V3D::Matrix3x3d R;
+    V3D::Vector3d t;
 
-    ceres::RotationMatrixToAngleAxis(R_array, angle_axis);
+    // Libmv's rotation matrix type.
+    const Mat3 &R_libmv = index_to_camera[k]->R;
+    const Vec3 &t_libmv = index_to_camera[k]->t;
 
-    angle_axis[0] += delta[0];
-    angle_axis[1] += delta[1];
-    angle_axis[2] += delta[2];
-
-    ceres::AngleAxisToRotationMatrix(angle_axis, R_plus_delta_array);
-
-    return true;
+    for (int i = 0; i < 3; ++i) {
+      for (int j = 0; j < 3; ++j) {
+        R[i][j] = R_libmv(i, j);
+      }
+      t[i] = t_libmv(i);
+    }
+    v3d_cameras[k].setIntrinsic(v3d_K);
+    v3d_cameras[k].setRotation(R);
+    v3d_cameras[k].setTranslation(t);
   }
-};
+  LG << "Number of cameras: " << index_to_camera.size();
 
-template<typename PlusFunctor, int kGlobalSize, int kLocalSize>
-class AutodiffParameterization : public ceres::LocalParameterization {
- public:
-  AutodiffParameterization(const PlusFunctor &plus_functor)
-    : plus_functor_(plus_functor) {}
-
-  virtual ~AutodiffParameterization() {}
-
-  virtual bool Plus(const double* x,
-                    const double* delta,
-                    double* x_plus_delta) const {
-    return plus_functor_(x, delta, x_plus_delta);
+  // Convert libmv's points to V3D's points.
+  std::vector<V3D::Vector3d> v3d_points(index_to_point.size());
+  for (int i = 0; i < index_to_point.size(); i++) {
+    v3d_points[i][0] = index_to_point[i]->X(0);
+    v3d_points[i][1] = index_to_point[i]->X(1);
+    v3d_points[i][2] = index_to_point[i]->X(2);
   }
+  LG << "Number of points: " << index_to_point.size();
 
-  virtual bool ComputeJacobian(const double* x, double* jacobian) const {
-    double zero_delta[kLocalSize] = { 0.0 };
-    double x_plus_delta[kGlobalSize];
-    const double* parameters[2] = { x, zero_delta };
-    double* jacobians_array[2] = { NULL, jacobian };
-
-    Plus(x, zero_delta, x_plus_delta);
-
-    return ceres::internal::AutoDiff<PlusFunctor,
-                              double,
-                              kGlobalSize, kLocalSize>
-        ::Differentiate(plus_functor_,
-                        parameters,
-                        kGlobalSize,
-                        x_plus_delta,
-                        jacobians_array);
-
-    return true;
+  // Convert libmv's measurements to v3d measurements.
+  int num_residuals = 0;
+  std::vector<V3D::Vector2d> v3d_measurements;
+  std::vector<int> v3d_camera_for_measurement;
+  std::vector<int> v3d_point_for_measurement;
+  for (int i = 0; i < markers.size(); ++i) {
+    EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
+    EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+    if (!camera || !point) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list