[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