[Bf-blender-cvs] [8232ce0] soc-2016-multiview: in the middle of nasty bundle migration

Tianwei Shen noreply at git.blender.org
Thu Jun 16 17:41:49 CEST 2016


Commit: 8232ce0605e1d920ad5e28d2b2f6a45305ec071f
Author: Tianwei Shen
Date:   Thu Jun 16 23:41:33 2016 +0800
Branches: soc-2016-multiview
https://developer.blender.org/rB8232ce0605e1d920ad5e28d2b2f6a45305ec071f

in the middle of nasty bundle migration

===================================================================

M	intern/libmv/CMakeLists.txt
M	intern/libmv/intern/reconstructionN.cc
A	intern/libmv/libmv/autotrack/bundle.cc
A	intern/libmv/libmv/autotrack/bundle.h
M	intern/libmv/libmv/autotrack/reconstruction.cc
M	intern/libmv/libmv/autotrack/reconstruction.h

===================================================================

diff --git a/intern/libmv/CMakeLists.txt b/intern/libmv/CMakeLists.txt
index c7d75ed..d88f0f4 100644
--- a/intern/libmv/CMakeLists.txt
+++ b/intern/libmv/CMakeLists.txt
@@ -75,6 +75,7 @@ if(WITH_LIBMV)
 		intern/tracks.cc
 		intern/tracksN.cc
 		libmv/autotrack/autotrack.cc
+		libmv/autotrack/bundle.cc
 		libmv/autotrack/predict_tracks.cc
 		libmv/autotrack/reconstruction.cc
 		libmv/autotrack/tracks.cc
@@ -126,6 +127,7 @@ if(WITH_LIBMV)
 		intern/tracks.h
 		intern/tracksN.h
 		libmv/autotrack/autotrack.h
+		libmv/autotrack/bundle.h
 		libmv/autotrack/callbacks.h
 		libmv/autotrack/frame_accessor.h
 		libmv/autotrack/marker.h
diff --git a/intern/libmv/intern/reconstructionN.cc b/intern/libmv/intern/reconstructionN.cc
index 1960b13..8369ff9 100644
--- a/intern/libmv/intern/reconstructionN.cc
+++ b/intern/libmv/intern/reconstructionN.cc
@@ -31,6 +31,7 @@
 
 #include "libmv/logging/logging.h"
 #include "libmv/autotrack/autotrack.h"
+#include "libmv/autotrack/bundle.h"
 #include "libmv/autotrack/frame_accessor.h"
 #include "libmv/autotrack/marker.h"
 #include "libmv/autotrack/model.h"
diff --git a/intern/libmv/libmv/autotrack/bundle.cc b/intern/libmv/libmv/autotrack/bundle.cc
new file mode 100644
index 0000000..2dfe231
--- /dev/null
+++ b/intern/libmv/libmv/autotrack/bundle.cc
@@ -0,0 +1,678 @@
+// Copyright (c) 2011, 2012, 2013, 2016 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.
+//
+// Author: Tianwei Shen <shentianweipku at gmail.com>
+//
+// This is a autotrack equivalent bundle set, adapted from simple_pipeline,
+// which replaces libmv with mv, includeing tracks and markers
+
+#include "libmv/autotrack/bundle.h"
+
+#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"
+#include "libmv/multiview/projection.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+#include "libmv/simple_pipeline/distortion_models.h"
+#include "libmv/autotrack/reconstruction.h"
+#include "libmv/autotrack/tracks.h"
+
+#ifdef _OPENMP
+#  include <omp.h>
+#endif
+
+using libmv::DistortionModelType;
+using libmv::Vec6;
+using libmv::PolynomialCameraIntrinsics;
+
+namespace mv {
+
+// The intrinsics need to get combined into a single parameter block; use these
+// enums to index instead of numeric constants.
+enum {
+  // Camera calibration values.
+  OFFSET_FOCAL_LENGTH,
+  OFFSET_PRINCIPAL_POINT_X,
+  OFFSET_PRINCIPAL_POINT_Y,
+
+  // Distortion model coefficients.
+  OFFSET_K1,
+  OFFSET_K2,
+  OFFSET_K3,
+  OFFSET_P1,
+  OFFSET_P2,
+
+  // Maximal possible offset.
+  OFFSET_MAX,
+};
+
+#define FIRST_DISTORTION_COEFFICIENT OFFSET_K1
+#define LAST_DISTORTION_COEFFICIENT OFFSET_P2
+#define NUM_DISTORTION_COEFFICIENTS  \
+  (LAST_DISTORTION_COEFFICIENT - FIRST_DISTORTION_COEFFICIENT + 1)
+
+namespace {
+
+// Cost functor which computes reprojection error of 3D point X
+// on camera defined by angle-axis rotation and it's translation
+// (which are in the same block due to optimization reasons).
+//
+// This functor uses a radial distortion model.
+struct OpenCVReprojectionError {
+  OpenCVReprojectionError(const DistortionModelType distortion_model,
+                          const double observed_x,
+                          const double observed_y,
+                          const double weight) :
+      distortion_model_(distortion_model),
+      observed_x_(observed_x), observed_y_(observed_y),
+      weight_(weight) {}
+
+  template <typename T>
+  bool operator()(const T* const intrinsics,
+                  const T* const R_t,  // Rotation denoted by angle axis followed with translation
+                  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];
+
+    // Compute projective coordinates: x = RX + t.
+    T x[3];
+
+    ceres::AngleAxisRotatePoint(R_t, X, x);
+    x[0] += R_t[3];
+    x[1] += R_t[4];
+    x[2] += R_t[5];
+
+    // Prevent points from going behind the camera.
+    if (x[2] < T(0)) {
+      return false;
+    }
+
+    // Compute normalized coordinates: x /= x[2].
+    T xn = x[0] / x[2];
+    T yn = x[1] / x[2];
+
+    T predicted_x, predicted_y;
+
+    // Apply distortion to the normalized points to get (xd, yd).
+    // TODO(keir): Do early bailouts for zero distortion; these are expensive
+    // jet operations.
+    switch (distortion_model_) {
+      case libmv::DISTORTION_MODEL_POLYNOMIAL:
+        {
+          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];
+
+		  libmv::ApplyPolynomialDistortionModel(focal_length,
+		                                        focal_length,
+		                                        principal_point_x,
+		                                        principal_point_y,
+		                                        k1, k2, k3,
+		                                        p1, p2,
+		                                        xn, yn,
+		                                        &predicted_x,
+		                                        &predicted_y);
+          break;
+        }
+      case libmv::DISTORTION_MODEL_DIVISION:
+        {
+          const T& k1 = intrinsics[OFFSET_K1];
+          const T& k2 = intrinsics[OFFSET_K2];
+
+		  libmv::ApplyDivisionDistortionModel(focal_length,
+		                                      focal_length,
+		                                      principal_point_x,
+		                                      principal_point_y,
+		                                      k1, k2,
+		                                      xn, yn,
+		                                      &predicted_x,
+		                                      &predicted_y);
+          break;
+        }
+      default:
+        LOG(FATAL) << "Unknown distortion model";
+    }
+
+    // The error is the difference between the predicted and observed position.
+    residuals[0] = (predicted_x - T(observed_x_)) * weight_;
+    residuals[1] = (predicted_y - T(observed_y_)) * weight_;
+    return true;
+  }
+
+  const DistortionModelType distortion_model_;
+  const double observed_x_;
+  const double observed_y_;
+  const double weight_;
+};
+
+// Print a message to the log which camera intrinsics are gonna to be optimixed.
+void BundleIntrinsicsLogMessage(const int bundle_intrinsics) {
+  if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
+    LOG(INFO) << "Bundling only camera positions.";
+  } else {
+    std::string bundling_message = "";
+
+#define APPEND_BUNDLING_INTRINSICS(name, flag) \
+    if (bundle_intrinsics & flag) { \
+      if (!bundling_message.empty()) { \
+        bundling_message += ", "; \
+      } \
+      bundling_message += name; \
+    } (void)0
+
+    APPEND_BUNDLING_INTRINSICS("f",      BUNDLE_FOCAL_LENGTH);
+    APPEND_BUNDLING_INTRINSICS("px, py", BUNDLE_PRINCIPAL_POINT);
+    APPEND_BUNDLING_INTRINSICS("k1",     BUNDLE_RADIAL_K1);
+    APPEND_BUNDLING_INTRINSICS("k2",     BUNDLE_RADIAL_K2);
+    APPEND_BUNDLING_INTRINSICS("p1",     BUNDLE_TANGENTIAL_P1);
+    APPEND_BUNDLING_INTRINSICS("p2",     BUNDLE_TANGENTIAL_P2);
+
+    LOG(INFO) << "Bundling " << bundling_message << ".";
+  }
+}
+
+// Pack intrinsics from object to an array for easier
+// and faster minimization.
+void PackIntrinisicsIntoArray(const CameraIntrinsics &intrinsics,
+                              double ceres_intrinsics[OFFSET_MAX]) {
+  ceres_intrinsics[OFFSET_FOCAL_LENGTH]       = intrinsics.focal_length();
+  ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X]  = intrinsics.principal_point_x();
+  ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y]  = intrinsics.principal_point_y();
+
+  int num_distortion_parameters = intrinsics.num_distortion_parameters();
+  assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS);
+
+  const double *distortion_parameters = intrinsics.distortion_parameters();
+  for (int i = 0; i < num_distortion_parameters; ++i) {
+    ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i] =
+        distortion_parameters[i];
+  }
+}
+
+// Unpack intrinsics back from an array to an object.
+void UnpackIntrinsicsFromArray(const double ceres_intrinsics[OFFSET_MAX],
+                               CameraIntrinsics *intrinsics) {
+  intrinsics->SetFocalLength(ceres_intrinsics[OFFSET_FOCAL_LENGTH],
+                             ceres_intrinsics[OFFSET_FOCAL_LENGTH]);
+
+  intrinsics->SetPrincipalPoint(ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X],
+                                ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y]);
+
+  int num_distortion_parameters = intrinsics->num_distortion_parameters();
+  assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS);
+
+  double *distortion_parameters = intrinsics->distortion_parameters();
+  for (int i = 0; i < num_distortion_parameters; ++

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list