[Bf-blender-cvs] [a17ef5f] soc-2016-multiview: at the point where two-view bundle is returned

Tianwei Shen noreply at git.blender.org
Wed Jun 22 11:49:44 CEST 2016


Commit: a17ef5f9fe2d6250c7fa6c1d51920621269f4725
Author: Tianwei Shen
Date:   Wed Jun 22 15:27:17 2016 +0800
Branches: soc-2016-multiview
https://developer.blender.org/rBa17ef5f9fe2d6250c7fa6c1d51920621269f4725

at the point where two-view bundle is returned

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

M	intern/libmv/intern/reconstructionN.cc
M	intern/libmv/libmv/autotrack/bundle.cc
M	intern/libmv/libmv/autotrack/reconstruction.cc
M	intern/libmv/libmv/autotrack/reconstruction.h
M	intern/libmv/libmv/autotrack/tracks.cc
M	intern/libmv/libmv/autotrack/tracks.h

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

diff --git a/intern/libmv/intern/reconstructionN.cc b/intern/libmv/intern/reconstructionN.cc
index 1ceeec5..8f1cfe0 100644
--- a/intern/libmv/intern/reconstructionN.cc
+++ b/intern/libmv/intern/reconstructionN.cc
@@ -122,6 +122,7 @@ libmv_ReconstructionN** libmv_solveMultiviewReconstruction(
 	int keyframe1, keyframe2;
 
 	Tracks all_normalized_tracks;	// normalized tracks of all clips
+	all_normalized_tracks.SetClipNum(clip_num);
 	for(int i = 0; i < clip_num; i++)
 	{
 		all_libmv_reconstruction[i] = LIBMV_OBJECT_NEW(libmv_ReconstructionN);
@@ -147,7 +148,6 @@ libmv_ReconstructionN** libmv_solveMultiviewReconstruction(
 	}
 	// make reconstrution on the primary clip reconstruction
 	Reconstruction &reconstruction = all_libmv_reconstruction[0]->reconstruction;
-	printf("all pose num %d\n", reconstruction.GetAllPoseNum());
 
 	printf("frames to init from: %d %d\n", keyframe1, keyframe2);
 	printf("number of markers for init: %d\n", keyframe_markers.size());
@@ -190,6 +190,7 @@ libmv_ReconstructionN** libmv_solveMultiviewReconstruction(
 		all_libmv_reconstruction[0]->is_valid = false;
 		return all_libmv_reconstruction;
 	}
+	// bundle the two-view initial reconstruction
 	if(!mv::EuclideanBundleAll(all_normalized_tracks, &reconstruction))
 	{
 		printf("mv::EuclideanBundleAll failed\n");
diff --git a/intern/libmv/libmv/autotrack/bundle.cc b/intern/libmv/libmv/autotrack/bundle.cc
index 35aa3f4..5034258 100644
--- a/intern/libmv/libmv/autotrack/bundle.cc
+++ b/intern/libmv/libmv/autotrack/bundle.cc
@@ -235,32 +235,43 @@ void UnpackIntrinsicsFromArray(const double ceres_intrinsics[OFFSET_MAX],
   }
 }
 
-//// Get a vector of camera's rotations denoted by angle axis
-//// conjuncted with translations into single block
-////
-//// Element with index i matches to a rotation+translation for
-//// camera at image i.
-//vector<Vec6> PackCamerasRotationAndTranslation(
-//    const Tracks &tracks,
-//    const Reconstruction &reconstruction) {
-//  vector<Vec6> all_cameras_R_t;
-//  int max_image = tracks.MaxImage();
-//
-//  all_cameras_R_t.resize(max_image + 1);
-//
-//  for (int i = 0; i <= max_image; i++) {
-//    const EuclideanCamera *camera = reconstruction.CameraForImage(i);
-//
-//    if (!camera) {
-//      continue;
-//    }
-//
-//    ceres::RotationMatrixToAngleAxis(&camera->R(0, 0),
-//                                     &all_cameras_R_t[i](0));
-//    all_cameras_R_t[i].tail<3>() = camera->t;
-//  }
-//  return all_cameras_R_t;
-//}
+// Get a vector of camera's rotations denoted by angle axis
+// conjuncted with translations into single block. Since we use clip and frame
+// to access a camera pose, this function saves the (clip, frame)->global_index
+// map in camera_pose_map
+vector<Vec6> PackMultiCamerasRotationAndTranslation(
+        const Tracks &tracks,
+        const Reconstruction &reconstruction,
+        vector<vector<int> > &camera_pose_map)  {
+	vector<Vec6> all_cameras_R_t;
+	int clip_num = tracks.GetClipNum();
+	camera_pose_map.resize(clip_num);
+	int total_frame = 0;
+	for(int i = 0; i < clip_num; i++) {
+		total_frame += tracks.MaxFrame(i) + 1;
+		camera_pose_map[i].resize(tracks.MaxFrame(i) + 1);
+	}
+	printf("total frame: %d\n", total_frame);
+
+	all_cameras_R_t.resize(total_frame);	// maximum possible number of camera poses
+
+	int frame_count = 0;
+	for(int i = 0; i < clip_num; i++) {
+		int max_frame = tracks.MaxFrame(i);
+		for(int j = 0; j <= max_frame; j++) {
+			const CameraPose *camera = reconstruction.CameraPoseForFrame(i, j);
+			if (!camera)
+				continue;
+			ceres::RotationMatrixToAngleAxis(&camera->R(0, 0),
+			                                 &all_cameras_R_t[frame_count](0));
+			        all_cameras_R_t[frame_count].tail<3>() = camera->t;
+			camera_pose_map[i][j] = frame_count;	// save the global map
+			frame_count++;
+		}
+	}
+
+	return all_cameras_R_t;
+}
 
 //// Convert cameras rotations fro mangle axis back to rotation matrix.
 //void UnpackCamerasRotationAndTranslation(
@@ -471,82 +482,84 @@ void EuclideanBundleCommonIntrinsics(
   double ceres_intrinsics[OFFSET_MAX];
   PackIntrinisicsIntoArray(*intrinsics, ceres_intrinsics);
 
-//  // Convert cameras rotations to angle axis and merge with translation
-//  // into single parameter block for maximal minimization speed.
-//  //
-//  // Block for minimization has got the following structure:
-//  //   <3 elements for angle-axis> <3 elements for translation>
-//  vector<Vec6> all_cameras_R_t =
-//    PackCamerasRotationAndTranslation(tracks, *reconstruction);
-//
-//  // Parameterization used to restrict camera motion for modal solvers.
-//  ceres::SubsetParameterization *constant_translation_parameterization = NULL;
-//  if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
-//      std::vector<int> constant_translation;
-//
-//      // First three elements are rotation, ast three are translation.
-//      constant_translation.push_back(3);
-//      constant_translation.push_back(4);
-//      constant_translation.push_back(5);
-//
-//      constant_translation_parameterization =
-//        new ceres::SubsetParameterization(6, constant_translation);
-//  }
-//
-//  // Add residual blocks to the problem.
-//  ceres::Problem::Options problem_options;
-//  ceres::Problem problem(problem_options);
-//  int num_residuals = 0;
-//  bool have_locked_camera = false;
-//  for (int i = 0; i < markers.size(); ++i) {
-//    const Marker &marker = markers[i];
-//    EuclideanCamera *camera = reconstruction->CameraForImage(marker.image);
-//    EuclideanPoint *point = reconstruction->PointForTrack(marker.track);
-//    if (camera == NULL || point == NULL) {
-//      continue;
-//    }
-//
-//    // Rotation of camera denoted in angle axis followed with
-//    // camera translaiton.
-//    double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
-//
-//    // Skip residual block for markers which does have absolutely
-//    // no affect on the final solution.
-//    // This way ceres is not gonna to go crazy.
-//    if (marker.weight != 0.0) {
-//      problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
-//          OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>(
-//              new OpenCVReprojectionError(
-//                  intrinsics->GetDistortionModelType(),
-//                  marker.x,
-//                  marker.y,
-//                  marker.weight)),
-//          NULL,
-//          ceres_intrinsics,
-//          current_camera_R_t,
-//          &point->X(0));
-//
-//      // We lock the first camera to better deal with scene orientation ambiguity.
-//      if (!have_locked_camera) {
-//        problem.SetParameterBlockConstant(current_camera_R_t);
-//        have_locked_camera = true;
-//      }
-//
-//      if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
-//        problem.SetParameterization(current_camera_R_t,
-//                                    constant_translation_parameterization);
-//      }
-//
-//      zero_weight_tracks_flags[marker.track] = false;
-//      num_residuals++;
-//    }
-//  }
-//  LG << "Number of residuals: " << num_residuals;
-//
-//  if (!num_residuals) {
-//    LG << "Skipping running minimizer with zero residuals";
-//    return;
-//  }
+  // Convert cameras rotations to angle axis and merge with translation
+  // into single parameter block for maximal minimization speed.
+  //
+  // Block for minimization has got the following structure:
+  //   <3 elements for angle-axis> <3 elements for translation>
+  vector<vector<int> > camera_pose_map;
+  vector<Vec6> all_cameras_R_t =
+    PackMultiCamerasRotationAndTranslation(tracks, *reconstruction, camera_pose_map);
+
+  // Parameterization used to restrict camera motion for modal solvers.
+  // TODO(tianwei): haven't think about modal solvers, leave it for now
+  ceres::SubsetParameterization *constant_translation_parameterization = NULL;
+  if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
+      std::vector<int> constant_translation;
+
+      // First three elements are rotation, last three are translation.
+      constant_translation.push_back(3);
+      constant_translation.push_back(4);
+      constant_translation.push_back(5);
+
+      constant_translation_parameterization =
+        new ceres::SubsetParameterization(6, constant_translation);
+  }
+
+  // Add residual blocks to the problem.
+  ceres::Problem::Options problem_options;
+  ceres::Problem problem(problem_options);
+  int num_residuals = 0;
+  bool have_locked_camera = false;
+  for (int i = 0; i < markers.size(); ++i) {
+    const Marker &marker = markers[i];
+    CameraPose *camera = reconstruction->CameraPoseForFrame(marker.clip, marker.frame);
+    Point *point = reconstruction->PointForTrack(marker.track);
+    if (camera == NULL || point == NULL) {
+      continue;
+    }
+
+    // Rotation of camera denoted in angle axis followed with
+    // camera translaiton.
+    double *current_camera_R_t = &all_cameras_R_t[camera_pose_map[marker.clip][marker.frame]](0);
+
+    // Skip residual block for markers which does have absolutely
+    // no affect on the final solution.
+    // This way ceres is not gonna to go crazy.
+    if (marker.weight != 0.0) {
+      problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
+          OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>(
+              new OpenCVReprojectionError(
+                  intrinsics->GetDistortionModelType(),
+                  marker.center[0],
+                  marker.center[1],
+                  marker.weight)),
+          NULL,
+          ceres_intrinsics,
+          current_camera_R_t,
+          &point->X(0));
+
+      // lock the first camera to deal with scene orientation ambiguity.
+      if (!have_locked_camera) {
+        problem.SetParameterBlockConstant(current_camera_R_t);
+        have_locked_camera = true;
+      }
+
+      if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
+        problem.SetParameterization(current_camera_R_t,
+                                    constant_translation_parameterization);
+      }
+
+      zero_weight_tracks_flags[marker.track] = false;
+      num_residuals++;
+    }
+  }
+  LG << "Number of residuals: " << num_residuals;
+
+  if (!num_residuals) {
+    LG << "Skipping running mi

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list