[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59953] branches/soc-2013-motion_track/ extern/libmv: Code cleanup: keyframe selection explicitly single-camera
Joseph Mansfield
sftrabbit at gmail.com
Mon Sep 9 15:55:24 CEST 2013
Revision: 59953
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59953
Author: sftrabbit
Date: 2013-09-09 13:55:24 +0000 (Mon, 09 Sep 2013)
Log Message:
-----------
Code cleanup: keyframe selection explicitly single-camera
The current keyframe selection algorithm only looks at frames from camera 0 to find two frames with high variance. It's definitely worth looking at algorithms for keyframe selection from multiple cameras - different cameras are likely to have high variance.
Modified Paths:
--------------
branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.h
branches/soc-2013-motion_track/extern/libmv/libmv-capi.cc
Modified: branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
===================================================================
--- branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc 2013-09-09 12:15:16 UTC (rev 59952)
+++ branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc 2013-09-09 13:55:24 UTC (rev 59953)
@@ -288,14 +288,18 @@
}
} // namespace
-void SelectkeyframesBasedOnGRICAndVariance(const Tracks &tracks,
- const CameraIntrinsics &intrinsics,
- vector<int> &keyframes) {
+void SelectkeyframesBasedOnGRICAndVariance(
+ const Tracks &tracks,
+ const std::vector<CameraIntrinsics> &intrinsics,
+ vector<int> &keyframes) {
// Mirza Tahir Ahmed, Matthew N. Dailey
// Robust key frame extraction for 3D reconstruction from video streams
//
// http://www.cs.ait.ac.th/~mdailey/papers/Tahir-KeyFrame.pdf
+ static const int SELECTION_CAMERA = 0;
+ const CameraIntrinsics &selection_intrinsics = intrinsics[SELECTION_CAMERA];
+
int max_image = tracks.MaxImage();
int next_keyframe = 1;
int number_keyframes = 0;
@@ -308,7 +312,7 @@
const double Tmin = 0.8;
const double Tmax = 1.0;
- Mat3 N = IntrinsicsNormalizationMatrix(intrinsics);
+ Mat3 N = IntrinsicsNormalizationMatrix(selection_intrinsics);
Mat3 N_inverse = N.inverse();
double Sc_best = std::numeric_limits<double>::max();
@@ -328,16 +332,16 @@
candidate_image++) {
// Conjunction of all markers from both keyframes
vector<Marker> all_markers =
- tracks.MarkersInBothImages(0, current_keyframe, candidate_image);
+ tracks.MarkersInBothImages(SELECTION_CAMERA, current_keyframe, candidate_image);
// Match keypoints between frames current_keyframe and candidate_image
vector<Marker> tracked_markers =
- tracks.MarkersForTracksInBothImages(0, current_keyframe, candidate_image);
+ tracks.MarkersForTracksInBothImages(SELECTION_CAMERA, current_keyframe, candidate_image);
// Correspondences in normalized space
Mat x1, x2;
- CoordinatesForMarkersInImage(tracked_markers, 0, current_keyframe, &x1);
- CoordinatesForMarkersInImage(tracked_markers, 0, candidate_image, &x2);
+ CoordinatesForMarkersInImage(tracked_markers, SELECTION_CAMERA, current_keyframe, &x1);
+ CoordinatesForMarkersInImage(tracked_markers, SELECTION_CAMERA, candidate_image, &x2);
LG << "Found " << x1.cols()
<< " correspondences between " << current_keyframe
@@ -360,8 +364,8 @@
continue;
Mat3 H, F;
- ComputeHomographyFromCorrespondences(x1, x2, intrinsics, &H);
- ComputeFundamentalFromCorrespondences(x1, x2, intrinsics, &F);
+ ComputeHomographyFromCorrespondences(x1, x2, selection_intrinsics, &H);
+ ComputeFundamentalFromCorrespondences(x1, x2, selection_intrinsics, &F);
// TODO(sergey): STEP 2: Discard outlier matches
@@ -373,9 +377,9 @@
F_e.resize(x1.cols());
for (int i = 0; i < x1.cols(); i++) {
Vec2 current_x1 =
- NorrmalizedToPixelSpace(Vec2(x1(0, i), x1(1, i)), intrinsics);
+ NorrmalizedToPixelSpace(Vec2(x1(0, i), x1(1, i)), selection_intrinsics);
Vec2 current_x2 =
- NorrmalizedToPixelSpace(Vec2(x2(0, i), x2(1, i)), intrinsics);
+ NorrmalizedToPixelSpace(Vec2(x2(0, i), x2(1, i)), selection_intrinsics);
H_e(i) = SymmetricGeometricDistance(H, current_x1, current_x2);
F_e(i) = SymmetricEpipolarDistance(F, current_x1, current_x2);
@@ -442,10 +446,10 @@
<< "\nt:" << t.transpose();
// First camera is identity, second one is relative to it
- reconstruction.InsertView(0, current_keyframe,
+ reconstruction.InsertView(SELECTION_CAMERA, current_keyframe,
Mat3::Identity(),
Vec3::Zero());
- reconstruction.InsertView(0, candidate_image, R, t);
+ reconstruction.InsertView(SELECTION_CAMERA, candidate_image, R, t);
// Reconstruct 3D points
int intersects_total = 0, intersects_success = 0;
Modified: branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.h
===================================================================
--- branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.h 2013-09-09 12:15:16 UTC (rev 59952)
+++ branches/soc-2013-motion_track/extern/libmv/libmv/simple_pipeline/keyframe_selection.h 2013-09-09 13:55:24 UTC (rev 59953)
@@ -21,31 +21,36 @@
#ifndef LIBMV_SIMPLE_PIPELINE_KEYFRAME_SELECTION_H_
#define LIBMV_SIMPLE_PIPELINE_KEYFRAME_SELECTION_H_
+#include <vector>
+
#include "libmv/base/vector.h"
#include "libmv/simple_pipeline/tracks.h"
#include "libmv/simple_pipeline/camera_intrinsics.h"
namespace libmv {
-// Get list of all images which are good enough to be as keyframes from
-// camera reconstruction. Based on GRIC criteria and uses Pollefeys'
+// Get list of all images from camera 0 which are good enough to be as keyframes
+// for camera reconstruction. Based on GRIC criteria and uses Pollefeys'
// approach for correspondence ratio constraint.
//
-// As an additional, additional criteria based on reconstruction
-// variance is used. This means if correspondence and GRIC criteria
-// are passed, two-frames reconstruction using candidate keyframes
-// happens. After reconstruction variance of 3D points is calculating
-// and if expected error estimation is too large, keyframe candidate
-// is rejecting.
+// Additional criteria based on reconstruction variance are used. This means if
+// correspondence and GRIC criteria are passed, two-frame reconstruction using
+// candidate keyframes happens. After reconstruction, the variance of 3D points
+// is calculated and, if the expected error estimation is too large, the keyframe
+// candidate is rejected.
//
// \param tracks contains all tracked correspondences between frames
// expected to be undistorted and normalized
// \param intrinsics is camera intrinsics
// \param keyframes will contain all images number which are considered
// good to be used for reconstruction
-void SelectkeyframesBasedOnGRICAndVariance(const Tracks &tracks,
- const CameraIntrinsics &intrinsics,
- vector<int> &keyframes);
+//
+// TODO(sftrabbit): Use algorithm that finds images of high variance from
+// multiple cameras.
+void SelectkeyframesBasedOnGRICAndVariance(
+ const Tracks &tracks,
+ const std::vector<CameraIntrinsics> &intrinsics,
+ vector<int> &keyframes);
} // namespace libmv
Modified: branches/soc-2013-motion_track/extern/libmv/libmv-capi.cc
===================================================================
--- branches/soc-2013-motion_track/extern/libmv/libmv-capi.cc 2013-09-09 12:15:16 UTC (rev 59952)
+++ branches/soc-2013-motion_track/extern/libmv/libmv-capi.cc 2013-09-09 13:55:24 UTC (rev 59953)
@@ -490,7 +490,7 @@
/* Get list of all keyframe candidates first. */
SelectkeyframesBasedOnGRICAndVariance(normalized_tracks,
- camera_intrinsics[0],
+ camera_intrinsics,
keyframes);
if (keyframes.size() < 2) {
More information about the Bf-blender-cvs
mailing list