code cleanup: camera tracking
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 10 Dec 2012 16:38:13 +0000 (16:38 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 10 Dec 2012 16:38:13 +0000 (16:38 +0000)
- Moved keyframes and refirement flags into reconstruction options structure
- Moved distortion coefficients and other camera intrinsics into own structure
- Cleaned up reconstruction functions in libmv c-api

extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
source/blender/blenkernel/intern/tracking.c

index 8e483ab..ffe4b6e 100644 (file)
@@ -552,40 +552,78 @@ static void libmv_solveRefineIntrinsics(libmv::Tracks *tracks, libmv::CameraIntr
                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, struct libmv_reconstructionOptions *options,
-                       reconstruct_progress_update_cb progress_update_callback, void *callback_customdata)
+static void cameraIntrinsicsFromOptions(libmv::CameraIntrinsics *camera_intrinsics,
+                                        libmv_cameraIntrinsicsOptions *camera_intrinsics_options)
+{
+       camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length,
+                                         camera_intrinsics_options->focal_length);
+
+       camera_intrinsics->SetPrincipalPoint(camera_intrinsics_options->principal_point_x,
+                                            camera_intrinsics_options->principal_point_y);
+
+       camera_intrinsics->SetRadialDistortion(camera_intrinsics_options->k1,
+                                              camera_intrinsics_options->k2,
+                                              camera_intrinsics_options->k3);
+}
+
+static libmv::Tracks getNormalizedTracks(libmv::Tracks *tracks, libmv::CameraIntrinsics *camera_intrinsics)
+{
+       libmv::vector<libmv::Marker> markers = tracks->AllMarkers();
+
+       for (int i = 0; i < markers.size(); ++i) {
+               camera_intrinsics->InvertIntrinsics(markers[i].x, markers[i].y,
+                       &(markers[i].x), &(markers[i].y));
+       }
+
+       return libmv::Tracks(markers);
+}
+
+static void finishReconstruction(libmv::Tracks *tracks, libmv::CameraIntrinsics *camera_intrinsics,
+                                 libmv_Reconstruction *libmv_reconstruction,
+                                 reconstruct_progress_update_cb progress_update_callback,
+                                 void *callback_customdata)
+{
+       libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+
+       /* reprojection error calculation */
+       progress_update_callback(callback_customdata, 1.0, "Finishing solution");
+       libmv_reconstruction->tracks = *tracks;
+       libmv_reconstruction->error = libmv::EuclideanReprojectionError(*tracks, *reconstruction, *camera_intrinsics);
+}
+
+libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *libmv_tracks,
+                       libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+                       libmv_reconstructionOptions *libmv_reconstruction_options,
+                       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::Tracks *tracks = ((libmv::Tracks *) libmv_tracks);
        libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
-       libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
-       libmv::ReconstructionOptions reconstruction_options;
+       libmv::CameraIntrinsics *camera_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);
+       cameraIntrinsicsFromOptions(camera_intrinsics, libmv_camera_intrinsics_options);
 
-       reconstruction_options.success_threshold = options->success_threshold;
-       reconstruction_options.use_fallback_reconstruction = options->use_fallback_reconstruction;
+       /* Invert the camera intrinsics */
+       libmv::Tracks normalized_tracks = getNormalizedTracks(tracks, camera_intrinsics);
 
-       for (int i = 0; i < markers.size(); ++i) {
-               intrinsics->InvertIntrinsics(markers[i].x,
-                       markers[i].y,
-                       &(markers[i].x),
-                       &(markers[i].y));
-       }
+       /* actual reconstruction */
+       libmv::ReconstructionOptions reconstruction_options;
+       reconstruction_options.success_threshold = libmv_reconstruction_options->success_threshold;
+       reconstruction_options.use_fallback_reconstruction = libmv_reconstruction_options->use_fallback_reconstruction;
 
-       libmv::Tracks normalized_tracks(markers);
+       int keyframe1 = libmv_reconstruction_options->keyframe1,
+           keyframe2 = libmv_reconstruction_options->keyframe2;
 
        LG << "frames to init from: " << keyframe1 << " " << keyframe2;
+
        libmv::vector<libmv::Marker> keyframe_markers =
                normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
+
        LG << "number of markers for init: " << keyframe_markers.size();
 
        update_callback.invoke(0, "Initial reconstruction");
@@ -595,49 +633,45 @@ libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyfra
        libmv::EuclideanCompleteReconstruction(reconstruction_options, normalized_tracks,
                                               reconstruction, &update_callback);
 
-       if (refine_intrinsics) {
-               libmv_solveRefineIntrinsics((libmv::Tracks *)tracks, intrinsics, reconstruction,
-                       refine_intrinsics, progress_update_callback, callback_customdata);
+       /* refinement */
+       if (libmv_reconstruction_options->refine_intrinsics) {
+               libmv_solveRefineIntrinsics((libmv::Tracks *)tracks, camera_intrinsics, reconstruction,
+                       libmv_reconstruction_options->refine_intrinsics,
+                       progress_update_callback, callback_customdata);
        }
 
-       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);
+       /* finish reconstruction */
+       finishReconstruction(tracks, camera_intrinsics, libmv_reconstruction,
+                            progress_update_callback, callback_customdata);
 
        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)
+struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *libmv_tracks,
+                       libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+                       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::Tracks *tracks = ((libmv::Tracks *) libmv_tracks);
        libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
-       libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+       libmv::CameraIntrinsics *camera_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));
-       }
+       cameraIntrinsicsFromOptions(camera_intrinsics, libmv_camera_intrinsics_options);
 
-       libmv::Tracks normalized_tracks(markers);
+       /* Invert the camera intrinsics */
+       libmv::Tracks normalized_tracks = getNormalizedTracks(tracks, camera_intrinsics);
 
+       /* actual reconstruction */
        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);
+       /* finish reconstruction */
+       finishReconstruction(tracks, camera_intrinsics, libmv_reconstruction,
+                            progress_update_callback, callback_customdata);
 
        return (libmv_Reconstruction *)libmv_reconstruction;
 }
index e5885e7..317f552 100644 (file)
@@ -86,28 +86,40 @@ void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track,
 void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks);
 
 /* Reconstruction solver */
-#define LIBMV_REFINE_FOCAL_LENGTH      (1<<0)
-#define LIBMV_REFINE_PRINCIPAL_POINT   (1<<1)
-#define LIBMV_REFINE_RADIAL_DISTORTION_K1 (1<<2)
-#define LIBMV_REFINE_RADIAL_DISTORTION_K2 (1<<4)
 
-/* TODO: make keyframes/distortion model a part of options? */
-struct libmv_reconstructionOptions {
+#define LIBMV_REFINE_FOCAL_LENGTH          (1 << 0)
+#define LIBMV_REFINE_PRINCIPAL_POINT       (1 << 1)
+#define LIBMV_REFINE_RADIAL_DISTORTION_K1  (1 << 2)
+#define LIBMV_REFINE_RADIAL_DISTORTION_K2  (1 << 4)
+
+typedef struct libmv_cameraIntrinsicsOptions {
+       double focal_length;
+       double principal_point_x, principal_point_y;
+       double k1, k2, k3;
+       double p1, p2;
+} libmv_cameraIntrinsicsOptions;
+
+typedef struct libmv_reconstructionOptions {
+       int keyframe1, keyframe2;
+       int refine_intrinsics;
+
        double success_threshold;
        int use_fallback_reconstruction;
-};
+} libmv_reconstructionOptions;
 
 typedef void (*reconstruct_progress_update_cb) (void *customdata, double progress, const char *message);
 
 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,
-                       struct libmv_reconstructionOptions *options, reconstruct_progress_update_cb progress_update_callback,
+struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *libmv_tracks,
+                       libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+                       libmv_reconstructionOptions *libmv_reconstruction_options,
+                       reconstruct_progress_update_cb progress_update_callback,
+                       void *callback_customdata);
+struct libmv_Reconstruction *libmv_solveModal(struct libmv_Tracks *libmv_tracks,
+                       libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+                       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);
index 30b4840..1641525 100644 (file)
@@ -2932,6 +2932,31 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const
 
        BLI_snprintf(progressdata->stats_message, progressdata->message_size, "Solving camera | %s", message);
 }
+
+static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *camera_intrinsics_options,
+                                              MovieReconstructContext *context)
+{
+       camera_intrinsics_options->focal_length = context->focal_length;
+
+       camera_intrinsics_options->principal_point_x = context->principal_point[0];
+       camera_intrinsics_options->principal_point_y = context->principal_point[1];
+
+       camera_intrinsics_options->k1 = context->k1;
+       camera_intrinsics_options->k2 = context->k2;
+       camera_intrinsics_options->k3 = context->k3;
+}
+
+static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options,
+                                             MovieReconstructContext *context)
+{
+       reconstruction_options->keyframe1 = context->keyframe1;
+       reconstruction_options->keyframe2 = context->keyframe2;
+
+       reconstruction_options->refine_intrinsics = context->refine_flags;
+
+       reconstruction_options->success_threshold = context->success_threshold;
+       reconstruction_options->use_fallback_reconstruction = context->use_fallback_reconstruction;
+}
 #endif
 
 void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update,
@@ -2942,32 +2967,27 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *
 
        ReconstructProgressData progressdata;
 
+       libmv_cameraIntrinsicsOptions camera_intrinsics_options;
+       libmv_reconstructionOptions reconstruction_options;
+
        progressdata.stop = stop;
        progressdata.do_update = do_update;
        progressdata.progress = progress;
        progressdata.stats_message = stats_message;
        progressdata.message_size = message_size;
 
+       camraIntrincicsOptionsFromContext(&camera_intrinsics_options, context);
+       reconstructionOptionsFromContext(&reconstruction_options, context);
+
        if (context->motion_flag & TRACKING_MOTION_MODAL) {
                context->reconstruction = libmv_solveModal(context->tracks,
-                                                          context->focal_length,
-                                                          context->principal_point[0], context->principal_point[1],
-                                                          context->k1, context->k2, context->k3,
+                                                          &camera_intrinsics_options,
                                                           reconstruct_update_solve_cb, &progressdata);
        }
        else {
-               struct libmv_reconstructionOptions options;
-
-               options.success_threshold = context->success_threshold;
-               options.use_fallback_reconstruction = context->use_fallback_reconstruction;
-
                context->reconstruction = libmv_solveReconstruction(context->tracks,
-                                                                   context->keyframe1, context->keyframe2,
-                                                                   context->refine_flags,
-                                                                   context->focal_length,
-                                                                   context->principal_point[0], context->principal_point[1],
-                                                                   context->k1, context->k2, context->k3,
-                                                                   &options,
+                                                                   &camera_intrinsics_options,
+                                                                   &reconstruction_options,
                                                                    reconstruct_update_solve_cb, &progressdata);
        }