Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-01-04 16:22:27 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-01-04 17:39:13 +0300
commitba432299cdd4382130103cf5a84c34693d4a3bdc (patch)
tree8d31ffec1aad8f9216aa1fc7108f494b65f74e7e /extern/libmv/intern/reconstruction.cc
parent6fb6a08bf84d5d16ebac35527a77bec37112494e (diff)
Move Libmv from extern/ to intern/
Logically it is intern library since being mainly developed by 1.5 blender guys.
Diffstat (limited to 'extern/libmv/intern/reconstruction.cc')
-rw-r--r--extern/libmv/intern/reconstruction.cc542
1 files changed, 0 insertions, 542 deletions
diff --git a/extern/libmv/intern/reconstruction.cc b/extern/libmv/intern/reconstruction.cc
deleted file mode 100644
index 046671e467f..00000000000
--- a/extern/libmv/intern/reconstruction.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2011 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- * Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "intern/reconstruction.h"
-#include "intern/camera_intrinsics.h"
-#include "intern/tracks.h"
-#include "intern/utildefines.h"
-
-#include "libmv/logging/logging.h"
-#include "libmv/simple_pipeline/bundle.h"
-#include "libmv/simple_pipeline/keyframe_selection.h"
-#include "libmv/simple_pipeline/initialize_reconstruction.h"
-#include "libmv/simple_pipeline/modal_solver.h"
-#include "libmv/simple_pipeline/pipeline.h"
-#include "libmv/simple_pipeline/reconstruction_scale.h"
-#include "libmv/simple_pipeline/tracks.h"
-
-using libmv::CameraIntrinsics;
-using libmv::EuclideanCamera;
-using libmv::EuclideanPoint;
-using libmv::EuclideanReconstruction;
-using libmv::EuclideanScaleToUnity;
-using libmv::Marker;
-using libmv::ProgressUpdateCallback;
-
-using libmv::PolynomialCameraIntrinsics;
-using libmv::Tracks;
-using libmv::EuclideanBundle;
-using libmv::EuclideanCompleteReconstruction;
-using libmv::EuclideanReconstructTwoFrames;
-using libmv::EuclideanReprojectionError;
-
-struct libmv_Reconstruction {
- EuclideanReconstruction reconstruction;
-
- /* Used for per-track average error calculation after reconstruction */
- Tracks tracks;
- CameraIntrinsics *intrinsics;
-
- double error;
- bool is_valid;
-};
-
-namespace {
-
-class ReconstructUpdateCallback : public ProgressUpdateCallback {
- public:
- ReconstructUpdateCallback(
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata) {
- progress_update_callback_ = progress_update_callback;
- callback_customdata_ = callback_customdata;
- }
-
- void invoke(double progress, const char* message) {
- if (progress_update_callback_) {
- progress_update_callback_(callback_customdata_, progress, message);
- }
- }
- protected:
- reconstruct_progress_update_cb progress_update_callback_;
- void* callback_customdata_;
-};
-
-void libmv_solveRefineIntrinsics(
- const Tracks &tracks,
- const int refine_intrinsics,
- const int bundle_constraints,
- reconstruct_progress_update_cb progress_update_callback,
- void* callback_customdata,
- EuclideanReconstruction* reconstruction,
- CameraIntrinsics* intrinsics) {
- /* only a few combinations are supported but trust the caller/ */
- int bundle_intrinsics = 0;
-
- if (refine_intrinsics & LIBMV_REFINE_FOCAL_LENGTH) {
- bundle_intrinsics |= libmv::BUNDLE_FOCAL_LENGTH;
- }
- if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) {
- bundle_intrinsics |= libmv::BUNDLE_PRINCIPAL_POINT;
- }
- if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K1) {
- bundle_intrinsics |= libmv::BUNDLE_RADIAL_K1;
- }
- if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) {
- bundle_intrinsics |= libmv::BUNDLE_RADIAL_K2;
- }
-
- progress_update_callback(callback_customdata, 1.0, "Refining solution");
-
- EuclideanBundleCommonIntrinsics(tracks,
- bundle_intrinsics,
- bundle_constraints,
- reconstruction,
- intrinsics);
-}
-
-void finishReconstruction(
- const Tracks &tracks,
- const CameraIntrinsics &camera_intrinsics,
- libmv_Reconstruction *libmv_reconstruction,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata) {
- EuclideanReconstruction &reconstruction =
- libmv_reconstruction->reconstruction;
-
- /* Reprojection error calculation. */
- progress_update_callback(callback_customdata, 1.0, "Finishing solution");
- libmv_reconstruction->tracks = tracks;
- libmv_reconstruction->error = EuclideanReprojectionError(tracks,
- reconstruction,
- camera_intrinsics);
-}
-
-bool selectTwoKeyframesBasedOnGRICAndVariance(
- Tracks& tracks,
- Tracks& normalized_tracks,
- CameraIntrinsics& camera_intrinsics,
- int& keyframe1,
- int& keyframe2) {
- libmv::vector<int> keyframes;
-
- /* Get list of all keyframe candidates first. */
- SelectKeyframesBasedOnGRICAndVariance(normalized_tracks,
- camera_intrinsics,
- keyframes);
-
- if (keyframes.size() < 2) {
- LG << "Not enough keyframes detected by GRIC";
- return false;
- } else if (keyframes.size() == 2) {
- keyframe1 = keyframes[0];
- keyframe2 = keyframes[1];
- return true;
- }
-
- /* Now choose two keyframes with minimal reprojection error after initial
- * reconstruction choose keyframes with the least reprojection error after
- * solving from two candidate keyframes.
- *
- * In fact, currently libmv returns single pair only, so this code will
- * not actually run. But in the future this could change, so let's stay
- * prepared.
- */
- int previous_keyframe = keyframes[0];
- double best_error = std::numeric_limits<double>::max();
- for (int i = 1; i < keyframes.size(); i++) {
- EuclideanReconstruction reconstruction;
- int current_keyframe = keyframes[i];
- libmv::vector<Marker> keyframe_markers =
- normalized_tracks.MarkersForTracksInBothImages(previous_keyframe,
- current_keyframe);
-
- Tracks keyframe_tracks(keyframe_markers);
-
- /* get a solution from two keyframes only */
- EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- EuclideanBundle(keyframe_tracks, &reconstruction);
- EuclideanCompleteReconstruction(keyframe_tracks,
- &reconstruction,
- NULL);
-
- double current_error = EuclideanReprojectionError(tracks,
- reconstruction,
- camera_intrinsics);
-
- LG << "Error between " << previous_keyframe
- << " and " << current_keyframe
- << ": " << current_error;
-
- if (current_error < best_error) {
- best_error = current_error;
- keyframe1 = previous_keyframe;
- keyframe2 = current_keyframe;
- }
-
- previous_keyframe = current_keyframe;
- }
-
- return true;
-}
-
-Marker libmv_projectMarker(const EuclideanPoint& point,
- const EuclideanCamera& camera,
- const CameraIntrinsics& intrinsics) {
- libmv::Vec3 projected = camera.R * point.X + camera.t;
- projected /= projected(2);
-
- libmv::Marker reprojected_marker;
- intrinsics.ApplyIntrinsics(projected(0), projected(1),
- &reprojected_marker.x,
- &reprojected_marker.y);
-
- reprojected_marker.image = camera.image;
- reprojected_marker.track = point.track;
- return reprojected_marker;
-}
-
-void libmv_getNormalizedTracks(const Tracks &tracks,
- const CameraIntrinsics &camera_intrinsics,
- Tracks *normalized_tracks) {
- libmv::vector<Marker> markers = tracks.AllMarkers();
- for (int i = 0; i < markers.size(); ++i) {
- Marker &marker = markers[i];
- camera_intrinsics.InvertIntrinsics(marker.x, marker.y,
- &marker.x, &marker.y);
- normalized_tracks->Insert(marker.image,
- marker.track,
- marker.x, marker.y,
- marker.weight);
- }
-}
-
-} // namespace
-
-libmv_Reconstruction *libmv_solveReconstruction(
- const libmv_Tracks* libmv_tracks,
- const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
- libmv_ReconstructionOptions* libmv_reconstruction_options,
- reconstruct_progress_update_cb progress_update_callback,
- void* callback_customdata) {
- libmv_Reconstruction *libmv_reconstruction =
- LIBMV_OBJECT_NEW(libmv_Reconstruction);
-
- Tracks &tracks = *((Tracks *) libmv_tracks);
- EuclideanReconstruction &reconstruction =
- libmv_reconstruction->reconstruction;
-
- ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback,
- callback_customdata);
-
- /* Retrieve reconstruction options from C-API to libmv API. */
- CameraIntrinsics *camera_intrinsics;
- camera_intrinsics = libmv_reconstruction->intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
- /* Invert the camera intrinsics/ */
- Tracks normalized_tracks;
- libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
-
- /* keyframe selection. */
- int keyframe1 = libmv_reconstruction_options->keyframe1,
- keyframe2 = libmv_reconstruction_options->keyframe2;
-
- if (libmv_reconstruction_options->select_keyframes) {
- LG << "Using automatic keyframe selection";
-
- update_callback.invoke(0, "Selecting keyframes");
-
- selectTwoKeyframesBasedOnGRICAndVariance(tracks,
- normalized_tracks,
- *camera_intrinsics,
- keyframe1,
- keyframe2);
-
- /* so keyframes in the interface would be updated */
- libmv_reconstruction_options->keyframe1 = keyframe1;
- libmv_reconstruction_options->keyframe2 = keyframe2;
- }
-
- /* Actual reconstruction. */
- LG << "frames to init from: " << keyframe1 << " " << keyframe2;
-
- libmv::vector<Marker> keyframe_markers =
- normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
-
- LG << "number of markers for init: " << keyframe_markers.size();
-
- if (keyframe_markers.size() < 8) {
- LG << "No enough markers to initialize from";
- libmv_reconstruction->is_valid = false;
- return libmv_reconstruction;
- }
-
- update_callback.invoke(0, "Initial reconstruction");
-
- EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- EuclideanBundle(normalized_tracks, &reconstruction);
- EuclideanCompleteReconstruction(normalized_tracks,
- &reconstruction,
- &update_callback);
-
- /* Refinement/ */
- if (libmv_reconstruction_options->refine_intrinsics) {
- libmv_solveRefineIntrinsics(
- tracks,
- libmv_reconstruction_options->refine_intrinsics,
- libmv::BUNDLE_NO_CONSTRAINTS,
- progress_update_callback,
- callback_customdata,
- &reconstruction,
- camera_intrinsics);
- }
-
- /* Set reconstruction scale to unity. */
- EuclideanScaleToUnity(&reconstruction);
-
- /* Finish reconstruction. */
- finishReconstruction(tracks,
- *camera_intrinsics,
- libmv_reconstruction,
- progress_update_callback,
- callback_customdata);
-
- libmv_reconstruction->is_valid = true;
- return (libmv_Reconstruction *) libmv_reconstruction;
-}
-
-libmv_Reconstruction *libmv_solveModal(
- const libmv_Tracks *libmv_tracks,
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- const libmv_ReconstructionOptions *libmv_reconstruction_options,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata) {
- libmv_Reconstruction *libmv_reconstruction =
- LIBMV_OBJECT_NEW(libmv_Reconstruction);
-
- Tracks &tracks = *((Tracks *) libmv_tracks);
- EuclideanReconstruction &reconstruction =
- libmv_reconstruction->reconstruction;
-
- ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback,
- callback_customdata);
-
- /* Retrieve reconstruction options from C-API to libmv API. */
- CameraIntrinsics *camera_intrinsics;
- camera_intrinsics = libmv_reconstruction->intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(
- libmv_camera_intrinsics_options);
-
- /* Invert the camera intrinsics. */
- Tracks normalized_tracks;
- libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
-
- /* Actual reconstruction. */
- ModalSolver(normalized_tracks, &reconstruction, &update_callback);
-
- PolynomialCameraIntrinsics empty_intrinsics;
- EuclideanBundleCommonIntrinsics(normalized_tracks,
- libmv::BUNDLE_NO_INTRINSICS,
- libmv::BUNDLE_NO_TRANSLATION,
- &reconstruction,
- &empty_intrinsics);
-
- /* Refinement. */
- if (libmv_reconstruction_options->refine_intrinsics) {
- libmv_solveRefineIntrinsics(
- tracks,
- libmv_reconstruction_options->refine_intrinsics,
- libmv::BUNDLE_NO_TRANSLATION,
- progress_update_callback, callback_customdata,
- &reconstruction,
- camera_intrinsics);
- }
-
- /* Finish reconstruction. */
- finishReconstruction(tracks,
- *camera_intrinsics,
- libmv_reconstruction,
- progress_update_callback,
- callback_customdata);
-
- libmv_reconstruction->is_valid = true;
- return (libmv_Reconstruction *) libmv_reconstruction;
-}
-
-int libmv_reconstructionIsValid(libmv_Reconstruction *libmv_reconstruction) {
- return libmv_reconstruction->is_valid;
-}
-
-void libmv_reconstructionDestroy(libmv_Reconstruction *libmv_reconstruction) {
- LIBMV_OBJECT_DELETE(libmv_reconstruction->intrinsics, CameraIntrinsics);
- LIBMV_OBJECT_DELETE(libmv_reconstruction, libmv_Reconstruction);
-}
-
-int libmv_reprojectionPointForTrack(
- const libmv_Reconstruction *libmv_reconstruction,
- int track,
- double pos[3]) {
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const EuclideanPoint *point =
- reconstruction->PointForTrack(track);
- if (point) {
- pos[0] = point->X[0];
- pos[1] = point->X[2];
- pos[2] = point->X[1];
- return 1;
- }
- return 0;
-}
-
-double libmv_reprojectionErrorForTrack(
- const libmv_Reconstruction *libmv_reconstruction,
- int track) {
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const CameraIntrinsics *intrinsics = libmv_reconstruction->intrinsics;
- libmv::vector<Marker> markers =
- libmv_reconstruction->tracks.MarkersForTrack(track);
-
- int num_reprojected = 0;
- double total_error = 0.0;
-
- for (int i = 0; i < markers.size(); ++i) {
- double weight = markers[i].weight;
- const EuclideanCamera *camera =
- reconstruction->CameraForImage(markers[i].image);
- const EuclideanPoint *point =
- reconstruction->PointForTrack(markers[i].track);
-
- if (!camera || !point || weight == 0.0) {
- continue;
- }
-
- num_reprojected++;
-
- Marker reprojected_marker =
- libmv_projectMarker(*point, *camera, *intrinsics);
- double ex = (reprojected_marker.x - markers[i].x) * weight;
- double ey = (reprojected_marker.y - markers[i].y) * weight;
-
- total_error += sqrt(ex * ex + ey * ey);
- }
-
- return total_error / num_reprojected;
-}
-
-double libmv_reprojectionErrorForImage(
- const libmv_Reconstruction *libmv_reconstruction,
- int image) {
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const CameraIntrinsics *intrinsics = libmv_reconstruction->intrinsics;
- libmv::vector<Marker> markers =
- libmv_reconstruction->tracks.MarkersInImage(image);
- const EuclideanCamera *camera = reconstruction->CameraForImage(image);
- int num_reprojected = 0;
- double total_error = 0.0;
-
- if (!camera) {
- return 0.0;
- }
-
- for (int i = 0; i < markers.size(); ++i) {
- const EuclideanPoint *point =
- reconstruction->PointForTrack(markers[i].track);
-
- if (!point) {
- continue;
- }
-
- num_reprojected++;
-
- Marker reprojected_marker =
- libmv_projectMarker(*point, *camera, *intrinsics);
- double ex = (reprojected_marker.x - markers[i].x) * markers[i].weight;
- double ey = (reprojected_marker.y - markers[i].y) * markers[i].weight;
-
- total_error += sqrt(ex * ex + ey * ey);
- }
-
- return total_error / num_reprojected;
-}
-
-int libmv_reprojectionCameraForImage(
- const libmv_Reconstruction *libmv_reconstruction,
- int image,
- double mat[4][4]) {
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const EuclideanCamera *camera =
- reconstruction->CameraForImage(image);
-
- if (camera) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 3; ++k) {
- int l = k;
-
- if (k == 1) {
- l = 2;
- } else if (k == 2) {
- l = 1;
- }
-
- if (j == 2) {
- mat[j][l] = -camera->R(j, k);
- } else {
- mat[j][l] = camera->R(j, k);
- }
- }
- mat[j][3] = 0.0;
- }
-
- libmv::Vec3 optical_center = -camera->R.transpose() * camera->t;
-
- mat[3][0] = optical_center(0);
- mat[3][1] = optical_center(2);
- mat[3][2] = optical_center(1);
-
- mat[3][3] = 1.0;
-
- return 1;
- }
-
- return 0;
-}
-
-double libmv_reprojectionError(
- const libmv_Reconstruction *libmv_reconstruction) {
- return libmv_reconstruction->error;
-}
-
-libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
- libmv_Reconstruction *libmv_reconstruction) {
- return (libmv_CameraIntrinsics *) libmv_reconstruction->intrinsics;
-}