[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45565] trunk/blender/extern/libmv: libmv: bundle new upstream version from own branch with rigid registration implementation

Sergey Sharybin sergey.vfx at gmail.com
Thu Apr 12 13:37:51 CEST 2012


Revision: 45565
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45565
Author:   nazgul
Date:     2012-04-12 11:37:51 +0000 (Thu, 12 Apr 2012)
Log Message:
-----------
libmv: bundle new upstream version from own branch with rigid registration implementation

Currently not used in blender code but is needed for some current work.

Modified Paths:
--------------
    trunk/blender/extern/libmv/CMakeLists.txt
    trunk/blender/extern/libmv/ChangeLog
    trunk/blender/extern/libmv/files.txt
    trunk/blender/extern/libmv/libmv/numeric/numeric.h
    trunk/blender/extern/libmv/libmv/simple_pipeline/resect.cc
    trunk/blender/extern/libmv/libmv-capi.cpp
    trunk/blender/extern/libmv/libmv-capi.h

Added Paths:
-----------
    trunk/blender/extern/libmv/libmv/simple_pipeline/rigid_registration.cc
    trunk/blender/extern/libmv/libmv/simple_pipeline/rigid_registration.h

Modified: trunk/blender/extern/libmv/CMakeLists.txt
===================================================================
--- trunk/blender/extern/libmv/CMakeLists.txt	2012-04-12 11:27:50 UTC (rev 45564)
+++ trunk/blender/extern/libmv/CMakeLists.txt	2012-04-12 11:37:51 UTC (rev 45565)
@@ -72,6 +72,7 @@
 	libmv/simple_pipeline/pipeline.cc
 	libmv/simple_pipeline/reconstruction.cc
 	libmv/simple_pipeline/resect.cc
+	libmv/simple_pipeline/rigid_registration.cc
 	libmv/simple_pipeline/tracks.cc
 	libmv/tracking/brute_region_tracker.cc
 	libmv/tracking/esm_region_tracker.cc
@@ -128,6 +129,7 @@
 	libmv/simple_pipeline/pipeline.h
 	libmv/simple_pipeline/reconstruction.h
 	libmv/simple_pipeline/resect.h
+	libmv/simple_pipeline/rigid_registration.h
 	libmv/simple_pipeline/tracks.h
 	libmv/tracking/brute_region_tracker.h
 	libmv/tracking/esm_region_tracker.h

Modified: trunk/blender/extern/libmv/ChangeLog
===================================================================
--- trunk/blender/extern/libmv/ChangeLog	2012-04-12 11:27:50 UTC (rev 45564)
+++ trunk/blender/extern/libmv/ChangeLog	2012-04-12 11:37:51 UTC (rev 45565)
@@ -1,3 +1,36 @@
+commit fa3842e472e3b9c789e47bf6d8f592aa40a84f16
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date:   Thu Apr 12 12:32:48 2012 +0600
+
+    implementation of some basic algorithms for point cloud orientation:
+    
+    - Implementation of rigid registration algorithm which searches transformation
+      form one point cloud to another assuming that points in this clouds are
+      already paired (points with the same index in different clouds belongs to
+      the same pair) which minimizes average distance between points in pairs.
+    
+      Algorithm uses Levenberg-Marquardt solver to find such transformation.
+    
+      Supports registration of rotation-scale-transform (which is probably most
+      common usage) and rotation only (which might be useful for basic modal
+      tripod solver).
+    
+    - Implementation of Iterative-Point-Clouds algorithm which searches
+      transformation from one arbitrary point cloud to another  making
+      points as closest to each other as possible.
+    
+      This algorithm doesn't require points be initially paired, but for
+      good result clouds should have rough initial orientation. If they're
+      arbitrary oriented from the very beginning, algorithm might fail
+      producing good resold.
+    
+      Iteration is based on building pairs of closest to each other points
+      and registering rigid transformation between them which incrementally
+      constructs final result.
+    
+    TODO: building pairs might be speedup a lot using data structures like
+          AABB trees, K-D trees or so.
+
 commit 9618d9a1d48bb3c28da605d9027f57a74f462785
 Author: Sergey Sharybin <sergey.vfx at gmail.com>
 Date:   Wed Apr 11 14:17:14 2012 +0600
@@ -493,11 +526,3 @@
 Date:   Fri Aug 19 14:59:24 2011 +0200
 
     Expose regularization parameters (areaPenalty and conditionPenalty) in API.
-
-commit 3e84ae5fbac10451d4935418f6281a90cedace11
-Author: Matthias Fauconneau <matthias.fauconneau at gmail.com>
-Date:   Fri Aug 19 14:19:27 2011 +0200
-
-    Add LaplaceFilter.
-    Add regularization in affine SAD Tracker (keep constant area and good condition number).
-    UI: Better track display (+enable line antialiasing).

Modified: trunk/blender/extern/libmv/files.txt
===================================================================
--- trunk/blender/extern/libmv/files.txt	2012-04-12 11:27:50 UTC (rev 45564)
+++ trunk/blender/extern/libmv/files.txt	2012-04-12 11:37:51 UTC (rev 45565)
@@ -48,6 +48,8 @@
 libmv/simple_pipeline/reconstruction.h
 libmv/simple_pipeline/resect.cc
 libmv/simple_pipeline/resect.h
+libmv/simple_pipeline/rigid_registration.cc
+libmv/simple_pipeline/rigid_registration.h
 libmv/simple_pipeline/tracks.cc
 libmv/simple_pipeline/tracks.h
 libmv/tracking/brute_region_tracker.cc

Modified: trunk/blender/extern/libmv/libmv/numeric/numeric.h
===================================================================
--- trunk/blender/extern/libmv/libmv/numeric/numeric.h	2012-04-12 11:27:50 UTC (rev 45564)
+++ trunk/blender/extern/libmv/libmv/numeric/numeric.h	2012-04-12 11:37:51 UTC (rev 45565)
@@ -474,6 +474,17 @@
           1, 0, -x(0);
   return skew;
 }
+
+/// Returns the rotaiton matrix built from given vector of euler angles
+inline Mat3 RotationFromEulerVector(Vec3 euler_vector) {
+  double theta = euler_vector.norm();
+  if (theta == 0.0) {
+    return Mat3::Identity();
+  }
+  Vec3 w = euler_vector / theta;
+  Mat3 w_hat = CrossProductMatrix(w);
+  return Mat3::Identity() + w_hat*sin(theta) + w_hat*w_hat*(1 - cos(theta));
+}
 } // namespace libmv
 
 #endif  // LIBMV_NUMERIC_NUMERIC_H

Modified: trunk/blender/extern/libmv/libmv/simple_pipeline/resect.cc
===================================================================
--- trunk/blender/extern/libmv/libmv/simple_pipeline/resect.cc	2012-04-12 11:27:50 UTC (rev 45564)
+++ trunk/blender/extern/libmv/libmv/simple_pipeline/resect.cc	2012-04-12 11:37:51 UTC (rev 45565)
@@ -42,16 +42,6 @@
   return points;
 }
 
-Mat3 RotationFromEulerVector(Vec3 euler_vector) {
-  double theta = euler_vector.norm();
-  if (theta == 0.0) {
-    return Mat3::Identity();
-  }
-  Vec3 w = euler_vector / theta;
-  Mat3 w_hat = CrossProductMatrix(w);
-  return Mat3::Identity() + w_hat*sin(theta) + w_hat*w_hat*(1 - cos(theta));
-}
-
 // Uses an incremental rotation:
 //
 //   x = R' * R * X + t;

Added: trunk/blender/extern/libmv/libmv/simple_pipeline/rigid_registration.cc
===================================================================
--- trunk/blender/extern/libmv/libmv/simple_pipeline/rigid_registration.cc	                        (rev 0)
+++ trunk/blender/extern/libmv/libmv/simple_pipeline/rigid_registration.cc	2012-04-12 11:37:51 UTC (rev 45565)
@@ -0,0 +1,182 @@
+// Copyright (c) 2012 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/simple_pipeline/rigid_registration.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+
+namespace libmv {
+
+template<class RigidTransformation>
+struct RigidRegistrationCostFunction {
+ public:
+  typedef Vec FMatrixType;
+  typedef RigidTransformation XMatrixType;
+
+  RigidRegistrationCostFunction(const vector<Vec3> &reference_points,
+                                const vector<Vec3> &points):
+    reference_points_(reference_points),
+    points_(points) {}
+
+  Vec CalculateResiduals(const Mat3 &R,
+                         const Vec3 &S,
+                         const Vec3 &t) const {
+    Vec residuals(points_.size());
+    residuals.setZero();
+
+    // Convert scale vector to matrix
+    Mat3 SMat = Mat3::Identity();
+    SMat(0, 0) *= S(0);
+    SMat(1, 1) *= S(1);
+    SMat(2, 2) *= S(2);
+
+    for (int i = 0; i < points_.size(); i++) {
+      Vec3 transformed_point = R * SMat * points_[i] + t;
+
+      double norm = (transformed_point - reference_points_[i]).norm();
+
+      residuals(i) = norm * norm;
+    }
+
+    return residuals;
+  }
+
+  Vec operator()(const Vec9 &RSt) const {
+    Mat3 R = RotationFromEulerVector(RSt.head<3>());
+    Vec3 S = RSt.segment<3>(3);
+    Vec3 t = RSt.tail<3>();
+
+    return CalculateResiduals(R, S, t);
+  }
+
+  Vec operator()(const Vec3 &euler) const {
+    Mat3 R = RotationFromEulerVector(euler);
+
+    return CalculateResiduals(R, Vec3(1.0, 1.0, 1.0), Vec3::Zero());
+  }
+
+  Vec operator()(const Vec6 &Rt) const {
+    Mat3 R = RotationFromEulerVector(Rt.head<3>());
+    Vec3 t = Rt.tail<3>();
+
+    return CalculateResiduals(R, Vec3(1.0, 1.0, 1.0), t);
+  }
+
+ private:
+  vector<Vec3> reference_points_;
+  vector<Vec3> points_;
+};
+
+static double RigidRegistrationError(const vector<Vec3> &reference_points,
+                                     const vector<Vec3> &points,
+                                     const Mat3 &R,
+                                     const Vec3 &S,
+                                     const Vec3 &t) {
+  double error = 0.0;
+
+  Mat3 SMat = Mat3::Identity();
+  SMat(0, 0) *= S(0);
+  SMat(1, 1) *= S(1);
+  SMat(2, 2) *= S(2);
+
+  for (int i = 0; i < points.size(); i++) {
+    Vec3 new_point = R * SMat * points[i] + t;
+
+    double norm = (new_point - reference_points[i]).norm();
+    error += norm * norm;
+  }
+  error /= points.size();
+
+  return error;
+}
+
+double RigidRegistration(const vector<Vec3> &reference_points,
+                         const vector<Vec3> &points,
+                         Mat3 &R,
+                         Vec3 &S,
+                         Vec3 &t) {
+  typedef LevenbergMarquardt<RigidRegistrationCostFunction <Vec9> > Solver;
+
+  RigidRegistrationCostFunction<Vec9> rigidregistration_cost(reference_points, points);
+  Solver solver(rigidregistration_cost);
+
+  Vec9 RSt = Vec9::Zero();
+
+  RSt(3) = RSt(4) = RSt(5) = 1.0;
+
+  Solver::SolverParameters params;
+  /*Solver::Results results = */ solver.minimize(params, &RSt);
+  /* TODO(sergey): better error handling here */
+
+  LG << "Rigid registration completed, rotation is:" << RSt.head<3>().transpose()
+    << ", scale is " << RSt.segment<3>(3).transpose()
+    << ", translation is " << RSt.tail<3>().transpose();
+
+  // Decompose individual rotation and translation
+  R = RotationFromEulerVector(RSt.head<3>());
+  S = RSt.segment<3>(3);
+  t = RSt.tail<3>();
+
+  return RigidRegistrationError(reference_points, points, R, S, t);
+}
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list