[Bf-blender-cvs] [e183da7] soc-2016-multiview: add intersect and resect
Tianwei Shen
noreply at git.blender.org
Thu Jun 23 09:01:55 CEST 2016
Commit: e183da7db99a93cfd28cff3967ec5218e3a310f8
Author: Tianwei Shen
Date: Thu Jun 23 15:01:41 2016 +0800
Branches: soc-2016-multiview
https://developer.blender.org/rBe183da7db99a93cfd28cff3967ec5218e3a310f8
add intersect and resect
===================================================================
M intern/libmv/CMakeLists.txt
M intern/libmv/intern/reconstructionN.cc
M intern/libmv/libmv/autotrack/bundle.cc
M intern/libmv/libmv/autotrack/bundle.h
A intern/libmv/libmv/autotrack/intersect.cc
A intern/libmv/libmv/autotrack/intersect.h
A intern/libmv/libmv/autotrack/pipeline.cc
A intern/libmv/libmv/autotrack/pipeline.h
M intern/libmv/libmv/autotrack/reconstruction.h
A intern/libmv/libmv/autotrack/resect.cc
A intern/libmv/libmv/autotrack/resect.h
===================================================================
diff --git a/intern/libmv/CMakeLists.txt b/intern/libmv/CMakeLists.txt
index d88f0f4..f1cc270 100644
--- a/intern/libmv/CMakeLists.txt
+++ b/intern/libmv/CMakeLists.txt
@@ -76,8 +76,11 @@ if(WITH_LIBMV)
intern/tracksN.cc
libmv/autotrack/autotrack.cc
libmv/autotrack/bundle.cc
+ libmv/autotrack/intersect.cc
+ libmv/autotrack/pipeline.cc
libmv/autotrack/predict_tracks.cc
libmv/autotrack/reconstruction.cc
+ libmv/autotrack/resect.cc
libmv/autotrack/tracks.cc
libmv/base/aligned_malloc.cc
libmv/image/array_nd.cc
@@ -130,12 +133,15 @@ if(WITH_LIBMV)
libmv/autotrack/bundle.h
libmv/autotrack/callbacks.h
libmv/autotrack/frame_accessor.h
+ libmv/autotrack/intersect.h
libmv/autotrack/marker.h
libmv/autotrack/model.h
+ libmv/autotrack/pipeline.h
libmv/autotrack/predict_tracks.h
libmv/autotrack/quad.h
libmv/autotrack/reconstruction.h
libmv/autotrack/region.h
+ libmv/autotrack/resect.h
libmv/autotrack/tracks.h
libmv/base/aligned_malloc.h
libmv/base/id_generator.h
diff --git a/intern/libmv/intern/reconstructionN.cc b/intern/libmv/intern/reconstructionN.cc
index 8f1cfe0..3f59b3e 100644
--- a/intern/libmv/intern/reconstructionN.cc
+++ b/intern/libmv/intern/reconstructionN.cc
@@ -35,6 +35,7 @@
#include "libmv/autotrack/frame_accessor.h"
#include "libmv/autotrack/marker.h"
#include "libmv/autotrack/model.h"
+#include "libmv/autotrack/pipeline.h"
#include "libmv/autotrack/predict_tracks.h"
#include "libmv/autotrack/quad.h"
#include "libmv/autotrack/reconstruction.h"
@@ -184,21 +185,19 @@ libmv_ReconstructionN** libmv_solveMultiviewReconstruction(
update_callback.invoke(0, "Initial reconstruction");
// reconstruct two views from the main clip
- if(!mv::ReconstructTwoFrames(keyframe_markers, 0, *(all_libmv_reconstruction[0]->intrinsics), &reconstruction))
- {
+ if(!mv::ReconstructTwoFrames(keyframe_markers, 0, *(all_libmv_reconstruction[0]->intrinsics), &reconstruction)) {
printf("mv::ReconstrucTwoFrames failed\n");
all_libmv_reconstruction[0]->is_valid = false;
return all_libmv_reconstruction;
}
// bundle the two-view initial reconstruction
- if(!mv::EuclideanBundleAll(all_normalized_tracks, &reconstruction))
- {
+ // (it is redundant for now since now 3d point is added at this stage)
+ if(!mv::EuclideanBundleAll(all_normalized_tracks, &reconstruction)) {
printf("mv::EuclideanBundleAll failed\n");
all_libmv_reconstruction[0]->is_valid = false;
return all_libmv_reconstruction;
}
- if(!mv::EuclideanReconstructionComplete(all_normalized_tracks, &reconstruction, &update_callback))
- {
+ if(!mv::EuclideanCompleteMultiviewReconstruction(all_normalized_tracks, &reconstruction, &update_callback)) {
printf("mv::EuclideanReconstructionComplete failed\n");
all_libmv_reconstruction[0]->is_valid = false;
return all_libmv_reconstruction;
diff --git a/intern/libmv/libmv/autotrack/bundle.cc b/intern/libmv/libmv/autotrack/bundle.cc
index 257f06d..1113e7b 100644
--- a/intern/libmv/libmv/autotrack/bundle.cc
+++ b/intern/libmv/libmv/autotrack/bundle.cc
@@ -682,10 +682,4 @@ bool EuclideanBundleAll(const Tracks &tracks,
return true;
}
-bool EuclideanReconstructionComplete(const Tracks &tracks,
- Reconstruction *reconstruction,
- libmv::ProgressUpdateCallback *update_callback) {
- return true;
-}
-
} // namespace mv
diff --git a/intern/libmv/libmv/autotrack/bundle.h b/intern/libmv/libmv/autotrack/bundle.h
index 4755bea..c367802 100644
--- a/intern/libmv/libmv/autotrack/bundle.h
+++ b/intern/libmv/libmv/autotrack/bundle.h
@@ -23,8 +23,8 @@
// This is a autotrack equivalent bundle set, adapted from simple_pipeline,
// which replaces libmv with mv, includeing tracks and markers
-#ifndef LIBMV_SIMPLE_PIPELINE_BUNDLE_H
-#define LIBMV_SIMPLE_PIPELINE_BUNDLE_H
+#ifndef LIBMV_AUTOTRACK_BUNDLE_H
+#define LIBMV_AUTOTRACK_BUNDLE_H
#include "libmv/numeric/numeric.h"
#include "libmv/autotrack/tracks.h"
@@ -132,10 +132,6 @@ void EuclideanBundleCommonIntrinsics(
bool EuclideanBundleAll(const Tracks &tracks,
Reconstruction *reconstruction);
-bool EuclideanReconstructionComplete(const Tracks &tracks,
- Reconstruction *reconstruction,
- libmv::ProgressUpdateCallback *update_callback);
} // namespace mv
-#endif // LIBMV_SIMPLE_PIPELINE_BUNDLE_H
-
+#endif // LIBMV_AUTOTRACK_BUNDLE_H
diff --git a/intern/libmv/libmv/autotrack/intersect.cc b/intern/libmv/libmv/autotrack/intersect.cc
new file mode 100644
index 0000000..59f0820
--- /dev/null
+++ b/intern/libmv/libmv/autotrack/intersect.cc
@@ -0,0 +1,262 @@
+// Copyright (c) 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>
+
+#include "libmv/autotrack/intersect.h"
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/multiview/triangulation.h"
+#include "libmv/multiview/nviewtriangulation.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+#include "libmv/autotrack/reconstruction.h"
+#include "libmv/autotrack/tracks.h"
+
+#include "ceres/ceres.h"
+
+using libmv::Mat;
+using libmv::Mat34;
+using libmv::Mat2X;
+using libmv::Vec4;
+
+namespace mv {
+
+namespace {
+
+class EuclideanIntersectCostFunctor {
+ public:
+ EuclideanIntersectCostFunctor(const Marker &marker,
+ const CameraPose &camera)
+ : marker_(marker), camera_(camera) {}
+
+ template<typename T>
+ bool operator()(const T *X, T *residuals) const {
+ typedef Eigen::Matrix<T, 3, 3> Mat3;
+ typedef Eigen::Matrix<T, 3, 1> Vec3;
+
+ Vec3 x(X);
+ Mat3 R(camera_.R.cast<T>());
+ Vec3 t(camera_.t.cast<T>());
+
+ Vec3 projected = R * x + t;
+ projected /= projected(2);
+
+ residuals[0] = (T(projected(0)) - T(marker_.center[0])) * T(marker_.weight);
+ residuals[1] = (T(projected(1)) - T(marker_.center[1])) * T(marker_.weight);
+
+ return true;
+ }
+
+ const Marker &marker_;
+ const CameraPose &camera_;
+};
+
+} // namespace
+
+bool EuclideanIntersect(const vector<Marker> &markers,
+ Reconstruction *reconstruction) {
+ if (markers.size() < 2) {
+ return false;
+ }
+
+ // Compute projective camera matrices for the cameras the intersection is
+ // going to use.
+ Mat3 K = Mat3::Identity();
+ vector<Mat34> cameras;
+ Mat34 P;
+ for (int i = 0; i < markers.size(); ++i) {
+ CameraPose *camera = reconstruction->CameraPoseForFrame(markers[i].clip, markers[i].frame);
+ libmv::P_From_KRt(K, camera->R, camera->t, &P);
+ cameras.push_back(P);
+ }
+
+ // Stack the 2D coordinates together as required by NViewTriangulate.
+ Mat2X points(2, markers.size());
+ for (int i = 0; i < markers.size(); ++i) {
+ points(0, i) = markers[i].center[0];
+ points(1, i) = markers[i].center[1];
+ }
+
+ Vec4 Xp;
+ LG << "Intersecting with " << markers.size() << " markers.";
+ libmv::NViewTriangulateAlgebraic(points, cameras, &Xp);
+
+ // Get euclidean version of the homogeneous point.
+ Xp /= Xp(3);
+ Vec3 X = Xp.head<3>();
+
+ 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) {
+ const CameraPose &camera =
+ *reconstruction->CameraPoseForFrame(marker.clip, marker.frame);
+
+ problem.AddResidualBlock(
+ new ceres::AutoDiffCostFunction<
+ EuclideanIntersectCostFunctor,
+ 2, /* num_residuals */
+ 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>();
+ Point mv_point(markers[0].track, point);
+ reconstruction->AddPoint(mv_point);
+
+ return true;
+ }
+
+ // Configure the solve.
+ ceres::Solver::Options solver_options;
+ solver_options.linear_solver_type = ceres::DENSE_QR;
+ solver_options.max_num_iterations = 50;
+ solver_options.update_state_every_iteration = true;
+ solver_options.parameter_tolerance = 1e-16;
+ solver_options.function_tolerance = 1e-16;
+
+ // Run the solve.
+ ceres::Solver::Summary summary;
+ ceres::Solve(solver_options, &problem, &summary);
+
+ VLOG(1) << "Summary:\n" << summary.FullReport();
+
+ // Try projecting the point; make sure it's in front of everyone.
+ for (int i = 0; i < cameras.size(); ++i) {
+ const CameraPose &camera =
+ *reconstruction->CameraPoseForFrame(ma
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list