diff options
Diffstat (limited to 'extern')
-rw-r--r-- | extern/libmv/CMakeLists.txt | 2 | ||||
-rw-r--r-- | extern/libmv/ChangeLog | 19 | ||||
-rw-r--r-- | extern/libmv/files.txt | 2 | ||||
-rw-r--r-- | extern/libmv/libmv-capi.cpp | 79 | ||||
-rw-r--r-- | extern/libmv/libmv-capi.h | 3 | ||||
-rw-r--r-- | extern/libmv/libmv/simple_pipeline/modal_solver.cc | 126 | ||||
-rw-r--r-- | extern/libmv/libmv/simple_pipeline/modal_solver.h | 48 |
7 files changed, 256 insertions, 23 deletions
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 02723b64b62..6be813883ec 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -69,6 +69,7 @@ set(SRC libmv/simple_pipeline/detect.cc libmv/simple_pipeline/initialize_reconstruction.cc libmv/simple_pipeline/intersect.cc + libmv/simple_pipeline/modal_solver.cc libmv/simple_pipeline/pipeline.cc libmv/simple_pipeline/reconstruction.cc libmv/simple_pipeline/resect.cc @@ -126,6 +127,7 @@ set(SRC libmv/simple_pipeline/detect.h libmv/simple_pipeline/initialize_reconstruction.h libmv/simple_pipeline/intersect.h + libmv/simple_pipeline/modal_solver.h libmv/simple_pipeline/pipeline.h libmv/simple_pipeline/reconstruction.h libmv/simple_pipeline/resect.h diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog index 33068bddf90..7248e4c9cd9 100644 --- a/extern/libmv/ChangeLog +++ b/extern/libmv/ChangeLog @@ -1,3 +1,16 @@ +commit a44312a7beb2963b8e3bf8015c516d2eff40cc3d +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Apr 12 13:56:02 2012 +0600 + + Added solver for modal camera motion, currently supports only tripod solving + + This solver is intended to deal with such camera motions as tripod and panning, + where it's impossible to reconstruct exact position of markers in 3d view. + + It projects markers onto sphere and uses rigid registration of rotation to + find rotation angles which makes bundles from previous and current frame be + as closest as it's possible. + commit fa3842e472e3b9c789e47bf6d8f592aa40a84f16 Author: Sergey Sharybin <sergey.vfx@gmail.com> Date: Thu Apr 12 12:32:48 2012 +0600 @@ -520,9 +533,3 @@ Author: Matthias Fauconneau <matthias.fauconneau@gmail.com> Date: Fri Aug 19 16:04:37 2011 +0200 MSVC compatibility: heap allocate pattern, explicit float cast. - -commit 702658d2f8616964a6eeb3743fd85e97ac7ff09d -Author: Matthias Fauconneau <matthias.fauconneau@gmail.com> -Date: Fri Aug 19 14:59:24 2011 +0200 - - Expose regularization parameters (areaPenalty and conditionPenalty) in API. diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt index 1e564d3a2f2..85d09ce05b8 100644 --- a/extern/libmv/files.txt +++ b/extern/libmv/files.txt @@ -42,6 +42,8 @@ libmv/simple_pipeline/initialize_reconstruction.cc libmv/simple_pipeline/initialize_reconstruction.h libmv/simple_pipeline/intersect.cc libmv/simple_pipeline/intersect.h +libmv/simple_pipeline/modal_solver.cc +libmv/simple_pipeline/modal_solver.h libmv/simple_pipeline/pipeline.cc libmv/simple_pipeline/pipeline.h libmv/simple_pipeline/reconstruction.cc diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index e4708e5907d..6c20d76eeac 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -54,6 +54,7 @@ #include "libmv/simple_pipeline/pipeline.h" #include "libmv/simple_pipeline/camera_intrinsics.h" #include "libmv/simple_pipeline/rigid_registration.h" +#include "libmv/simple_pipeline/modal_solver.h" #include <stdlib.h> #include <assert.h> @@ -384,6 +385,31 @@ int libmv_refineParametersAreValid(int parameters) { LIBMV_REFINE_RADIAL_DISTORTION_K1)); } +void libmv_solveRefineIntrinsics(libmv::Tracks *tracks, libmv::CameraIntrinsics *intrinsics, + libmv::EuclideanReconstruction *reconstruction, int refine_intrinsics, + reconstruct_progress_update_cb progress_update_callback, void *callback_customdata) +{ + /* only a few combinations are supported but trust the caller */ + int libmv_refine_flags = 0; + + if (refine_intrinsics & LIBMV_REFINE_FOCAL_LENGTH) { + libmv_refine_flags |= libmv::BUNDLE_FOCAL_LENGTH; + } + if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) { + libmv_refine_flags |= libmv::BUNDLE_PRINCIPAL_POINT; + } + if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K1) { + libmv_refine_flags |= libmv::BUNDLE_RADIAL_K1; + } + if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) { + libmv_refine_flags |= libmv::BUNDLE_RADIAL_K2; + } + + progress_update_callback(callback_customdata, 1.0, "Refining solution"); + + libmv::EuclideanBundleCommonIntrinsics(*(libmv::Tracks *)tracks, libmv_refine_flags, + reconstruction, intrinsics); +} libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyframe1, int keyframe2, int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, @@ -423,26 +449,45 @@ libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyfra libmv::EuclideanCompleteReconstruction(normalized_tracks, reconstruction, &update_callback); if (refine_intrinsics) { - /* only a few combinations are supported but trust the caller */ - int libmv_refine_flags = 0; - if (refine_intrinsics & LIBMV_REFINE_FOCAL_LENGTH) { - libmv_refine_flags |= libmv::BUNDLE_FOCAL_LENGTH; - } - if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) { - libmv_refine_flags |= libmv::BUNDLE_PRINCIPAL_POINT; - } - if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K1) { - libmv_refine_flags |= libmv::BUNDLE_RADIAL_K1; - } - if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) { - libmv_refine_flags |= libmv::BUNDLE_RADIAL_K2; - } + libmv_solveRefineIntrinsics((libmv::Tracks *)tracks, intrinsics, reconstruction, + refine_intrinsics, progress_update_callback, callback_customdata); + } - progress_update_callback(callback_customdata, 1.0, "Refining solution"); - libmv::EuclideanBundleCommonIntrinsics(*(libmv::Tracks *)tracks, libmv_refine_flags, - reconstruction, intrinsics); + progress_update_callback(callback_customdata, 1.0, "Finishing solution"); + libmv_reconstruction->tracks = *(libmv::Tracks *)tracks; + libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics); + + return (libmv_Reconstruction *)libmv_reconstruction; +} + +struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, double focal_length, + double principal_x, double principal_y, double k1, double k2, double k3, + reconstruct_progress_update_cb progress_update_callback, void *callback_customdata) +{ + /* Invert the camera intrinsics. */ + libmv::vector<libmv::Marker> markers = ((libmv::Tracks*)tracks)->AllMarkers(); + libmv_Reconstruction *libmv_reconstruction = new libmv_Reconstruction(); + libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction; + libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics; + + ReconstructUpdateCallback update_callback = + ReconstructUpdateCallback(progress_update_callback, callback_customdata); + + intrinsics->SetFocalLength(focal_length, focal_length); + intrinsics->SetPrincipalPoint(principal_x, principal_y); + intrinsics->SetRadialDistortion(k1, k2, k3); + + for (int i = 0; i < markers.size(); ++i) { + intrinsics->InvertIntrinsics(markers[i].x, + markers[i].y, + &(markers[i].x), + &(markers[i].y)); } + libmv::Tracks normalized_tracks(markers); + + libmv::ModalSolver(normalized_tracks, reconstruction, &update_callback); + progress_update_callback(callback_customdata, 1.0, "Finishing solution"); libmv_reconstruction->tracks = *(libmv::Tracks *)tracks; libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics); diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index 01019832374..bccc4706832 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -68,6 +68,9 @@ int libmv_refineParametersAreValid(int parameters); struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2, int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, reconstruct_progress_update_cb progress_update_callback, void *callback_customdata); +struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *tracks, double focal_length, + double principal_x, double principal_y, double k1, double k2, double k3, + reconstruct_progress_update_cb progress_update_callback, void *callback_customdata); int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]); double libmv_reporojectionErrorForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track); double libmv_reporojectionErrorForImage(struct libmv_Reconstruction *libmv_reconstruction, int image); diff --git a/extern/libmv/libmv/simple_pipeline/modal_solver.cc b/extern/libmv/libmv/simple_pipeline/modal_solver.cc new file mode 100644 index 00000000000..bb49b30dbce --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/modal_solver.cc @@ -0,0 +1,126 @@ +// 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 <cstdio> + +#include "libmv/logging/logging.h" +#include "libmv/simple_pipeline/modal_solver.h" +#include "libmv/simple_pipeline/rigid_registration.h" + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +namespace libmv { + +static void ProjectMarkerOnSphere(Marker &marker, Vec3 &X) { + X(0) = marker.x; + X(1) = marker.y; + X(2) = 1.0; + + X *= 5.0 / X.norm(); +} + +static void ModalSolverLogProress(ProgressUpdateCallback *update_callback, + double progress) +{ + if (update_callback) { + char message[256]; + + snprintf(message, sizeof(message), "Solving progress %d%%", (int)(progress * 100)); + + update_callback->invoke(progress, message); + } +} + +void ModalSolver(Tracks &tracks, + EuclideanReconstruction *reconstruction, + ProgressUpdateCallback *update_callback) { + int max_image = tracks.MaxImage(); + int max_track = tracks.MaxTrack(); + + LG << "Max image: " << max_image; + LG << "Max track: " << max_track; + + Mat3 R = Mat3::Identity(); + + for (int image = 0; image <= max_image; ++image) { + vector<Marker> all_markers = tracks.MarkersInImage(image); + + ModalSolverLogProress(update_callback, (float) image / max_image); + + // Skip empty frames without doing anything + if (all_markers.size() == 0) { + LG << "Skipping frame: " << image; + continue; + } + + vector<Vec3> points, reference_points; + + // Cnstruct pairs of markers from current and previous image, + // to reproject them and find rigid transformation between + // previous and current image + for (int track = 0; track <= max_track; ++track) { + EuclideanPoint *point = reconstruction->PointForTrack(track); + + if (point) { + Marker marker = tracks.MarkerInImageForTrack(image, track); + + if (marker.image == image) { + Vec3 X; + + LG << "Use track " << track << " for rigid registration between image " << + image - 1 << " and " << image; + + ProjectMarkerOnSphere(marker, X); + + points.push_back(point->X); + reference_points.push_back(X); + } + } + } + + if (points.size()) { + // Find rigid delta transformation to current image + RigidRegistration(reference_points, points, R); + } + + reconstruction->InsertCamera(image, R, Vec3::Zero()); + + // Review if there's new tracks for which position might be reconstructed + for (int track = 0; track <= max_track; ++track) { + if (!reconstruction->PointForTrack(track)) { + Marker marker = tracks.MarkerInImageForTrack(image, track); + + if (marker.image == image) { + // New track appeared on this image, project it's position onto sphere + + LG << "Projecting track " << track << " at image " << image; + + Vec3 X; + ProjectMarkerOnSphere(marker, X); + reconstruction->InsertPoint(track, R.inverse() * X); + } + } + } + } +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/modal_solver.h b/extern/libmv/libmv/simple_pipeline/modal_solver.h new file mode 100644 index 00000000000..560b37c2987 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/modal_solver.h @@ -0,0 +1,48 @@ +// 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. + +#ifndef LIBMV_SIMPLE_PIPELINE_MODAL_SOLVER_H_ +#define LIBMV_SIMPLE_PIPELINE_MODAL_SOLVER_H_ + +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/callbacks.h" + +namespace libmv { + +/*! + This solver solves such camera motion as tripod rotation, reconstructing + only camera motion itself. Bundles are not reconstructing properly, they're + just getting projected onto sphere. + + Markers from tracks object would be used for recosntruction, and algorithm + assumes thir's positions are undistorted already and they're in nnormalized + space. + + Reconstructed cameras and projected bundles would be added to reconstruction + object. +*/ +void ModalSolver(Tracks &tracks, + EuclideanReconstruction *reconstruction, + ProgressUpdateCallback *update_callback = NULL); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_MODAL_SOLVER_H_ |