Tracking: Decouple C-API module into more granular files
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 25 Sep 2014 11:01:06 +0000 (17:01 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 25 Sep 2014 11:04:56 +0000 (17:04 +0600)
This way maintaining the C-API is a bit less tedious job
and makes code cleaner to follow.

Should be no functional changes.

28 files changed:
extern/libmv/CMakeLists.txt
extern/libmv/SConscript
extern/libmv/bundle.sh
extern/libmv/intern/camera_intrinsics.cc [new file with mode: 0644]
extern/libmv/intern/camera_intrinsics.h [new file with mode: 0644]
extern/libmv/intern/detector.cc [new file with mode: 0644]
extern/libmv/intern/detector.h [new file with mode: 0644]
extern/libmv/intern/homography.cc [new file with mode: 0644]
extern/libmv/intern/homography.h [new file with mode: 0644]
extern/libmv/intern/image.cc [new file with mode: 0644]
extern/libmv/intern/image.h [new file with mode: 0644]
extern/libmv/intern/logging.cc [new file with mode: 0644]
extern/libmv/intern/logging.h [new file with mode: 0644]
extern/libmv/intern/reconstruction.cc [new file with mode: 0644]
extern/libmv/intern/reconstruction.h [new file with mode: 0644]
extern/libmv/intern/region.h [new file with mode: 0644]
extern/libmv/intern/stub.cc [new file with mode: 0644]
extern/libmv/intern/track_region.cc [new file with mode: 0644]
extern/libmv/intern/track_region.h [new file with mode: 0644]
extern/libmv/intern/tracks.cc [new file with mode: 0644]
extern/libmv/intern/tracks.h [new file with mode: 0644]
extern/libmv/intern/utildefines.h [moved from extern/libmv/libmv-capi_intern.h with 81% similarity]
extern/libmv/libmv-capi.cc [deleted file]
extern/libmv/libmv-capi.h
extern/libmv/libmv-capi_stub.cc [deleted file]
extern/libmv/libmv-util.cc [deleted file]
extern/libmv/libmv-util.h [deleted file]
source/blender/blenkernel/intern/tracking.c

index 9030ae9c1eda8f17e1676cac09c903a7c2b7ffcd..d482819c2cec4655729e1eb35dffc65c0408865c 100644 (file)
@@ -35,12 +35,10 @@ set(INC_SYS
 
 set(SRC
        libmv-capi.h
-       libmv-capi_intern.h
 )
 
 if(WITH_LIBMV)
        add_definitions(
-               -DWITH_LIBMV
                -DWITH_LIBMV_GUARDED_ALLOC
                -DGOOGLE_GLOG_DLL_DECL=
                -DLIBMV_NO_FAST_DETECTOR=
@@ -73,8 +71,14 @@ if(WITH_LIBMV)
        )
 
        list(APPEND SRC
-               libmv-capi.cc
-               libmv-util.cc
+               intern/camera_intrinsics.cc
+               intern/detector.cc
+               intern/homography.cc
+               intern/image.cc
+               intern/logging.cc
+               intern/reconstruction.cc
+               intern/track_region.cc
+               intern/tracks.cc
                libmv/base/aligned_malloc.cc
                libmv/image/array_nd.cc
                libmv/image/convolve.cc
@@ -109,7 +113,15 @@ if(WITH_LIBMV)
                libmv/tracking/track_region.cc
                libmv/tracking/trklt_region_tracker.cc
 
-               libmv-util.h
+
+               intern/camera_intrinsics.h
+               intern/detector.h
+               intern/homography.h
+               intern/image.h
+               intern/logging.h
+               intern/reconstruction.h
+               intern/track_region.h
+               intern/tracks.h
                libmv/base/aligned_malloc.h
                libmv/base/id_generator.h
                libmv/base/scoped_ptr.h
@@ -217,7 +229,7 @@ if(WITH_LIBMV)
        endif()
 else()
        list(APPEND SRC
-               libmv-capi_stub.cc
+               intern/stub.cc
        )
 endif()
 
index 6156dd45146b5b7b3fdb11f5219b245f1149db93..857d7dec7d4955081d1c150f264de2f009e42070 100644 (file)
@@ -24,11 +24,10 @@ if env['WITH_BF_LIBMV']:
         defs.append('CERES_TR1_SHARED_PTR')
 
     defs.append('GOOGLE_GLOG_DLL_DECL=')
-    defs.append('WITH_LIBMV')
     defs.append('WITH_LIBMV_GUARDED_ALLOC')
     defs.append('LIBMV_NO_FAST_DETECTOR')
 
-    src = env.Glob('*.cc')
+    src = env.Glob('intern/*.cc')
     src += env.Glob('libmv/base/*.cc')
     src += env.Glob('libmv/image/*.cc')
     src += env.Glob('libmv/multiview/*.cc')
@@ -52,7 +51,7 @@ if env['WITH_BF_LIBMV']:
         src += env.Glob("third_party/glog/src/*.cc")
         incs += ' ./third_party/glog/src'
 else:
-    src = env.Glob("libmv-capi_stub.cc")
+    src = env.Glob("intern/stub.cc")
 
 src = [src for src in src if src.find('_test.cc') == -1]
 
index 0560ab0acd2d571337ba00208c166bc1b6df983a..d394d2cd8c5329c9562a0ecb8be748ed98ccd7ba 100755 (executable)
@@ -7,7 +7,7 @@ else
   exit 1
 fi
 
-BRANCH="devel"
+BRANCH="master"
 
 repo="git://git.blender.org/libmv.git"
 tmp=`mktemp -d`
@@ -128,12 +128,10 @@ set(INC_SYS
 
 set(SRC
        libmv-capi.h
-       libmv-capi_intern.h
 )
 
 if(WITH_LIBMV)
        add_definitions(
-               -DWITH_LIBMV
                -DWITH_LIBMV_GUARDED_ALLOC
                -DGOOGLE_GLOG_DLL_DECL=
                -DLIBMV_NO_FAST_DETECTOR=
@@ -166,11 +164,29 @@ if(WITH_LIBMV)
        )
 
        list(APPEND SRC
-               libmv-capi.cc
-               libmv-util.cc
+               intern/camera_intrinsics.cc
+               intern/detector.cc
+               intern/frame_accessor.cc
+               intern/homography.cc
+               intern/image.cc
+               intern/logging.cc
+               intern/reconstruction.cc
+               intern/track_region.cc
+               intern/tracks.cc
+               intern/tracksN.cc
 ${sources}
 ${third_sources}
-               libmv-util.h
+
+               intern/camera_intrinsics.h
+               intern/detector.h
+               intern/frame_accessor.h
+               intern/homography.h
+               intern/image.h
+               intern/logging.h
+               intern/reconstruction.h
+               intern/track_region.h
+               intern/tracks.h
+               intern/tracksN.h
 ${headers}
 
 ${third_headers}
@@ -287,11 +303,10 @@ if env['WITH_BF_LIBMV']:
         defs.append('CERES_TR1_SHARED_PTR')
 
     defs.append('GOOGLE_GLOG_DLL_DECL=')
-    defs.append('WITH_LIBMV')
     defs.append('WITH_LIBMV_GUARDED_ALLOC')
     defs.append('LIBMV_NO_FAST_DETECTOR')
 
-    src = env.Glob('*.cc')
+    src = env.Glob('intern/*.cc')
 $src
 
     incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
@@ -309,7 +324,7 @@ ${win_src}
         src += env.Glob("third_party/glog/src/*.cc")
         incs += ' ./third_party/glog/src'
 else:
-    src = env.Glob("libmv-capi_stub.cc")
+    src = env.Glob("intern/stub.cc")
 
 src = [src for src in src if src.find('_test.cc') == -1]
 
diff --git a/extern/libmv/intern/camera_intrinsics.cc b/extern/libmv/intern/camera_intrinsics.cc
new file mode 100644 (file)
index 0000000..e8b9997
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * ***** 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/camera_intrinsics.h"
+#include "intern/utildefines.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+
+using libmv::CameraIntrinsics;
+using libmv::DivisionCameraIntrinsics;
+using libmv::PolynomialCameraIntrinsics;
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options) {
+  CameraIntrinsics *camera_intrinsics =
+    libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+  return (libmv_CameraIntrinsics *) camera_intrinsics;
+}
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+    const libmv_CameraIntrinsics* libmv_intrinsics) {
+  const CameraIntrinsics *orig_intrinsics =
+    (const CameraIntrinsics *) libmv_intrinsics;
+
+  CameraIntrinsics *new_intrinsics = NULL;
+  switch (orig_intrinsics->GetDistortionModelType()) {
+    case libmv::DISTORTION_MODEL_POLYNOMIAL:
+      {
+        const PolynomialCameraIntrinsics *polynomial_intrinsics =
+          static_cast<const PolynomialCameraIntrinsics*>(orig_intrinsics);
+        new_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics,
+                                          *polynomial_intrinsics);
+        break;
+      }
+    case libmv::DISTORTION_MODEL_DIVISION:
+      {
+        const DivisionCameraIntrinsics *division_intrinsics =
+          static_cast<const DivisionCameraIntrinsics*>(orig_intrinsics);
+        new_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics,
+                                          *division_intrinsics);
+        break;
+      }
+    default:
+      assert(!"Unknown distortion model");
+  }
+  return (libmv_CameraIntrinsics *) new_intrinsics;
+}
+
+void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics) {
+  LIBMV_OBJECT_DELETE(libmv_intrinsics, CameraIntrinsics);
+}
+
+void libmv_cameraIntrinsicsUpdate(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    libmv_CameraIntrinsics* libmv_intrinsics) {
+  CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+
+  double focal_length = libmv_camera_intrinsics_options->focal_length;
+  double principal_x = libmv_camera_intrinsics_options->principal_point_x;
+  double principal_y = libmv_camera_intrinsics_options->principal_point_y;
+  int image_width = libmv_camera_intrinsics_options->image_width;
+  int image_height = libmv_camera_intrinsics_options->image_height;
+
+  /* Try avoid unnecessary updates, so pre-computed distortion grids
+   * are not freed.
+   */
+
+  if (camera_intrinsics->focal_length() != focal_length) {
+    camera_intrinsics->SetFocalLength(focal_length, focal_length);
+  }
+
+  if (camera_intrinsics->principal_point_x() != principal_x ||
+      camera_intrinsics->principal_point_y() != principal_y) {
+    camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
+  }
+
+  if (camera_intrinsics->image_width() != image_width ||
+      camera_intrinsics->image_height() != image_height) {
+    camera_intrinsics->SetImageSize(image_width, image_height);
+  }
+
+  switch (libmv_camera_intrinsics_options->distortion_model) {
+    case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+      {
+        assert(camera_intrinsics->GetDistortionModelType() ==
+               libmv::DISTORTION_MODEL_POLYNOMIAL);
+
+        PolynomialCameraIntrinsics *polynomial_intrinsics =
+          (PolynomialCameraIntrinsics *) camera_intrinsics;
+
+        double k1 = libmv_camera_intrinsics_options->polynomial_k1;
+        double k2 = libmv_camera_intrinsics_options->polynomial_k2;
+        double k3 = libmv_camera_intrinsics_options->polynomial_k3;
+
+        if (polynomial_intrinsics->k1() != k1 ||
+            polynomial_intrinsics->k2() != k2 ||
+            polynomial_intrinsics->k3() != k3) {
+          polynomial_intrinsics->SetRadialDistortion(k1, k2, k3);
+        }
+        break;
+      }
+
+    case LIBMV_DISTORTION_MODEL_DIVISION:
+      {
+        assert(camera_intrinsics->GetDistortionModelType() ==
+               libmv::DISTORTION_MODEL_DIVISION);
+
+        DivisionCameraIntrinsics *division_intrinsics =
+          (DivisionCameraIntrinsics *) camera_intrinsics;
+
+        double k1 = libmv_camera_intrinsics_options->division_k1;
+        double k2 = libmv_camera_intrinsics_options->division_k2;
+
+        if (division_intrinsics->k1() != k1 ||
+            division_intrinsics->k2() != k2) {
+          division_intrinsics->SetDistortion(k1, k2);
+        }
+
+        break;
+      }
+
+    default:
+      assert(!"Unknown distortion model");
+  }
+}
+
+void libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics* libmv_intrinsics,
+                                      int threads) {
+  CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  camera_intrinsics->SetThreads(threads);
+}
+
+void libmv_cameraIntrinsicsExtractOptions(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
+  const CameraIntrinsics *camera_intrinsics =
+    (const CameraIntrinsics *) libmv_intrinsics;
+
+  // Fill in options which are common for all distortion models.
+  camera_intrinsics_options->focal_length = camera_intrinsics->focal_length();
+  camera_intrinsics_options->principal_point_x =
+    camera_intrinsics->principal_point_x();
+  camera_intrinsics_options->principal_point_y =
+    camera_intrinsics->principal_point_y();
+
+  camera_intrinsics_options->image_width = camera_intrinsics->image_width();
+  camera_intrinsics_options->image_height = camera_intrinsics->image_height();
+
+  switch (camera_intrinsics->GetDistortionModelType()) {
+    case libmv::DISTORTION_MODEL_POLYNOMIAL:
+      {
+        const PolynomialCameraIntrinsics *polynomial_intrinsics =
+          static_cast<const PolynomialCameraIntrinsics *>(camera_intrinsics);
+        camera_intrinsics_options->distortion_model =
+          LIBMV_DISTORTION_MODEL_POLYNOMIAL;
+        camera_intrinsics_options->polynomial_k1 = polynomial_intrinsics->k1();
+        camera_intrinsics_options->polynomial_k2 = polynomial_intrinsics->k2();
+        camera_intrinsics_options->polynomial_k3 = polynomial_intrinsics->k3();
+        camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p1();
+        camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p2();
+        break;
+      }
+
+    case libmv::DISTORTION_MODEL_DIVISION:
+      {
+        const DivisionCameraIntrinsics *division_intrinsics =
+          static_cast<const DivisionCameraIntrinsics *>(camera_intrinsics);
+        camera_intrinsics_options->distortion_model =
+          LIBMV_DISTORTION_MODEL_DIVISION;
+        camera_intrinsics_options->division_k1 = division_intrinsics->k1();
+        camera_intrinsics_options->division_k2 = division_intrinsics->k2();
+        break;
+      }
+
+    default:
+      assert(!"Uknown distortion model");
+  }
+}
+
+void libmv_cameraIntrinsicsUndistortByte(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    const unsigned char *source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    unsigned char* destination_image) {
+  CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  camera_intrinsics->UndistortBuffer(source_image,
+                                     width, height,
+                                     overscan,
+                                     channels,
+                                     destination_image);
+}
+
+void libmv_cameraIntrinsicsUndistortFloat(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    const float* source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    float* destination_image) {
+  CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  intrinsics->UndistortBuffer(source_image,
+                              width, height,
+                              overscan,
+                              channels,
+                              destination_image);
+}
+
+void libmv_cameraIntrinsicsDistortByte(
+    const struct libmv_CameraIntrinsics* libmv_intrinsics,
+    const unsigned char *source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    unsigned char *destination_image) {
+  CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  intrinsics->DistortBuffer(source_image,
+                            width, height,
+                            overscan,
+                            channels,
+                            destination_image);
+}
+
+void libmv_cameraIntrinsicsDistortFloat(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    float* source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    float* destination_image) {
+  CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+  intrinsics->DistortBuffer(source_image,
+                            width, height,
+                            overscan,
+                            channels,
+                            destination_image);
+}
+
+void libmv_cameraIntrinsicsApply(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    double x,
+    double y,
+    double* x1,
+    double* y1) {
+  /* Do a lens distortion if focal length is non-zero only. */
+  if (libmv_camera_intrinsics_options->focal_length) {
+    CameraIntrinsics* camera_intrinsics =
+      libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+    camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
+    LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
+  }
+}
+
+void libmv_cameraIntrinsicsInvert(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    double x,
+    double y,
+    double* x1,
+    double* y1) {
+  /* Do a lens un-distortion if focal length is non-zero only/ */
+  if (libmv_camera_intrinsics_options->focal_length) {
+    CameraIntrinsics *camera_intrinsics =
+      libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+    camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
+    LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
+  }
+}
+
+static void libmv_cameraIntrinsicsFillFromOptions(
+    const libmv_CameraIntrinsicsOptions* camera_intrinsics_options,
+    CameraIntrinsics* camera_intrinsics) {
+  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->SetImageSize(camera_intrinsics_options->image_width,
+      camera_intrinsics_options->image_height);
+
+  switch (camera_intrinsics_options->distortion_model) {
+    case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+      {
+        PolynomialCameraIntrinsics *polynomial_intrinsics =
+          static_cast<PolynomialCameraIntrinsics*>(camera_intrinsics);
+
+        polynomial_intrinsics->SetRadialDistortion(
+            camera_intrinsics_options->polynomial_k1,
+            camera_intrinsics_options->polynomial_k2,
+            camera_intrinsics_options->polynomial_k3);
+
+        break;
+      }
+
+    case LIBMV_DISTORTION_MODEL_DIVISION:
+      {
+        DivisionCameraIntrinsics *division_intrinsics =
+          static_cast<DivisionCameraIntrinsics*>(camera_intrinsics);
+
+        division_intrinsics->SetDistortion(
+            camera_intrinsics_options->division_k1,
+            camera_intrinsics_options->division_k2);
+        break;
+      }
+
+    default:
+      assert(!"Unknown distortion model");
+  }
+}
+
+CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
+    const libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
+  CameraIntrinsics *camera_intrinsics = NULL;
+  switch (camera_intrinsics_options->distortion_model) {
+    case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+      camera_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics);
+      break;
+    case LIBMV_DISTORTION_MODEL_DIVISION:
+      camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
+      break;
+    default:
+      assert(!"Unknown distortion model");
+  }
+  libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options, camera_intrinsics);
+  return camera_intrinsics;
+}
diff --git a/extern/libmv/intern/camera_intrinsics.h b/extern/libmv/intern/camera_intrinsics.h
new file mode 100644 (file)
index 0000000..9910d16
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_CAMERA_INTRINSICS_H_
+#define LIBMV_C_API_CAMERA_INTRINSICS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
+
+enum {
+  LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0,
+  LIBMV_DISTORTION_MODEL_DIVISION = 1,
+};
+
+typedef struct libmv_CameraIntrinsicsOptions {
+  // Common settings of all distortion models.
+  int distortion_model;
+  int image_width, image_height;
+  double focal_length;
+  double principal_point_x, principal_point_y;
+
+  // Radial distortion model.
+  double polynomial_k1, polynomial_k2, polynomial_k3;
+  double polynomial_p1, polynomial_p2;
+
+  // Division distortion model.
+  double division_k1, division_k2;
+} libmv_CameraIntrinsicsOptions;
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options);
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+    const libmv_CameraIntrinsics* libmv_intrinsics);
+
+void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics);
+void libmv_cameraIntrinsicsUpdate(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    libmv_CameraIntrinsics* libmv_intrinsics);
+
+void libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics* libmv_intrinsics,
+                                      int threads);
+
+void libmv_cameraIntrinsicsExtractOptions(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    libmv_CameraIntrinsicsOptions* camera_intrinsics_options);
+
+void libmv_cameraIntrinsicsUndistortByte(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    const unsigned char *source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    unsigned char* destination_image);
+
+void libmv_cameraIntrinsicsUndistortFloat(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    const float* source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    float* destination_image);
+
+void libmv_cameraIntrinsicsDistortByte(
+    const struct libmv_CameraIntrinsics* libmv_intrinsics,
+    const unsigned char *source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    unsigned char *destination_image);
+
+void libmv_cameraIntrinsicsDistortFloat(
+    const libmv_CameraIntrinsics* libmv_intrinsics,
+    float* source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    float* destination_image);
+
+void libmv_cameraIntrinsicsApply(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    double x,
+    double y,
+    double* x1,
+    double* y1);
+
+void libmv_cameraIntrinsicsInvert(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    double x,
+    double y,
+    double* x1,
+    double* y1);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+namespace libmv {
+  class CameraIntrinsics;
+}
+
+libmv::CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
+    const libmv_CameraIntrinsicsOptions* camera_intrinsics_options);
+#endif
+
+#endif  // LIBMV_C_API_CAMERA_INTRINSICS_H_
diff --git a/extern/libmv/intern/detector.cc b/extern/libmv/intern/detector.cc
new file mode 100644 (file)
index 0000000..8abc901
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * ***** 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/detector.h"
+#include "intern/image.h"
+#include "intern/utildefines.h"
+#include "libmv/simple_pipeline/detect.h"
+
+using libmv::Detect;
+using libmv::DetectOptions;
+using libmv::Feature;
+using libmv::FloatImage;
+
+struct libmv_Features {
+  int count;
+  Feature* features;
+};
+
+namespace {
+
+libmv_Features *libmv_featuresFromVector(
+    const libmv::vector<Feature>& features) {
+  libmv_Features* libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
+  int count = features.size();
+  if (count) {
+    libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
+    for (int i = 0; i < count; i++) {
+      libmv_features->features[i] = features.at(i);
+    }
+  } else {
+    libmv_features->features = NULL;
+  }
+  libmv_features->count = count;
+  return libmv_features;
+}
+
+void libmv_convertDetectorOptions(libmv_DetectOptions *options,
+                                  DetectOptions *detector_options) {
+  switch (options->detector) {
+#define LIBMV_CONVERT(the_detector) \
+  case LIBMV_DETECTOR_ ## the_detector:                 \
+    detector_options->type = DetectOptions::the_detector; \
+    break;
+    LIBMV_CONVERT(FAST)
+    LIBMV_CONVERT(MORAVEC)
+    LIBMV_CONVERT(HARRIS)
+#undef LIBMV_CONVERT
+  }
+  detector_options->margin = options->margin;
+  detector_options->min_distance = options->min_distance;
+  detector_options->fast_min_trackness = options->fast_min_trackness;
+  detector_options->moravec_max_count = options->moravec_max_count;
+  detector_options->moravec_pattern = options->moravec_pattern;
+  detector_options->harris_threshold = options->harris_threshold;
+}
+
+}  // namespace
+
+libmv_Features *libmv_detectFeaturesByte(const unsigned char* image_buffer,
+                                         int width,
+                                         int height,
+                                         int channels,
+                                         libmv_DetectOptions* options) {
+  // Prepare the image.
+  FloatImage image;
+  libmv_byteBufferToFloatImage(image_buffer, width, height, channels, &image);
+
+  // Configure detector.
+  DetectOptions detector_options;
+  libmv_convertDetectorOptions(options, &detector_options);
+
+  // Run the detector.
+  libmv::vector<Feature> detected_features;
+  Detect(image, detector_options, &detected_features);
+
+  // Convert result to C-API.
+  libmv_Features* result = libmv_featuresFromVector(detected_features);
+  return result;
+}
+
+libmv_Features* libmv_detectFeaturesFloat(const float* image_buffer,
+                                          int width,
+                                          int height,
+                                          int channels,
+                                          libmv_DetectOptions* options) {
+  // Prepare the image.
+  FloatImage image;
+  libmv_floatBufferToFloatImage(image_buffer, width, height, channels, &image);
+
+  // Configure detector.
+  DetectOptions detector_options;
+  libmv_convertDetectorOptions(options, &detector_options);
+
+  // Run the detector.
+  libmv::vector<Feature> detected_features;
+  Detect(image, detector_options, &detected_features);
+
+  // Convert result to C-API.
+  libmv_Features* result = libmv_featuresFromVector(detected_features);
+  return result;
+}
+
+void libmv_featuresDestroy(libmv_Features* libmv_features) {
+  if (libmv_features->features) {
+    LIBMV_STRUCT_DELETE(libmv_features->features);
+  }
+  LIBMV_STRUCT_DELETE(libmv_features);
+}
+
+int libmv_countFeatures(const libmv_Features* libmv_features) {
+  return libmv_features->count;
+}
+
+void libmv_getFeature(const libmv_Features* libmv_features,
+                      int number,
+                      double* x,
+                      double* y,
+                      double* score,
+                      double* size) {
+  Feature &feature = libmv_features->features[number];
+  *x = feature.x;
+  *y = feature.y;
+  *score = feature.score;
+  *size = feature.size;
+}
diff --git a/extern/libmv/intern/detector.h b/extern/libmv/intern/detector.h
new file mode 100644 (file)
index 0000000..f72b0dd
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_DETECTOR_H_
+#define LIBMV_C_API_DETECTOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_Features libmv_Features;
+
+enum {
+  LIBMV_DETECTOR_FAST,
+  LIBMV_DETECTOR_MORAVEC,
+  LIBMV_DETECTOR_HARRIS,
+};
+
+typedef struct libmv_DetectOptions {
+  int detector;
+  int margin;
+  int min_distance;
+  int fast_min_trackness;
+  int moravec_max_count;
+  unsigned char *moravec_pattern;
+  double harris_threshold;
+} libmv_DetectOptions;
+
+libmv_Features* libmv_detectFeaturesByte(const unsigned char* image_buffer,
+                                         int width,
+                                         int height,
+                                         int channels,
+                                         libmv_DetectOptions* options);
+
+libmv_Features* libmv_detectFeaturesFloat(const float* image_buffer,
+                                          int width,
+                                          int height,
+                                          int channels,
+                                          libmv_DetectOptions* options);
+
+void libmv_featuresDestroy(libmv_Features* libmv_features);
+int libmv_countFeatures(const libmv_Features* libmv_features);
+void libmv_getFeature(const libmv_Features* libmv_features,
+                      int number,
+                      double* x,
+                      double* y,
+                      double* score,
+                      double* size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_C_API_DETECTOR_H_
diff --git a/extern/libmv/intern/homography.cc b/extern/libmv/intern/homography.cc
new file mode 100644 (file)
index 0000000..6b61bd9
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * ***** 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/homography.h"
+#include "intern/utildefines.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/homography.h"
+
+void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
+                                              /* const */ double (*x2)[2],
+                                              int num_points,
+                                              double H[3][3]) {
+  libmv::Mat x1_mat, x2_mat;
+  libmv::Mat3 H_mat;
+
+  x1_mat.resize(2, num_points);
+  x2_mat.resize(2, num_points);
+
+  for (int i = 0; i < num_points; i++) {
+    x1_mat.col(i) = libmv::Vec2(x1[i][0], x1[i][1]);
+    x2_mat.col(i) = libmv::Vec2(x2[i][0], x2[i][1]);
+  }
+
+  LG << "x1: " << x1_mat;
+  LG << "x2: " << x2_mat;
+
+  libmv::EstimateHomographyOptions options;
+  libmv::EstimateHomography2DFromCorrespondences(x1_mat,
+                                                 x2_mat,
+                                                 options,
+                                                 &H_mat);
+
+  LG << "H: " << H_mat;
+
+  memcpy(H, H_mat.data(), 9 * sizeof(double));
+}
diff --git a/extern/libmv/intern/homography.h b/extern/libmv/intern/homography.h
new file mode 100644 (file)
index 0000000..175108e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_HOMOGRAPHY_H_
+#define LIBMV_C_API_HOMOGRAPHY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
+                                              /* const */ double (*x2)[2],
+                                              int num_points,
+                                              double H[3][3]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_C_API_HOMOGRAPHY_H_
diff --git a/extern/libmv/intern/image.cc b/extern/libmv/intern/image.cc
new file mode 100644 (file)
index 0000000..7e623bd
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * ***** 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/image.h"
+#include "intern/utildefines.h"
+#include "libmv/tracking/track_region.h"
+
+#include <cassert>
+#include <png.h>
+
+using libmv::FloatImage;
+using libmv::SamplePlanarPatch;
+
+void libmv_floatImaheDestroy(libmv_FloatImage *image) {
+  delete [] image->buffer;
+}
+
+/* Image <-> buffers conversion */
+
+void libmv_byteBufferToFloatImage(const unsigned char* buffer,
+                                  int width,
+                                  int height,
+                                  int channels,
+                                  FloatImage* image) {
+  image->Resize(height, width, channels);
+  for (int y = 0, a = 0; y < height; y++) {
+    for (int x = 0; x < width; x++) {
+      for (int k = 0; k < channels; k++) {
+        (*image)(y, x, k) = (float)buffer[a++] / 255.0f;
+      }
+    }
+  }
+}
+
+void libmv_floatBufferToFloatImage(const float* buffer,
+                                   int width,
+                                   int height,
+                                   int channels,
+                                   FloatImage* image) {
+  image->Resize(height, width, channels);
+  for (int y = 0, a = 0; y < height; y++) {
+    for (int x = 0; x < width; x++) {
+      for (int k = 0; k < channels; k++) {
+        (*image)(y, x, k) = buffer[a++];
+      }
+    }
+  }
+}
+
+void libmv_floatImageToFloatBuffer(const FloatImage &image,
+                                   float* buffer) {
+  for (int y = 0, a = 0; y < image.Height(); y++) {
+    for (int x = 0; x < image.Width(); x++) {
+      for (int k = 0; k < image.Depth(); k++) {
+        buffer[a++] = image(y, x, k);
+      }
+    }
+  }
+}
+
+void libmv_floatImageToByteBuffer(const libmv::FloatImage &image,
+                                  unsigned char* buffer) {
+  for (int y = 0, a= 0; y < image.Height(); y++) {
+    for (int x = 0; x < image.Width(); x++) {
+      for (int k = 0; k < image.Depth(); k++) {
+        buffer[a++] = image(y, x, k) * 255.0f;
+      }
+    }
+  }
+}
+
+static bool savePNGImage(png_bytep* row_pointers,
+                         int width,
+                         int height,
+                         int depth,
+                         int color_type,
+                         const char* file_name) {
+  png_infop info_ptr;
+  png_structp png_ptr;
+  FILE *fp = fopen(file_name, "wb");
+
+  if (fp == NULL) {
+    return false;
+  }
+
+  /* Initialize stuff */
+  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  info_ptr = png_create_info_struct(png_ptr);
+
+  if (setjmp(png_jmpbuf(png_ptr))) {
+    fclose(fp);
+    return false;
+  }
+
+  png_init_io(png_ptr, fp);
+
+  /* Write PNG header. */
+  if (setjmp(png_jmpbuf(png_ptr))) {
+    fclose(fp);
+    return false;
+  }
+
+  png_set_IHDR(png_ptr,
+               info_ptr,
+               width,
+               height,
+               depth,
+               color_type,
+               PNG_INTERLACE_NONE,
+               PNG_COMPRESSION_TYPE_BASE,
+               PNG_FILTER_TYPE_BASE);
+
+  png_write_info(png_ptr, info_ptr);
+
+  /* Write bytes/ */
+  if (setjmp(png_jmpbuf(png_ptr))) {
+    fclose(fp);
+    return false;
+  }
+
+  png_write_image(png_ptr, row_pointers);
+
+  /* End write/ */
+  if (setjmp(png_jmpbuf(png_ptr))) {
+    fclose(fp);
+    return false;
+  }
+
+  png_write_end(png_ptr, NULL);
+  fclose(fp);
+
+  return true;
+}
+
+bool libmv_saveImage(const FloatImage& image,
+                     const char* prefix,
+                     int x0,
+                     int y0) {
+  int x, y;
+  png_bytep *row_pointers;
+
+  assert(image.Depth() == 1);
+
+  row_pointers = new png_bytep[image.Height()];
+
+  for (y = 0; y < image.Height(); y++) {
+    row_pointers[y] = new png_byte[4 * image.Width()];
+
+    for (x = 0; x < image.Width(); x++) {
+      if (x0 == x && image.Height() - y0 - 1 == y) {
+        row_pointers[y][x * 4 + 0] = 255;
+        row_pointers[y][x * 4 + 1] = 0;
+        row_pointers[y][x * 4 + 2] = 0;
+        row_pointers[y][x * 4 + 3] = 255;
+      } else {
+        float pixel = image(image.Height() - y - 1, x, 0);
+        row_pointers[y][x * 4 + 0] = pixel * 255;
+        row_pointers[y][x * 4 + 1] = pixel * 255;
+        row_pointers[y][x * 4 + 2] = pixel * 255;
+        row_pointers[y][x * 4 + 3] = 255;
+      }
+    }
+  }
+
+  static int image_counter = 0;
+  char file_name[128];
+  snprintf(file_name, sizeof(file_name),
+           "%s_%02d.png",
+           prefix, ++image_counter);
+  bool result = savePNGImage(row_pointers,
+                             image.Width(),
+                             image.Height(),
+                             8,
+                             PNG_COLOR_TYPE_RGBA,
+                             file_name);
+
+  for (y = 0; y < image.Height(); y++) {
+    delete [] row_pointers[y];
+  }
+  delete [] row_pointers;
+
+  return result;
+}
+
+void libmv_samplePlanarPatchFloat(const float* image,
+                                  int width,
+                                  int height,
+                                  int channels,
+                                  const double* xs,
+                                  const double* ys,
+                                  int num_samples_x,
+                                  int num_samples_y,
+                                  const float* mask,
+                                  float* patch,
+                                  double* warped_position_x,
+                                  double* warped_position_y) {
+  FloatImage libmv_image, libmv_patch, libmv_mask;
+  FloatImage *libmv_mask_for_sample = NULL;
+
+  libmv_floatBufferToFloatImage(image, width, height, channels, &libmv_image);
+
+  if (mask) {
+    libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
+    libmv_mask_for_sample = &libmv_mask;
+  }
+
+  SamplePlanarPatch(libmv_image,
+                    xs, ys,
+                    num_samples_x, num_samples_y,
+                    libmv_mask_for_sample,
+                    &libmv_patch,
+                    warped_position_x,
+                    warped_position_y);
+
+  libmv_floatImageToFloatBuffer(libmv_patch, patch);
+}
+
+ void libmv_samplePlanarPatchByte(const unsigned char* image,
+                                  int width,
+                                  int height,
+                                  int channels,
+                                  const double* xs,
+                                  const double* ys,
+                                  int num_samples_x,
+                                  int num_samples_y,
+                                  const float* mask,
+                                  unsigned char* patch,
+                                  double* warped_position_x,
+                                  double* warped_position_y) {
+  libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
+  libmv::FloatImage *libmv_mask_for_sample = NULL;
+
+  libmv_byteBufferToFloatImage(image, width, height, channels, &libmv_image);
+
+  if (mask) {
+    libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
+    libmv_mask_for_sample = &libmv_mask;
+  }
+
+  libmv::SamplePlanarPatch(libmv_image,
+                           xs, ys,
+                           num_samples_x, num_samples_y,
+                           libmv_mask_for_sample,
+                           &libmv_patch,
+                           warped_position_x,
+                           warped_position_y);
+
+       libmv_floatImageToByteBuffer(libmv_patch, patch);
+}
diff --git a/extern/libmv/intern/image.h b/extern/libmv/intern/image.h
new file mode 100644 (file)
index 0000000..9936e74
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_IMAGE_H_
+#define LIBMV_IMAGE_H_
+
+#ifdef __cplusplus
+#  include "libmv/image/image.h"
+void libmv_byteBufferToFloatImage(const unsigned char* buffer,
+                                  int width,
+                                  int height,
+                                  int channels,
+                                  libmv::FloatImage* image);
+
+void libmv_floatBufferToFloatImage(const float* buffer,
+                                   int width,
+                                   int height,
+                                   int channels,
+                                   libmv::FloatImage* image);
+
+void libmv_floatImageToFloatBuffer(const libmv::FloatImage& image,
+                                   float *buffer);
+
+void libmv_floatImageToByteBuffer(const libmv::FloatImage& image,
+                                  unsigned char* buffer);
+
+bool libmv_saveImage(const libmv::FloatImage& image,
+                     const char* prefix,
+                     int x0,
+                     int y0);
+#endif  // __cplusplus
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_FloatImage {
+  float *buffer;
+  int width;
+  int height;
+  int channels;
+} libmv_FloatImage;
+
+void libmv_floatImaheDestroy(libmv_FloatImage *image);
+
+void libmv_samplePlanarPatchFloat(const float* image,
+                                  int width,
+                                  int height,
+                                  int channels,
+                                  const double* xs,
+                                  const double* ys,
+                                  int num_samples_x,
+                                  int num_samples_y,
+                                  const float* mask,
+                                  float* patch,
+                                  double* warped_position_x,
+                                  double* warped_position_y);
+
+ void libmv_samplePlanarPatchByte(const unsigned char* image,
+                                  int width,
+                                  int height,
+                                  int channels,
+                                  const double* xs,
+                                  const double* ys,
+                                  int num_samples_x,
+                                  int num_samples_y,
+                                  const float* mask,
+                                  unsigned char* patch,
+                                  double* warped_position_x,
+                                  double* warped_position_y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_IMAGE_H_
diff --git a/extern/libmv/intern/logging.cc b/extern/libmv/intern/logging.cc
new file mode 100644 (file)
index 0000000..4ab2d91
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * ***** 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/logging.h"
+#include "intern/utildefines.h"
+#include "libmv/logging/logging.h"
+
+void libmv_initLogging(const char* argv0) {
+  // Make it so FATAL messages are always print into console.
+  char severity_fatal[32];
+  snprintf(severity_fatal, sizeof(severity_fatal), "%d",
+           google::GLOG_FATAL);
+
+  google::InitGoogleLogging(argv0);
+  google::SetCommandLineOption("logtostderr", "1");
+  google::SetCommandLineOption("v", "0");
+  google::SetCommandLineOption("stderrthreshold", severity_fatal);
+  google::SetCommandLineOption("minloglevel", severity_fatal);
+}
+
+void libmv_startDebugLogging(void) {
+  google::SetCommandLineOption("logtostderr", "1");
+  google::SetCommandLineOption("v", "2");
+  google::SetCommandLineOption("stderrthreshold", "1");
+  google::SetCommandLineOption("minloglevel", "0");
+}
+
+void libmv_setLoggingVerbosity(int verbosity) {
+  char val[10];
+  snprintf(val, sizeof(val), "%d", verbosity);
+  google::SetCommandLineOption("v", val);
+}
diff --git a/extern/libmv/intern/logging.h b/extern/libmv/intern/logging.h
new file mode 100644 (file)
index 0000000..479ed3d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_LOGGING_H_
+#define LIBMV_C_API_LOGGING_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initialize GLog logging.
+void libmv_initLogging(const char* argv0);
+
+// Switch Glog to debug logging level.
+void libmv_startDebugLogging(void);
+
+// Set GLog logging verbosity level.
+void libmv_setLoggingVerbosity(int verbosity);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_C_API_LOGGING_H_
diff --git a/extern/libmv/intern/reconstruction.cc b/extern/libmv/intern/reconstruction.cc
new file mode 100644 (file)
index 0000000..eb3677f
--- /dev/null
@@ -0,0 +1,530 @@
+/*
+ * ***** 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;
+};
+
+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();
+
+  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);
+
+  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);
+
+  return (libmv_Reconstruction *) libmv_reconstruction;
+}
+
+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;
+}
diff --git a/extern/libmv/intern/reconstruction.h b/extern/libmv/intern/reconstruction.h
new file mode 100644 (file)
index 0000000..744f4ba
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_RECONSTRUCTION_H_
+#define LIBMV_C_API_RECONSTRUCTION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
+typedef struct libmv_CameraIntrinsicsOptions libmv_CameraIntrinsicsOptions;
+typedef struct libmv_Reconstruction libmv_Reconstruction;
+typedef struct libmv_Tracks libmv_Tracks;
+
+enum {
+  LIBMV_REFINE_FOCAL_LENGTH         = (1 << 0),
+  LIBMV_REFINE_PRINCIPAL_POINT      = (1 << 1),
+  LIBMV_REFINE_RADIAL_DISTORTION_K1 = (1 << 2),
+  LIBMV_REFINE_RADIAL_DISTORTION_K2 = (1 << 4),
+};
+
+typedef struct libmv_ReconstructionOptions {
+  int select_keyframes;
+  int keyframe1, keyframe2;
+  int refine_intrinsics;
+} libmv_ReconstructionOptions;
+
+typedef void (*reconstruct_progress_update_cb) (void* customdata,
+                                                double progress,
+                                                const char* message);
+
+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_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);
+
+void libmv_reconstructionDestroy(libmv_Reconstruction* libmv_reconstruction);
+
+int libmv_reprojectionPointForTrack(
+    const libmv_Reconstruction* libmv_reconstruction,
+    int track,
+    double pos[3]);
+
+double libmv_reprojectionErrorForTrack(
+    const libmv_Reconstruction* libmv_reconstruction,
+    int track);
+
+double libmv_reprojectionErrorForImage(
+    const libmv_Reconstruction* libmv_reconstruction,
+    int image);
+
+int libmv_reprojectionCameraForImage(
+    const libmv_Reconstruction* libmv_reconstruction,
+    int image,
+    double mat[4][4]);
+
+double libmv_reprojectionError(const libmv_Reconstruction* libmv_reconstruction);
+
+libmv_CameraIntrinsics* libmv_reconstructionExtractIntrinsics(
+    libmv_Reconstruction *libmv_Reconstruction);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif   // LIBMV_C_API_RECONSTRUCTION_H_
diff --git a/extern/libmv/intern/region.h b/extern/libmv/intern/region.h
new file mode 100644 (file)
index 0000000..9f114bb
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ***** 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) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_REGION_H_
+#define LIBMV_C_API_REGION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_Region {
+  float min[2];
+  float max[2];
+} libmv_Region;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_C_API_REGION_H_
diff --git a/extern/libmv/intern/stub.cc b/extern/libmv/intern/stub.cc
new file mode 100644 (file)
index 0000000..cd8bb8a
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * ***** 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) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "libmv-capi.h"
+
+#include <cstdlib>
+#include <cstring>
+
+/* ************ Logging ************ */
+
+void libmv_initLogging(const char * /*argv0*/) {
+}
+
+void libmv_startDebugLogging(void) {
+}
+
+void libmv_setLoggingVerbosity(int /*verbosity*/) {
+}
+
+/* ************ Planar tracker ************ */
+
+/* TrackRegion (new planar tracker) */
+int libmv_trackRegion(const libmv_TrackRegionOptions * /*options*/,
+                      const float * /*image1*/,
+                      int /*image1_width*/,
+                      int /*image1_height*/,
+                      const float * /*image2*/,
+                      int /*image2_width*/,
+                      int /*image2_height*/,
+                      const double *x1,
+                      const double *y1,
+                      libmv_TrackRegionResult *result,
+                      double *x2,
+                      double *y2) {
+  /* Convert to doubles for the libmv api. The four corners and the center. */
+  for (int i = 0; i < 5; ++i) {
+    x2[i] = x1[i];
+    y2[i] = y1[i];
+  }
+
+  result->termination = -1;
+  result->termination_reason = "Built without libmv support";
+  result->correlation = 0.0;
+
+  return false;
+}
+
+void libmv_samplePlanarPatchFloat(const float * /*image*/,
+                                  int /*width*/,
+                                  int /*height*/,
+                                  int /*channels*/,
+                                  const double * /*xs*/,
+                                  const double * /*ys*/,
+                                  int /*num_samples_x*/,
+                                  int /*num_samples_y*/,
+                                  const float * /*mask*/,
+                                  float * /*patch*/,
+                                  double * /*warped_position_x*/,
+                                  double * /*warped_position_y*/) {
+  /* TODO(sergey): implement */
+}
+
+void libmv_samplePlanarPatchByte(const unsigned char * /*image*/,
+                                 int /*width*/,
+                                 int /*height*/,
+                                 int /*channels*/,
+                                 const double * /*xs*/,
+                                 const double * /*ys*/,
+                                 int /*num_samples_x*/, int /*num_samples_y*/,
+                                 const float * /*mask*/,
+                                 unsigned char * /*patch*/,
+                                 double * /*warped_position_x*/,
+                                 double * /*warped_position_y*/) {
+  /* TODO(sergey): implement */
+}
+
+/* ************ Tracks ************ */
+
+libmv_Tracks *libmv_tracksNew(void) {
+  return NULL;
+}
+
+void libmv_tracksInsert(libmv_Tracks * /*libmv_tracks*/,
+                        int /*image*/,
+                        int /*track*/,
+                        double /*x*/,
+                        double /*y*/,
+                        double /*weight*/) {
+}
+
+void libmv_tracksDestroy(libmv_Tracks * /*libmv_tracks*/) {
+}
+
+/* ************ Reconstruction solver ************ */
+
+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*/) {
+  return NULL;
+}
+
+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*/) {
+  return NULL;
+}
+
+int libmv_reprojectionPointForTrack(
+    const libmv_Reconstruction * /*libmv_reconstruction*/,
+    int /*track*/,
+    double /*pos*/[3]) {
+  return 0;
+}
+
+double libmv_reprojectionErrorForTrack(
+    const libmv_Reconstruction * /*libmv_reconstruction*/,
+    int /*track*/) {
+  return 0.0;
+}
+
+double libmv_reprojectionErrorForImage(
+    const libmv_Reconstruction * /*libmv_reconstruction*/,
+    int /*image*/) {
+  return 0.0;
+}
+
+int libmv_reprojectionCameraForImage(
+    const libmv_Reconstruction * /*libmv_reconstruction*/,
+    int /*image*/,
+    double /*mat*/[4][4]) {
+  return 0;
+}
+
+double libmv_reprojectionError(
+    const libmv_Reconstruction * /*libmv_reconstruction*/) {
+  return 0.0;
+}
+
+void libmv_reconstructionDestroy(
+    struct libmv_Reconstruction * /*libmv_reconstruction*/) {
+}
+
+/* ************ Feature detector ************ */
+
+libmv_Features *libmv_detectFeaturesByte(const unsigned char */*image_buffer*/,
+                                         int /*width*/,
+                                         int /*height*/,
+                                         int /*channels*/,
+                                         libmv_DetectOptions */*options*/) {
+  return NULL;
+}
+
+struct libmv_Features *libmv_detectFeaturesFloat(
+    const float */*image_buffer*/,
+    int /*width*/,
+    int /*height*/,
+    int /*channels*/,
+    libmv_DetectOptions */*options*/) {
+  return NULL;
+}
+
+int libmv_countFeatures(const libmv_Features * /*libmv_features*/) {
+  return 0;
+}
+
+void libmv_getFeature(const libmv_Features * /*libmv_features*/,
+                      int /*number*/,
+                      double *x,
+                      double *y,
+                      double *score,
+                      double *size) {
+  *x = 0.0;
+  *y = 0.0;
+  *score = 0.0;
+  *size = 0.0;
+}
+
+void libmv_featuresDestroy(struct libmv_Features * /*libmv_features*/) {
+}
+
+/* ************ Camera intrinsics ************ */
+
+libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
+    libmv_Reconstruction * /*libmv_reconstruction*/) {
+  return NULL;
+}
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+    const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/) {
+  return NULL;
+}
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+    const libmv_CameraIntrinsics * /*libmvIntrinsics*/) {
+  return NULL;
+}
+
+void libmv_cameraIntrinsicsDestroy(
+    libmv_CameraIntrinsics * /*libmvIntrinsics*/) {
+}
+
+void libmv_cameraIntrinsicsUpdate(
+    const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
+    libmv_CameraIntrinsics * /*libmv_intrinsics*/) {
+}
+
+void libmv_cameraIntrinsicsSetThreads(
+    libmv_CameraIntrinsics * /*libmv_intrinsics*/,
+    int /*threads*/) {
+}
+
+void libmv_cameraIntrinsicsExtractOptions(
+    const libmv_CameraIntrinsics */*libmv_intrinsics*/,
+    libmv_CameraIntrinsicsOptions *camera_intrinsics_options) {
+  memset(camera_intrinsics_options, 0, sizeof(libmv_CameraIntrinsicsOptions));
+  camera_intrinsics_options->focal_length = 1.0;
+}
+
+void libmv_cameraIntrinsicsUndistortByte(
+    const libmv_CameraIntrinsics * /*libmv_intrinsics*/,
+    const unsigned char *source_image,
+    int width, int height,
+    float overscan, int channels,
+    unsigned char *destination_image) {
+  memcpy(destination_image, source_image,
+         channels * width * height * sizeof(unsigned char));
+}
+
+void libmv_cameraIntrinsicsUndistortFloat(
+    const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+    const float* source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    float* destination_image) {
+  memcpy(destination_image, source_image,
+         channels * width * height * sizeof(float));
+}
+
+void libmv_cameraIntrinsicsDistortByte(
+    const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+    const unsigned char *source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    unsigned char *destination_image) {
+  memcpy(destination_image, source_image,
+         channels * width * height * sizeof(unsigned char));
+}
+
+void libmv_cameraIntrinsicsDistortFloat(
+    const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+    float* source_image,
+    int width,
+    int height,
+    float overscan,
+    int channels,
+    float* destination_image) {
+  memcpy(destination_image, source_image,
+         channels * width * height * sizeof(float));
+}
+
+/* ************ utils ************ */
+
+void libmv_cameraIntrinsicsApply(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    double x,
+    double y,
+    double* x1,
+    double* y1) {
+  double focal_length = libmv_camera_intrinsics_options->focal_length;
+  double principal_x = libmv_camera_intrinsics_options->principal_point_x;
+  double principal_y = libmv_camera_intrinsics_options->principal_point_y;
+  *x1 = x * focal_length + principal_x;
+  *y1 = y * focal_length + principal_y;
+}
+
+void libmv_cameraIntrinsicsInvert(
+    const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+    double x,
+    double y,
+    double* x1,
+    double* y1) {
+  double focal_length = libmv_camera_intrinsics_options->focal_length;
+  double principal_x = libmv_camera_intrinsics_options->principal_point_x;
+  double principal_y = libmv_camera_intrinsics_options->principal_point_y;
+  *x1 = (x - principal_x) / focal_length;
+  *y1 = (y - principal_y) / focal_length;
+}
+
+void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
+                                              /* const */ double (*x2)[2],
+                                              int num_points,
+                                              double H[3][3]) {
+  memset(H, 0, sizeof(double[3][3]));
+  H[0][0] = 1.0f;
+  H[1][1] = 1.0f;
+  H[2][2] = 1.0f;
+}
diff --git a/extern/libmv/intern/track_region.cc b/extern/libmv/intern/track_region.cc
new file mode 100644 (file)
index 0000000..24fbc78
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * ***** 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/track_region.h"
+#include "intern/image.h"
+#include "intern/utildefines.h"
+#include "libmv/image/image.h"
+#include "libmv/tracking/track_region.h"
+
+/* define this to generate PNG images with content of search areas
+   tracking between which failed */
+#undef DUMP_FAILURE
+
+/* define this to generate PNG images with content of search areas
+   on every itteration of tracking */
+#undef DUMP_ALWAYS
+
+using libmv::FloatImage;
+using libmv::TrackRegionOptions;
+using libmv::TrackRegionResult;
+using libmv::TrackRegion;
+
+void libmv_configureTrackRegionOptions(
+    const libmv_TrackRegionOptions& options,
+    TrackRegionOptions* track_region_options) {
+  switch (options.motion_model) {
+#define LIBMV_CONVERT(the_model) \
+  case TrackRegionOptions::the_model: \
+    track_region_options->mode = TrackRegionOptions::the_model; \
+    break;
+    LIBMV_CONVERT(TRANSLATION)
+    LIBMV_CONVERT(TRANSLATION_ROTATION)
+    LIBMV_CONVERT(TRANSLATION_SCALE)
+    LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
+    LIBMV_CONVERT(AFFINE)
+    LIBMV_CONVERT(HOMOGRAPHY)
+#undef LIBMV_CONVERT
+  }
+
+  track_region_options->minimum_correlation = options.minimum_correlation;
+  track_region_options->max_iterations = options.num_iterations;
+  track_region_options->sigma = options.sigma;
+  track_region_options->num_extra_points = 1;
+  track_region_options->image1_mask = NULL;
+  track_region_options->use_brute_initialization = options.use_brute;
+  /* TODO(keir): This will make some cases better, but may be a regression until
+   * the motion model is in. Since this is on trunk, enable it for now.
+   *
+   * TODO(sergey): This gives much worse results on mango footage (see 04_2e)
+   * so disabling for now for until proper prediction model is landed.
+   *
+   * The thing is, currently blender sends input coordinates as the guess to
+   * region tracker and in case of fast motion such an early out ruins the track.
+   */
+  track_region_options->attempt_refine_before_brute = false;
+  track_region_options->use_normalized_intensities = options.use_normalization;
+}
+
+void libmv_regionTrackergetResult(const TrackRegionResult& track_region_result,
+                                  libmv_TrackRegionResult* result) {
+  result->termination = (int) track_region_result.termination;
+  result->termination_reason = "";
+  result->correlation = track_region_result.correlation;
+}
+
+int libmv_trackRegion(const libmv_TrackRegionOptions* options,
+                      const float* image1,
+                      int image1_width,
+                      int image1_height,
+                      const float* image2,
+                      int image2_width,
+                      int image2_height,
+                      const double* x1,
+                      const double* y1,
+                      libmv_TrackRegionResult* result,
+                      double* x2,
+                      double* y2) {
+  double xx1[5], yy1[5];
+  double xx2[5], yy2[5];
+  bool tracking_result = false;
+
+  // Convert to doubles for the libmv api. The four corners and the center.
+  for (int i = 0; i < 5; ++i) {
+    xx1[i] = x1[i];
+    yy1[i] = y1[i];
+    xx2[i] = x2[i];
+    yy2[i] = y2[i];
+  }
+
+  TrackRegionOptions track_region_options;
+  FloatImage image1_mask;
+
+  libmv_configureTrackRegionOptions(*options, &track_region_options);
+  if (options->image1_mask) {
+    libmv_floatBufferToFloatImage(options->image1_mask,
+                                  image1_width,
+                                  image1_height,
+                                  1,
+                                  &image1_mask);
+
+    track_region_options.image1_mask = &image1_mask;
+  }
+
+  // Convert from raw float buffers to libmv's FloatImage.
+  FloatImage old_patch, new_patch;
+  libmv_floatBufferToFloatImage(image1,
+                                image1_width,
+                                image1_height,
+                                1,
+                                &old_patch);
+  libmv_floatBufferToFloatImage(image2,
+                                image2_width,
+                                image2_height,
+                                1,
+                                &new_patch);
+
+  TrackRegionResult track_region_result;
+  TrackRegion(old_patch, new_patch,
+              xx1, yy1,
+              track_region_options,
+              xx2, yy2,
+              &track_region_result);
+
+  // Convert to floats for the blender api.
+  for (int i = 0; i < 5; ++i) {
+    x2[i] = xx2[i];
+    y2[i] = yy2[i];
+  }
+
+  // TODO(keir): Update the termination string with failure details.
+  if (track_region_result.termination == TrackRegionResult::CONVERGENCE ||
+      track_region_result.termination == TrackRegionResult::NO_CONVERGENCE) {
+    tracking_result = true;
+  }
+
+  // Debug dump of patches.
+#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
+  bool need_dump = !tracking_result;
+
+#  ifdef DUMP_ALWAYS
+  need_dump = true;
+#  endif
+
+  if (need_dump) {
+    libmv_saveImage(old_patch, "old_patch", x1[4], y1[4]);
+    libmv_saveImage(new_patch, "new_patch", x2[4], y2[4]);
+    if (options->image1_mask) {
+      libmv_saveImage(image1_mask, "mask", x2[4], y2[4]);
+    }
+  }
+#endif
+
+  return tracking_result;
+}
diff --git a/extern/libmv/intern/track_region.h b/extern/libmv/intern/track_region.h
new file mode 100644 (file)
index 0000000..95ec124
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_TRACK_REGION_H_
+#define LIBMV_C_API_TRACK_REGION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_TrackRegionOptions {
+  int motion_model;
+  int num_iterations;
+  int use_brute;
+  int use_normalization;
+  double minimum_correlation;
+  double sigma;
+  float *image1_mask;
+} libmv_TrackRegionOptions;
+
+typedef struct libmv_TrackRegionResult {
+  int termination;
+  const char* termination_reason;
+  double correlation;
+} libmv_TrackRegionResult;
+
+#ifdef __cplusplus
+namespace libmv {
+  class TrackRegionOptions;
+  class TrackRegionResult;
+}
+void libmv_configureTrackRegionOptions(
+    const libmv_TrackRegionOptions& options,
+    libmv::TrackRegionOptions* track_region_options);
+
+void libmv_regionTrackergetResult(
+    const libmv::TrackRegionResult& track_region_result,
+    libmv_TrackRegionResult* result);
+#endif
+
+int libmv_trackRegion(const libmv_TrackRegionOptions* options,
+                      const float* image1,
+                      int image1_width,
+                      int image1_height,
+                      const float* image2,
+                      int image2_width,
+                      int image2_height,
+                      const double* x1,
+                      const double* y1,
+                      libmv_TrackRegionResult* result,
+                      double* x2,
+                      double* y2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_C_API_PLANAR_TRACKER_H_
diff --git a/extern/libmv/intern/tracks.cc b/extern/libmv/intern/tracks.cc
new file mode 100644 (file)
index 0000000..9b032b0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ***** 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/tracks.h"
+#include "intern/utildefines.h"
+
+#include "libmv/simple_pipeline/tracks.h"
+
+using libmv::Marker;
+using libmv::Tracks;
+
+libmv_Tracks* libmv_tracksNew(void) {
+  Tracks* tracks = LIBMV_OBJECT_NEW(Tracks);
+
+  return (libmv_Tracks*) tracks;
+}
+
+void libmv_tracksDestroy(libmv_Tracks* libmv_tracks) {
+  LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
+}
+
+void libmv_tracksInsert(libmv_Tracks *libmv_tracks,
+                        int image,
+                        int track,
+                        double x,
+                        double y,
+                        double weight) {
+  ((Tracks *) libmv_tracks)->Insert(image, track, x, y, weight);
+}
diff --git a/extern/libmv/intern/tracks.h b/extern/libmv/intern/tracks.h
new file mode 100644 (file)
index 0000000..79f6cc9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef LIBMV_C_API_TRACKS_H_
+#define LIBMV_C_API_TRACKS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_Tracks libmv_Tracks;
+
+libmv_Tracks* libmv_tracksNew(void);
+
+void libmv_tracksDestroy(libmv_Tracks* libmv_tracks);
+
+void libmv_tracksInsert(libmv_Tracks* libmv_tracks,
+                        int image,
+                        int track,
+                        double x,
+                        double y,
+                        double weight);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LIBMV_C_API_TRACKS_H_
similarity index 81%
rename from extern/libmv/libmv-capi_intern.h
rename to extern/libmv/intern/utildefines.h
index 90087c52a6c2fb03ff75d8979f085aa68945c57b..7366b242cf75524887168b3141c9e705d3fd9683 100644 (file)
@@ -23,8 +23,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifndef LIBMV_C_API_INTERN_H
-#define LIBMV_C_API_INTERN_H
+#ifndef LIBMV_C_API_UTILDEFINES_H_
+#define LIBMV_C_API_UTILDEFINES_H_
 
 #if defined(_MSC_VER)
 #  define __func__ __FUNCTION__
 #  define LIBMV_OBJECT_NEW OBJECT_GUARDED_NEW
 #  define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
 #  define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
-#  define LIBMV_STRUCT_NEW(type, count) (type*)MEM_mallocN(sizeof(type) * count, __func__)
+#  define LIBMV_STRUCT_NEW(type, count) \
+  (type*)MEM_mallocN(sizeof(type) * count, __func__)
 #  define LIBMV_STRUCT_DELETE(what) MEM_freeN(what)
 #else
 // Need this to keep libmv-capi potentially standalone.
 #  if defined __GNUC__ || defined __sun
 #    define LIBMV_OBJECT_NEW(type, args ...) \
-       new(malloc(sizeof(type))) type(args)
+  new(malloc(sizeof(type))) type(args)
 #  else
 #    define LIBMV_OBJECT_NEW(type, ...) \
-       new(malloc(sizeof(type))) type(__VA_ARGS__)
+  new(malloc(sizeof(type))) type(__VA_ARGS__)
 #endif
 #  define LIBMV_OBJECT_DELETE(what, type) \
-       { if(what) { \
-                       ((type*)(what))->~type(); \
-                       free(what); \
-       } } (void)0
+  { \
+    if (what) { \
+      ((type*)(what))->~type(); \
+      free(what); \
+    } \
+  } (void)0
 #  define LIBMV_STRUCT_NEW(type, count) (type*)malloc(sizeof(type) * count)
 #  define LIBMV_STRUCT_DELETE(what) { if (what) free(what); } (void)0
 #endif
 
-#endif  // LIBMV_C_API_INTERN_H
+#endif  // LIBMV_C_API_UTILDEFINES_H_
diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc
deleted file mode 100644 (file)
index 82143d5..0000000
+++ /dev/null
@@ -1,1185 +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 *****
- */
-
-#ifdef WITH_LIBMV
-
-/* define this to generate PNG images with content of search areas
-   tracking between which failed */
-#undef DUMP_FAILURE
-
-/* define this to generate PNG images with content of search areas
-   on every itteration of tracking */
-#undef DUMP_ALWAYS
-
-#include "libmv-capi.h"
-#include "libmv-util.h"
-
-#include <cassert>
-
-#include "libmv-capi_intern.h"
-#include "libmv/logging/logging.h"
-#include "libmv/multiview/homography.h"
-#include "libmv/tracking/track_region.h"
-#include "libmv/simple_pipeline/callbacks.h"
-#include "libmv/simple_pipeline/tracks.h"
-#include "libmv/simple_pipeline/initialize_reconstruction.h"
-#include "libmv/simple_pipeline/bundle.h"
-#include "libmv/simple_pipeline/detect.h"
-#include "libmv/simple_pipeline/pipeline.h"
-#include "libmv/simple_pipeline/camera_intrinsics.h"
-#include "libmv/simple_pipeline/modal_solver.h"
-#include "libmv/simple_pipeline/reconstruction_scale.h"
-#include "libmv/simple_pipeline/keyframe_selection.h"
-
-#ifdef _MSC_VER
-#  define snprintf _snprintf
-#endif
-
-using libmv::CameraIntrinsics;
-using libmv::DetectOptions;
-using libmv::DivisionCameraIntrinsics;
-using libmv::EuclideanCamera;
-using libmv::EuclideanPoint;
-using libmv::EuclideanReconstruction;
-using libmv::EuclideanScaleToUnity;
-using libmv::Feature;
-using libmv::FloatImage;
-using libmv::Marker;
-using libmv::PolynomialCameraIntrinsics;
-using libmv::ProgressUpdateCallback;
-using libmv::Tracks;
-using libmv::TrackRegionOptions;
-using libmv::TrackRegionResult;
-
-using libmv::Detect;
-using libmv::EuclideanBundle;
-using libmv::EuclideanCompleteReconstruction;
-using libmv::EuclideanReconstructTwoFrames;
-using libmv::EuclideanReprojectionError;
-using libmv::TrackRegion;
-using libmv::SamplePlanarPatch;
-
-typedef struct libmv_Tracks libmv_Tracks;
-typedef struct libmv_Reconstruction libmv_Reconstruction;
-typedef struct libmv_Features libmv_Features;
-typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
-
-struct libmv_Reconstruction {
-       EuclideanReconstruction reconstruction;
-
-       /* used for per-track average error calculation after reconstruction */
-       Tracks tracks;
-       CameraIntrinsics *intrinsics;
-
-       double error;
-};
-
-struct libmv_Features {
-       int count;
-       Feature *features;
-};
-
-/* ************ Logging ************ */
-
-void libmv_initLogging(const char *argv0)
-{
-       /* Make it so FATAL messages are always print into console */
-       char severity_fatal[32];
-       snprintf(severity_fatal, sizeof(severity_fatal), "%d",
-                google::GLOG_FATAL);
-
-       google::InitGoogleLogging(argv0);
-       google::SetCommandLineOption("logtostderr", "1");
-       google::SetCommandLineOption("v", "0");
-       google::SetCommandLineOption("stderrthreshold", severity_fatal);
-       google::SetCommandLineOption("minloglevel", severity_fatal);
-}
-
-void libmv_startDebugLogging(void)
-{
-       google::SetCommandLineOption("logtostderr", "1");
-       google::SetCommandLineOption("v", "2");
-       google::SetCommandLineOption("stderrthreshold", "1");
-       google::SetCommandLineOption("minloglevel", "0");
-}
-
-void libmv_setLoggingVerbosity(int verbosity)
-{
-       char val[10];
-       snprintf(val, sizeof(val), "%d", verbosity);
-
-       google::SetCommandLineOption("v", val);
-}
-
-/* ************ Planar tracker ************ */
-
-/* TrackRegion */
-int libmv_trackRegion(const libmv_TrackRegionOptions *options,
-                      const float *image1, int image1_width, int image1_height,
-                      const float *image2, int image2_width, int image2_height,
-                      const double *x1, const double *y1,
-                      libmv_TrackRegionResult *result,
-                      double *x2, double *y2)
-{
-       double xx1[5], yy1[5];
-       double xx2[5], yy2[5];
-       bool tracking_result = false;
-
-       /* Convert to doubles for the libmv api. The four corners and the center. */
-       for (int i = 0; i < 5; ++i) {
-               xx1[i] = x1[i];
-               yy1[i] = y1[i];
-               xx2[i] = x2[i];
-               yy2[i] = y2[i];
-       }
-
-       TrackRegionOptions track_region_options;
-       FloatImage image1_mask;
-
-       switch (options->motion_model) {
-#define LIBMV_CONVERT(the_model) \
-       case TrackRegionOptions::the_model: \
-               track_region_options.mode = TrackRegionOptions::the_model; \
-               break;
-               LIBMV_CONVERT(TRANSLATION)
-               LIBMV_CONVERT(TRANSLATION_ROTATION)
-               LIBMV_CONVERT(TRANSLATION_SCALE)
-               LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
-               LIBMV_CONVERT(AFFINE)
-               LIBMV_CONVERT(HOMOGRAPHY)
-#undef LIBMV_CONVERT
-       }
-
-       track_region_options.minimum_correlation = options->minimum_correlation;
-       track_region_options.max_iterations = options->num_iterations;
-       track_region_options.sigma = options->sigma;
-       track_region_options.num_extra_points = 1;
-       track_region_options.image1_mask = NULL;
-       track_region_options.use_brute_initialization = options->use_brute;
-       /* TODO(keir): This will make some cases better, but may be a regression until
-        * the motion model is in. Since this is on trunk, enable it for now.
-        *
-        * TODO(sergey): This gives much worse results on mango footage (see 04_2e)
-        * so disabling for now for until proper prediction model is landed.
-        *
-        * The thing is, currently blender sends input coordinates as the guess to
-        * region tracker and in case of fast motion such an early out ruins the track.
-        */
-       track_region_options.attempt_refine_before_brute = false;
-       track_region_options.use_normalized_intensities = options->use_normalization;
-
-       if (options->image1_mask) {
-               libmv_floatBufferToImage(options->image1_mask,
-                                        image1_width, image1_height, 1,
-                                        &image1_mask);
-
-               track_region_options.image1_mask = &image1_mask;
-       }
-
-       /* Convert from raw float buffers to libmv's FloatImage. */
-       FloatImage old_patch, new_patch;
-       libmv_floatBufferToImage(image1,
-                                image1_width, image1_height, 1,
-                                &old_patch);
-       libmv_floatBufferToImage(image2,
-                                image2_width, image2_height, 1,
-                                &new_patch);
-
-       TrackRegionResult track_region_result;
-       TrackRegion(old_patch, new_patch,
-                   xx1, yy1,
-                   track_region_options,
-                   xx2, yy2,
-                   &track_region_result);
-
-       /* Convert to floats for the blender api. */
-       for (int i = 0; i < 5; ++i) {
-               x2[i] = xx2[i];
-               y2[i] = yy2[i];
-       }
-
-       /* TODO(keir): Update the termination string with failure details. */
-       if (track_region_result.termination == TrackRegionResult::CONVERGENCE ||
-           track_region_result.termination == TrackRegionResult::NO_CONVERGENCE)
-       {
-               tracking_result = true;
-       }
-
-       /* Debug dump of patches. */
-#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
-       {
-               bool need_dump = !tracking_result;
-
-#  ifdef DUMP_ALWAYS
-               need_dump = true;
-#  endif
-
-               if (need_dump) {
-                       libmv_saveImage(old_patch, "old_patch", x1[4], y1[4]);
-                       libmv_saveImage(new_patch, "new_patch", x2[4], y2[4]);
-
-                       if (options->image1_mask) {
-                               libmv_saveImage(image1_mask, "mask", x2[4], y2[4]);
-                       }
-               }
-       }
-#endif
-
-       return tracking_result;
-}
-
-void libmv_samplePlanarPatch(const float *image,
-                             int width, int height, int channels,
-                             const double *xs, const double *ys,
-                             int num_samples_x, int num_samples_y,
-                             const float *mask,
-                             float *patch,
-                             double *warped_position_x,
-                             double *warped_position_y)
-{
-       FloatImage libmv_image, libmv_patch, libmv_mask;
-       FloatImage *libmv_mask_for_sample = NULL;
-
-       libmv_floatBufferToImage(image, width, height, channels, &libmv_image);
-
-       if (mask) {
-               libmv_floatBufferToImage(mask, width, height, 1, &libmv_mask);
-
-               libmv_mask_for_sample = &libmv_mask;
-       }
-
-       SamplePlanarPatch(libmv_image,
-                         xs, ys,
-                         num_samples_x, num_samples_y,
-                         libmv_mask_for_sample,
-                         &libmv_patch,
-                         warped_position_x,
-                         warped_position_y);
-
-       libmv_imageToFloatBuffer(libmv_patch, patch);
-}
-
- void libmv_samplePlanarPatchByte(const unsigned char *image,
-                                  int width, int height, int channels,
-                                  const double *xs, const double *ys,
-                                  int num_samples_x, int num_samples_y,
-                                  const float *mask,
-                                  unsigned char *patch,
-                                  double *warped_position_x, double *warped_position_y)
-{
-       libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
-       libmv::FloatImage *libmv_mask_for_sample = NULL;
-
-       libmv_byteBufferToImage(image, width, height, channels, &libmv_image);
-
-       if (mask) {
-               libmv_floatBufferToImage(mask, width, height, 1, &libmv_mask);
-
-               libmv_mask_for_sample = &libmv_mask;
-       }
-
-       libmv::SamplePlanarPatch(libmv_image, xs, ys,
-                                num_samples_x, num_samples_y,
-                                libmv_mask_for_sample,
-                                &libmv_patch,
-                                warped_position_x,
-                                warped_position_y);
-
-       libmv_imageToByteBuffer(libmv_patch, patch);
-}
-
-/* ************ Tracks ************ */
-
-libmv_Tracks *libmv_tracksNew(void)
-{
-       Tracks *libmv_tracks = LIBMV_OBJECT_NEW(Tracks);
-
-       return (libmv_Tracks *) libmv_tracks;
-}
-
-void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
-{
-       LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
-}
-
-void libmv_tracksInsert(libmv_Tracks *libmv_tracks,
-                        int image, int track,
-                        double x, double y,
-                        double weight)
-{
-       ((Tracks *) libmv_tracks)->Insert(image, track, x, y, weight);
-}
-
-/* ************ Reconstruction ************ */
-
-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;
-}
-
-}  // 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();
-
-       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);
-
-       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);
-
-       return (libmv_Reconstruction *) libmv_reconstruction;
-}
-
-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;
-}
-
-/* ************ Feature detector ************ */
-
-static libmv_Features *libmv_featuresFromVector(
-       const libmv::vector<Feature> &features)
-{
-       libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
-       int count = features.size();
-       if (count) {
-               libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
-
-               for (int i = 0; i < count; i++) {
-                       libmv_features->features[i] = features.at(i);
-               }
-       }
-       else {
-               libmv_features->features = NULL;
-       }
-
-       libmv_features->count = count;
-
-       return libmv_features;
-}
-
-static void libmv_convertDetectorOptions(libmv_DetectOptions *options,
-                                         DetectOptions *detector_options)
-{
-       switch (options->detector) {
-#define LIBMV_CONVERT(the_detector) \
-       case LIBMV_DETECTOR_ ## the_detector: \
-               detector_options->type = DetectOptions::the_detector; \
-               break;
-               LIBMV_CONVERT(FAST)
-               LIBMV_CONVERT(MORAVEC)
-               LIBMV_CONVERT(HARRIS)
-#undef LIBMV_CONVERT
-       }
-       detector_options->margin = options->margin;
-       detector_options->min_distance = options->min_distance;
-       detector_options->fast_min_trackness = options->fast_min_trackness;
-       detector_options->moravec_max_count = options->moravec_max_count;
-       detector_options->moravec_pattern = options->moravec_pattern;
-       detector_options->harris_threshold = options->harris_threshold;
-}
-
-libmv_Features *libmv_detectFeaturesByte(
-       const unsigned char *image_buffer,
-       int width, int height,
-       int channels,
-       libmv_DetectOptions *options)
-{
-       // Prepare the image.
-       FloatImage image;
-       libmv_byteBufferToImage(image_buffer, width, height, channels, &image);
-
-       // Configure detector.
-       DetectOptions detector_options;
-       libmv_convertDetectorOptions(options, &detector_options);
-
-       // Run the detector.
-       libmv::vector<Feature> detected_features;
-       Detect(image, detector_options, &detected_features);
-
-       // Convert result to C-API.
-       libmv_Features *result = libmv_featuresFromVector(detected_features);
-       return result;
-}
-
-libmv_Features *libmv_detectFeaturesFloat(const float *image_buffer,
-                                          int width, int height,
-                                          int channels,
-                                          libmv_DetectOptions *options)
-{
-       // Prepare the image.
-       FloatImage image;
-       libmv_floatBufferToImage(image_buffer, width, height, channels, &image);
-
-       // Configure detector.
-       DetectOptions detector_options;
-       libmv_convertDetectorOptions(options, &detector_options);
-
-       // Run the detector.
-       libmv::vector<Feature> detected_features;
-       Detect(image, detector_options, &detected_features);
-
-       // Convert result to C-API.
-       libmv_Features *result = libmv_featuresFromVector(detected_features);
-       return result;
-}
-
-void libmv_featuresDestroy(libmv_Features *libmv_features)
-{
-       if (libmv_features->features) {
-               LIBMV_STRUCT_DELETE(libmv_features->features);
-       }
-
-       LIBMV_STRUCT_DELETE(libmv_features);
-}
-
-int libmv_countFeatures(const libmv_Features *libmv_features)
-{
-       return libmv_features->count;
-}
-
-void libmv_getFeature(const libmv_Features *libmv_features,
-                      int number,
-                      double *x, double *y, double *score, double *size)
-{
-       Feature &feature = libmv_features->features[number];
-
-       *x = feature.x;
-       *y = feature.y;
-       *score = feature.score;
-       *size = feature.size;
-}
-
-/* ************ Camera intrinsics ************ */
-
-libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
-       const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
-{
-       CameraIntrinsics *camera_intrinsics =
-               libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
-       return (libmv_CameraIntrinsics *) camera_intrinsics;
-}
-
-libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
-       const libmv_CameraIntrinsics *libmvIntrinsics)
-{
-       const CameraIntrinsics *orig_intrinsics =
-               (const CameraIntrinsics *) libmvIntrinsics;
-
-       CameraIntrinsics *new_intrinsics = NULL;
-
-       switch (orig_intrinsics->GetDistortionModelType()) {
-               case libmv::DISTORTION_MODEL_POLYNOMIAL:
-               {
-                       const PolynomialCameraIntrinsics *polynomial_intrinsics =
-                               static_cast<const PolynomialCameraIntrinsics*>(orig_intrinsics);
-                       new_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics,
-                                                                *polynomial_intrinsics);
-                       break;
-               }
-               case libmv::DISTORTION_MODEL_DIVISION:
-               {
-                       const DivisionCameraIntrinsics *division_intrinsics =
-                               static_cast<const DivisionCameraIntrinsics*>(orig_intrinsics);
-                       new_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics,
-                                                                *division_intrinsics);
-                       break;
-               }
-               default:
-                       assert(!"Unknown distortion model");
-       }
-
-       return (libmv_CameraIntrinsics *) new_intrinsics;
-}
-
-void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics *libmvIntrinsics)
-{
-       LIBMV_OBJECT_DELETE(libmvIntrinsics, CameraIntrinsics);
-}
-
-void libmv_cameraIntrinsicsUpdate(
-       const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-       libmv_CameraIntrinsics *libmv_intrinsics)
-{
-       CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
-
-       double focal_length = libmv_camera_intrinsics_options->focal_length;
-       double principal_x = libmv_camera_intrinsics_options->principal_point_x;
-       double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-       int image_width = libmv_camera_intrinsics_options->image_width;
-       int image_height = libmv_camera_intrinsics_options->image_height;
-
-       /* Try avoid unnecessary updates,
-        * so pre-computed distortion grids are not freed.
-        */
-
-       if (camera_intrinsics->focal_length() != focal_length)
-               camera_intrinsics->SetFocalLength(focal_length, focal_length);
-
-       if (camera_intrinsics->principal_point_x() != principal_x ||
-           camera_intrinsics->principal_point_y() != principal_y)
-       {
-               camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
-       }
-
-       if (camera_intrinsics->image_width() != image_width ||
-           camera_intrinsics->image_height() != image_height)
-       {
-               camera_intrinsics->SetImageSize(image_width, image_height);
-       }
-
-       switch (libmv_camera_intrinsics_options->distortion_model) {
-               case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
-               {
-                       assert(camera_intrinsics->GetDistortionModelType() ==
-                                  libmv::DISTORTION_MODEL_POLYNOMIAL);
-
-                       PolynomialCameraIntrinsics *polynomial_intrinsics =
-                               (PolynomialCameraIntrinsics *) camera_intrinsics;
-
-                       double k1 = libmv_camera_intrinsics_options->polynomial_k1;
-                       double k2 = libmv_camera_intrinsics_options->polynomial_k2;
-                       double k3 = libmv_camera_intrinsics_options->polynomial_k3;
-
-                       if (polynomial_intrinsics->k1() != k1 ||
-                           polynomial_intrinsics->k2() != k2 ||
-                           polynomial_intrinsics->k3() != k3)
-                       {
-                               polynomial_intrinsics->SetRadialDistortion(k1, k2, k3);
-                       }
-
-                       break;
-               }
-
-               case LIBMV_DISTORTION_MODEL_DIVISION:
-               {
-                       assert(camera_intrinsics->GetDistortionModelType() ==
-                                  libmv::DISTORTION_MODEL_DIVISION);
-
-                       DivisionCameraIntrinsics *division_intrinsics =
-                               (DivisionCameraIntrinsics *) camera_intrinsics;
-
-                       double k1 = libmv_camera_intrinsics_options->division_k1;
-                       double k2 = libmv_camera_intrinsics_options->division_k2;
-
-                       if (division_intrinsics->k1() != k1 ||
-                           division_intrinsics->k2() != k2)
-                       {
-                               division_intrinsics->SetDistortion(k1, k2);
-                       }
-
-                       break;
-               }
-
-               default:
-                       assert(!"Unknown distortion model");
-       }
-}
-
-void libmv_cameraIntrinsicsSetThreads(
-       libmv_CameraIntrinsics *libmv_intrinsics, int threads)
-{
-       CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
-
-       camera_intrinsics->SetThreads(threads);
-}
-
-void libmv_cameraIntrinsicsExtractOptions(
-       const libmv_CameraIntrinsics *libmv_intrinsics,
-       libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
-       const CameraIntrinsics *camera_intrinsics =
-               (const CameraIntrinsics *) libmv_intrinsics;
-
-       // Fill in options which are common for all distortion models.
-       camera_intrinsics_options->focal_length = camera_intrinsics->focal_length();
-       camera_intrinsics_options->principal_point_x =
-               camera_intrinsics->principal_point_x();
-       camera_intrinsics_options->principal_point_y =
-               camera_intrinsics->principal_point_y();
-
-       camera_intrinsics_options->image_width = camera_intrinsics->image_width();
-       camera_intrinsics_options->image_height = camera_intrinsics->image_height();
-
-       switch (camera_intrinsics->GetDistortionModelType()) {
-               case libmv::DISTORTION_MODEL_POLYNOMIAL:
-               {
-                       const PolynomialCameraIntrinsics *polynomial_intrinsics =
-                               static_cast<const PolynomialCameraIntrinsics *>(camera_intrinsics);
-                       camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_POLYNOMIAL;
-                       camera_intrinsics_options->polynomial_k1 = polynomial_intrinsics->k1();
-                       camera_intrinsics_options->polynomial_k2 = polynomial_intrinsics->k2();
-                       camera_intrinsics_options->polynomial_k3 = polynomial_intrinsics->k3();
-                       camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p1();
-                       camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p2();
-                       break;
-               }
-
-               case libmv::DISTORTION_MODEL_DIVISION:
-               {
-                       const DivisionCameraIntrinsics *division_intrinsics =
-                               static_cast<const DivisionCameraIntrinsics *>(camera_intrinsics);
-                       camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_DIVISION;
-                       camera_intrinsics_options->division_k1 = division_intrinsics->k1();
-                       camera_intrinsics_options->division_k2 = division_intrinsics->k2();
-                       break;
-               }
-
-               default:
-                       assert(!"Uknown distortion model");
-       }
-}
-
-void libmv_cameraIntrinsicsUndistortByte(
-       const libmv_CameraIntrinsics *libmv_intrinsics,
-       unsigned char *src, unsigned char *dst, int width, int height,
-       float overscan, int channels)
-{
-       CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
-       camera_intrinsics->UndistortBuffer(src,
-                                          width, height, overscan, channels,
-                                          dst);
-}
-
-void libmv_cameraIntrinsicsUndistortFloat(
-       const libmv_CameraIntrinsics *libmvIntrinsics,
-       float *src, float *dst, int width, int height,
-       float overscan, int channels)
-{
-       CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
-       intrinsics->UndistortBuffer(src,
-                                   width, height, overscan, channels,
-                                   dst);
-}
-
-void libmv_cameraIntrinsicsDistortByte(
-       const libmv_CameraIntrinsics *libmvIntrinsics,
-       unsigned char *src, unsigned char *dst, int width, int height,
-       float overscan, int channels)
-{
-       CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
-       intrinsics->DistortBuffer(src,
-                                 width, height, overscan, channels,
-                                 dst);
-}
-
-void libmv_cameraIntrinsicsDistortFloat(
-       const libmv_CameraIntrinsics *libmvIntrinsics,
-       float *src, float *dst, int width, int height,
-       float overscan, int channels)
-{
-       CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
-       intrinsics->DistortBuffer(src,
-                                 width, height, overscan, channels,
-                                 dst);
-}
-
-void libmv_cameraIntrinsicsApply(
-       const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-       double x, double y, double *x1, double *y1)
-{
-       /* do a lens undistortion if focal length is non-zero only */
-       if (libmv_camera_intrinsics_options->focal_length) {
-               CameraIntrinsics *camera_intrinsics =
-                       libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
-               camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
-
-               LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
-       }
-}
-
-void libmv_cameraIntrinsicsInvert(
-       const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-       double x, double y, double *x1, double *y1)
-{
-       /* do a lens distortion if focal length is non-zero only */
-       if (libmv_camera_intrinsics_options->focal_length) {
-               CameraIntrinsics *camera_intrinsics =
-                       libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
-               camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
-
-               LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
-       }
-}
-
-void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2],
-                                              double (*x2)[2],
-                                              int num_points,
-                                              double H[3][3])
-{
-       libmv::Mat x1_mat, x2_mat;
-       libmv::Mat3 H_mat;
-
-       x1_mat.resize(2, num_points);
-       x2_mat.resize(2, num_points);
-
-       for (int i = 0; i < num_points; i++) {
-               x1_mat.col(i) = libmv::Vec2(x1[i][0], x1[i][1]);
-               x2_mat.col(i) = libmv::Vec2(x2[i][0], x2[i][1]);
-       }
-
-       LG << "x1: " << x1_mat;
-       LG << "x2: " << x2_mat;
-
-       libmv::EstimateHomographyOptions options;
-       libmv::EstimateHomography2DFromCorrespondences(x1_mat,
-                                                      x2_mat,
-                                                      options,
-                                                      &H_mat);
-
-       LG << "H: " << H_mat;
-
-       memcpy(H, H_mat.data(), 9 * sizeof(double));
-}
-
-#endif
index 5cd9936723bfbae4c32d946428a2e645bbc4c5c0..524f1822bc72953e00d4d7bacf0249d5c79861eb 100644 (file)
 #ifndef LIBMV_C_API_H
 #define LIBMV_C_API_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct libmv_Tracks;
-struct libmv_Reconstruction;
-struct libmv_Features;
-struct libmv_CameraIntrinsics;
-
-/* Logging */
-void libmv_initLogging(const char *argv0);
-void libmv_startDebugLogging(void);
-void libmv_setLoggingVerbosity(int verbosity);
-
-/* Planar tracker */
-typedef struct libmv_TrackRegionOptions {
-       int motion_model;
-       int num_iterations;
-       int use_brute;
-       int use_normalization;
-       double minimum_correlation;
-       double sigma;
-       float *image1_mask;
-} libmv_TrackRegionOptions;
-
-typedef struct libmv_TrackRegionResult {
-       int termination;
-       const char *termination_reason;
-       double correlation;
-} libmv_TrackRegionResult;
-
-int libmv_trackRegion(const libmv_TrackRegionOptions *options,
-                      const float *image1, int image1_width, int image1_height,
-                      const float *image2, int image2_width, int image2_height,
-                      const double *x1, const double *y1,
-                      libmv_TrackRegionResult *result,
-                      double *x2, double *y2);
-void libmv_samplePlanarPatch(const float *image,
-                             int width, int height,
-                             int channels,
-                             const double *xs, const double *ys,
-                             int num_samples_x, int num_samples_y,
-                             const float *mask,
-                             float *patch,
-                             double *warped_position_x, double *warped_position_y);
-void libmv_samplePlanarPatchByte(const unsigned char *image,
-                                 int width, int height,
-                                 int channels,
-                                 const double *xs, const double *ys,
-                                 int num_samples_x, int num_samples_y,
-                                 const float *mask,
-                                 unsigned char *patch,
-                                 double *warped_position_x, double *warped_position_y);
-
-/* Tracks */
-struct libmv_Tracks *libmv_tracksNew(void);
-void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks);
-void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y, double weight);
-
-/* Reconstruction */
-#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)
-
-enum {
-       LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0,
-       LIBMV_DISTORTION_MODEL_DIVISION = 1,
-};
-
-typedef struct libmv_CameraIntrinsicsOptions {
-       /* Common settings of all distortion models. */
-       int distortion_model;
-       int image_width, image_height;
-       double focal_length;
-       double principal_point_x, principal_point_y;
-
-       /* Radial distortion model. */
-       double polynomial_k1, polynomial_k2, polynomial_k3;
-       double polynomial_p1, polynomial_p2;
-
-       /* Division distortion model. */
-       double division_k1, division_k2;
-} libmv_CameraIntrinsicsOptions;
-
-typedef struct libmv_ReconstructionOptions {
-       int select_keyframes;
-       int keyframe1, keyframe2;
-
-       int refine_intrinsics;
-} libmv_ReconstructionOptions;
-
-typedef void (*reconstruct_progress_update_cb) (void *customdata, double progress, const char *message);
-
-struct libmv_Reconstruction *libmv_solveReconstruction(const struct 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);
-struct libmv_Reconstruction *libmv_solveModal(const struct 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);
-void libmv_reconstructionDestroy(struct libmv_Reconstruction *libmv_reconstruction);
-int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]);
-double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track);
-double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_reconstruction, int image);
-int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction *libmv_reconstruction,
-                                     int image, double mat[4][4]);
-double libmv_reprojectionError(const struct libmv_Reconstruction *libmv_reconstruction);
-struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(struct libmv_Reconstruction *libmv_Reconstruction);
-
-/* Feature detector */
-enum {
-       LIBMV_DETECTOR_FAST,
-       LIBMV_DETECTOR_MORAVEC,
-       LIBMV_DETECTOR_HARRIS,
-};
-
-typedef struct libmv_DetectOptions {
-  int detector;
-  int margin;
-  int min_distance;
-  int fast_min_trackness;
-  int moravec_max_count;
-  unsigned char *moravec_pattern;
-  double harris_threshold;
-} libmv_DetectOptions;
-
-struct libmv_Features *libmv_detectFeaturesByte(const unsigned char *image_buffer,
-                                                int width, int height, int channels,
-                                                libmv_DetectOptions *options);
-struct libmv_Features *libmv_detectFeaturesFloat(const float *image_buffer,
-                                                 int width, int height, int channels,
-                                                 libmv_DetectOptions *options);
-
-void libmv_featuresDestroy(struct libmv_Features *libmv_features);
-int libmv_countFeatures(const struct libmv_Features *libmv_features);
-void libmv_getFeature(const struct libmv_Features *libmv_features, int number, double *x, double *y, double *score,
-                      double *size);
-
-/* Camera intrinsics */
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
-               const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options);
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const struct libmv_CameraIntrinsics *libmv_intrinsics);
-void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmv_intrinsics);
-void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-                                  struct libmv_CameraIntrinsics *libmv_intrinsics);
-void libmv_cameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics *libmv_intrinsics, int threads);
-void libmv_cameraIntrinsicsExtractOptions(
-       const struct libmv_CameraIntrinsics *libmv_intrinsics,
-       struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
-void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics,
-                                         unsigned char *src, unsigned char *dst, int width, int height,
-                                         float overscan, int channels);
-void libmv_cameraIntrinsicsUndistortFloat(const struct libmv_CameraIntrinsics *libmv_intrinsics,
-                                          float *src, float *dst, int width, int height,
-                                          float overscan, int channels);
-void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics,
-                                       unsigned char *src, unsigned char *dst, int width, int height,
-                                       float overscan, int channels);
-void libmv_cameraIntrinsicsDistortFloat(const struct libmv_CameraIntrinsics *libmv_intrinsics,
-                                        float *src, float *dst, int width, int height,
-                                        float overscan, int channels);
-void libmv_cameraIntrinsicsApply(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-                                 double x, double y, double *x1, double *y1);
-void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-                                  double x, double y, double *x1, double *y1);
-
-void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2], double (*x2)[2], int num_points, double H[3][3]);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LIBMV_C_API_H
+#include "intern/camera_intrinsics.h"
+#include "intern/detector.h"
+#include "intern/homography.h"
+#include "intern/image.h"
+#include "intern/logging.h"
+#include "intern/reconstruction.h"
+#include "intern/track_region.h"
+#include "intern/tracks.h"
+
+#endif  // LIBMV_C_API_H
diff --git a/extern/libmv/libmv-capi_stub.cc b/extern/libmv/libmv-capi_stub.cc
deleted file mode 100644 (file)
index 36a3bc7..0000000
+++ /dev/null
@@ -1,293 +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) 2013 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- *                 Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef WITH_LIBMV
-
-#include "libmv-capi.h"
-
-#include <cstdlib>
-#include <cstring>
-
-/* ************ Logging ************ */
-
-void libmv_initLogging(const char * /*argv0*/)
-{
-}
-
-void libmv_startDebugLogging(void)
-{
-}
-
-void libmv_setLoggingVerbosity(int /*verbosity*/)
-{
-}
-
-/* ************ Planar tracker ************ */
-
-/* TrackRegion (new planar tracker) */
-int libmv_trackRegion(const libmv_TrackRegionOptions * /*options*/,
-                      const float * /*image1*/, int /*image1_width*/, int /*image1_height*/,
-                      const float * /*image2*/, int /*image2_width*/, int /*image2_height*/,
-                      const double *x1, const double *y1,
-                      libmv_TrackRegionResult *result,
-                      double *x2, double *y2)
-{
-       /* Convert to doubles for the libmv api. The four corners and the center. */
-       for (int i = 0; i < 5; ++i) {
-               x2[i] = x1[i];
-               y2[i] = y1[i];
-       }
-
-       result->termination = -1;
-       result->termination_reason = "Built without libmv support";
-       result->correlation = 0.0;
-
-       return false;
-}
-
-void libmv_samplePlanarPatch(const float * /*image*/,
-                             int /*width*/, int /*height*/, int /*channels*/,
-                             const double * /*xs*/, const double * /*ys*/,
-                             int /*num_samples_x*/, int /*num_samples_y*/,
-                             const float * /*mask*/,
-                             float * /*patch*/,
-                             double * /*warped_position_x*/, double * /*warped_position_y*/)
-{
-       /* TODO(sergey): implement */
-}
-
-void libmv_samplePlanarPatchByte(const unsigned char * /*image*/,
-                             int /*width*/, int /*height*/, int /*channels*/,
-                             const double * /*xs*/, const double * /*ys*/,
-                             int /*num_samples_x*/, int /*num_samples_y*/,
-                             const float * /*mask*/,
-                             unsigned char * /*patch*/,
-                             double * /*warped_position_x*/, double * /*warped_position_y*/)
-{
-       /* TODO(sergey): implement */
-}
-
-/* ************ Tracks ************ */
-
-struct libmv_Tracks *libmv_tracksNew(void)
-{
-       return NULL;
-}
-
-void libmv_tracksInsert(struct libmv_Tracks * /*libmv_tracks*/, int /*image*/,
-                        int /*track*/, double /*x*/, double /*y*/, double /*weight*/)
-{
-}
-
-void libmv_tracksDestroy(struct libmv_Tracks * /*libmv_tracks*/)
-{
-}
-
-/* ************ Reconstruction solver ************ */
-
-struct libmv_Reconstruction *libmv_solveReconstruction(const struct 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*/)
-{
-       return NULL;
-}
-
-struct libmv_Reconstruction *libmv_solveModal(const struct 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*/)
-{
-       return NULL;
-}
-
-int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction * /*libmv_reconstruction*/,
-                                     int /*track*/, double /*pos*/[3])
-{
-       return 0;
-}
-
-double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction * /*libmv_reconstruction*/, int /*track*/)
-{
-       return 0.0;
-}
-
-double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction * /*libmv_reconstruction*/, int /*image*/)
-{
-       return 0.0;
-}
-
-int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction * /*libmv_reconstruction*/, int /*image*/,
-                                      double /*mat*/[4][4])
-{
-       return 0;
-}
-
-double libmv_reprojectionError(const struct libmv_Reconstruction * /*libmv_reconstruction*/)
-{
-       return 0.0;
-}
-
-void libmv_reconstructionDestroy(struct libmv_Reconstruction * /*libmv_reconstruction*/)
-{
-}
-
-/* ************ feature detector ************ */
-
-struct libmv_Features *libmv_detectFeaturesByte(const unsigned char */*image_buffer*/,
-                                                int /*width*/, int /*height*/, int /*channels*/,
-                                                libmv_DetectOptions */*options*/)
-{
-       return NULL;
-}
-
-struct libmv_Features *libmv_detectFeaturesFloat(const float */*image_buffer*/,
-                                                 int /*width*/, int /*height*/, int /*channels*/,
-                                                 libmv_DetectOptions */*options*/)
-{
-       return NULL;
-}
-
-int libmv_countFeatures(const struct libmv_Features * /*libmv_features*/)
-{
-       return 0;
-}
-
-void libmv_getFeature(const struct libmv_Features * /*libmv_features*/, int /*number*/,
-                      double *x, double *y, double *score, double *size)
-{
-       *x = 0.0;
-       *y = 0.0;
-       *score = 0.0;
-       *size = 0.0;
-}
-
-void libmv_featuresDestroy(struct libmv_Features * /*libmv_features*/)
-{
-}
-
-/* ************ camera intrinsics ************ */
-
-struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
-               struct libmv_Reconstruction * /*libmv_reconstruction*/)
-{
-       return NULL;
-}
-
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
-               const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/)
-{
-       return NULL;
-}
-
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics * /*libmvIntrinsics*/)
-{
-       return NULL;
-}
-
-void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics * /*libmvIntrinsics*/)
-{
-}
-
-void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
-                                  struct libmv_CameraIntrinsics * /*libmv_intrinsics*/)
-{
-}
-
-void libmv_cameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics * /*libmv_intrinsics*/, int /*threads*/)
-{
-}
-
-void libmv_cameraIntrinsicsExtractOptions(
-       const libmv_CameraIntrinsics */*libmv_intrinsics*/,
-       libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
-       memset(camera_intrinsics_options, 0, sizeof(libmv_CameraIntrinsicsOptions));
-       camera_intrinsics_options->focal_length = 1.0;
-}
-
-void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics * /*libmv_intrinsics*/,
-                                         unsigned char *src, unsigned char *dst, int width, int height,
-                                         float overscan, int channels)
-{
-       memcpy(dst, src, channels * width * height * sizeof(unsigned char));
-}
-
-void libmv_cameraIntrinsicsUndistortFloat(const struct libmv_CameraIntrinsics * /*libmvIntrinsics*/,
-                                          float *src, float *dst, int width, int height, float overscan, int channels)
-{
-       memcpy(dst, src, channels * width * height * sizeof(float));
-}
-
-void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmvIntrinsics,
-                                       unsigned char *src, unsigned char *dst, int width, int height,
-                                       float overscan, int channels)
-{
-       memcpy(dst, src, channels * width * height * sizeof(unsigned char));
-}
-
-void libmv_cameraIntrinsicsDistortFloat(const struct libmv_CameraIntrinsics *libmvIntrinsics,
-                                        float *src, float *dst, int width, int height, float overscan, int channels)
-{
-       memcpy(dst, src, channels * width * height * sizeof(float));
-}
-
-/* ************ utils ************ */
-
-void libmv_cameraIntrinsicsApply(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-                                 double x, double y, double *x1, double *y1)
-{
-       double focal_length = libmv_camera_intrinsics_options->focal_length;
-       double principal_x = libmv_camera_intrinsics_options->principal_point_x;
-       double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-
-       *x1 = x * focal_length + principal_x;
-       *y1 = y * focal_length + principal_y;
-}
-
-void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
-                                  double x, double y, double *x1, double *y1)
-{
-       double focal_length = libmv_camera_intrinsics_options->focal_length;
-       double principal_x = libmv_camera_intrinsics_options->principal_point_x;
-       double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-
-       *x1 = (x - principal_x) / focal_length;
-       *y1 = (y - principal_y) / focal_length;
-}
-
-void libmv_homography2DFromCorrespondencesEuc(double (* /* x1 */)[2], double (* /* x2 */)[2], int /* num_points */,
-                                              double H[3][3])
-{
-       memset(H, 0, sizeof(double[3][3]));
-       H[0][0] = 1.0f;
-       H[1][1] = 1.0f;
-       H[2][2] = 1.0f;
-}
-
-#endif  // ifndef WITH_LIBMV
diff --git a/extern/libmv/libmv-util.cc b/extern/libmv/libmv-util.cc
deleted file mode 100644 (file)
index f969417..0000000
+++ /dev/null
@@ -1,309 +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) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- *                 Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "libmv-util.h"
-#include "libmv-capi_intern.h"
-
-#include <cassert>
-#include <png.h>
-
-using libmv::CameraIntrinsics;
-using libmv::DivisionCameraIntrinsics;
-using libmv::EuclideanCamera;
-using libmv::EuclideanPoint;
-using libmv::FloatImage;
-using libmv::Marker;
-using libmv::PolynomialCameraIntrinsics;
-using libmv::Tracks;
-
-/* Image <-> buffers conversion */
-
-void libmv_byteBufferToImage(const unsigned char *buf,
-                             int width, int height, int channels,
-                             FloatImage *image)
-{
-       int x, y, k, a = 0;
-
-       image->Resize(height, width, channels);
-
-       for (y = 0; y < height; y++) {
-               for (x = 0; x < width; x++) {
-                       for (k = 0; k < channels; k++) {
-                               (*image)(y, x, k) = (float)buf[a++] / 255.0f;
-                       }
-               }
-       }
-}
-
-void libmv_floatBufferToImage(const float *buf,
-                              int width, int height, int channels,
-                              FloatImage *image)
-{
-       image->Resize(height, width, channels);
-
-       for (int y = 0, a = 0; y < height; y++) {
-               for (int x = 0; x < width; x++) {
-                       for (int k = 0; k < channels; k++) {
-                               (*image)(y, x, k) = buf[a++];
-                       }
-               }
-       }
-}
-
-void libmv_imageToFloatBuffer(const FloatImage &image,
-                              float *buf)
-{
-       for (int y = 0, a = 0; y < image.Height(); y++) {
-               for (int x = 0; x < image.Width(); x++) {
-                       for (int k = 0; k < image.Depth(); k++) {
-                               buf[a++] = image(y, x, k);
-                       }
-               }
-       }
-}
-
-void libmv_imageToByteBuffer(const libmv::FloatImage &image,
-                             unsigned char *buf)
-{
-       for (int y = 0, a= 0; y < image.Height(); y++) {
-               for (int x = 0; x < image.Width(); x++) {
-                       for (int k = 0; k < image.Depth(); k++) {
-                               buf[a++] = image(y, x, k) * 255.0f;
-                       }
-               }
-       }
-}
-
-/* Debugging */
-
-static void savePNGImage(png_bytep *row_pointers,
-                         int width, int height, int depth, int color_type,
-                         const char *file_name)
-{
-       png_infop info_ptr;
-       png_structp png_ptr;
-       FILE *fp = fopen(file_name, "wb");
-
-       if (!fp) {
-               return;
-    }
-
-       /* Initialize stuff */
-       png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-       info_ptr = png_create_info_struct(png_ptr);
-
-       if (setjmp(png_jmpbuf(png_ptr))) {
-               fclose(fp);
-               return;
-       }
-
-       png_init_io(png_ptr, fp);
-
-       /* write header */
-       if (setjmp(png_jmpbuf(png_ptr))) {
-               fclose(fp);
-               return;
-       }
-
-       png_set_IHDR(png_ptr, info_ptr,
-                    width, height, depth, color_type,
-                    PNG_INTERLACE_NONE,
-                    PNG_COMPRESSION_TYPE_BASE,
-                    PNG_FILTER_TYPE_BASE);
-
-       png_write_info(png_ptr, info_ptr);
-
-       /* write bytes */
-       if (setjmp(png_jmpbuf(png_ptr))) {
-               fclose(fp);
-               return;
-       }
-
-       png_write_image(png_ptr, row_pointers);
-
-       /* end write */
-       if (setjmp(png_jmpbuf(png_ptr))) {
-               fclose(fp);
-               return;
-       }
-
-       png_write_end(png_ptr, NULL);
-
-       fclose(fp);
-}
-
-void libmv_saveImage(const FloatImage &image,
-                                        const char *prefix,
-                                        int x0, int y0)
-{
-       int x, y;
-       png_bytep *row_pointers;
-
-       assert(image.Depth() == 1);
-
-       row_pointers = new png_bytep[image.Height()];
-
-       for (y = 0; y < image.Height(); y++) {
-               row_pointers[y] = new png_byte[4 * image.Width()];
-
-               for (x = 0; x < image.Width(); x++) {
-                       if (x0 == x && image.Height() - y0 - 1 == y) {
-                               row_pointers[y][x * 4 + 0] = 255;
-                               row_pointers[y][x * 4 + 1] = 0;
-                               row_pointers[y][x * 4 + 2] = 0;
-                               row_pointers[y][x * 4 + 3] = 255;
-                       }
-                       else {
-                               float pixel = image(image.Height() - y - 1, x, 0);
-                               row_pointers[y][x * 4 + 0] = pixel * 255;
-                               row_pointers[y][x * 4 + 1] = pixel * 255;
-                               row_pointers[y][x * 4 + 2] = pixel * 255;
-                               row_pointers[y][x * 4 + 3] = 255;
-                       }
-               }
-       }
-
-       {
-               static int a = 0;
-               char buf[128];
-               snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
-               savePNGImage(row_pointers,
-                            image.Width(), image.Height(), 8,
-                            PNG_COLOR_TYPE_RGBA,
-                            buf);
-       }
-
-       for (y = 0; y < image.Height(); y++) {
-               delete [] row_pointers[y];
-       }
-       delete [] row_pointers;
-}
-
-/* Camera intrinsics utility functions */
-
-void libmv_cameraIntrinsicsFillFromOptions(
-       const libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
-       CameraIntrinsics *camera_intrinsics)
-{
-       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->SetImageSize(camera_intrinsics_options->image_width,
-                                       camera_intrinsics_options->image_height);
-
-       switch (camera_intrinsics_options->distortion_model) {
-               case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
-               {
-                       PolynomialCameraIntrinsics *polynomial_intrinsics =
-                               static_cast<PolynomialCameraIntrinsics*>(camera_intrinsics);
-
-                       polynomial_intrinsics->SetRadialDistortion(
-                               camera_intrinsics_options->polynomial_k1,
-                               camera_intrinsics_options->polynomial_k2,
-                               camera_intrinsics_options->polynomial_k3);
-
-                       break;
-               }
-
-               case LIBMV_DISTORTION_MODEL_DIVISION:
-               {
-                       DivisionCameraIntrinsics *division_intrinsics =
-                               static_cast<DivisionCameraIntrinsics*>(camera_intrinsics);
-
-                       division_intrinsics->SetDistortion(
-                               camera_intrinsics_options->division_k1,
-                               camera_intrinsics_options->division_k2);
-
-                       break;
-               }
-
-               default:
-                       assert(!"Unknown distortion model");
-       }
-}
-
-CameraIntrinsics *libmv_cameraIntrinsicsCreateFromOptions(
-       const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
-       CameraIntrinsics *camera_intrinsics = NULL;
-
-       switch (camera_intrinsics_options->distortion_model) {
-               case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
-                       camera_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics);
-                       break;
-
-               case LIBMV_DISTORTION_MODEL_DIVISION:
-                       camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
-                       break;
-
-               default:
-                       assert(!"Unknown distortion model");
-       }
-
-       libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options, camera_intrinsics);
-
-       return camera_intrinsics;
-}
-
-/* Reconstruction utilities */
-
-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);
-       }
-}
-
-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;
-}
diff --git a/extern/libmv/libmv-util.h b/extern/libmv/libmv-util.h
deleted file mode 100644 (file)
index d755f98..0000000
+++ /dev/null
@@ -1,69 +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) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- *                 Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef LIBMV_UTIL_H
-#define LIBMV_UTIL_H
-
-#include "libmv-capi.h"
-#include "libmv/image/image.h"
-#include "libmv/simple_pipeline/camera_intrinsics.h"
-#include "libmv/simple_pipeline/tracks.h"
-#include "libmv/simple_pipeline/reconstruction.h"
-
-void libmv_byteBufferToImage(const unsigned char *buf,
-                             int width, int height, int channels,
-                             libmv::FloatImage *image);
-
-void libmv_floatBufferToImage(const float *buf,
-                              int width, int height, int channels,
-                              libmv::FloatImage *image);
-
-void libmv_imageToFloatBuffer(const libmv::FloatImage &image,
-                              float *buf);
-
-void libmv_imageToByteBuffer(const libmv::FloatImage &image,
-                             unsigned char *buf);
-
-void libmv_saveImage(const libmv::FloatImage &image,
-                     const char *prefix,
-                     int x0, int y0);
-
-void libmv_cameraIntrinsicsFillFromOptions(
-       const libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
-       libmv::CameraIntrinsics *camera_intrinsics);
-
-libmv::CameraIntrinsics *libmv_cameraIntrinsicsCreateFromOptions(
-       const libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
-
-void libmv_getNormalizedTracks(const libmv::Tracks &tracks,
-                               const libmv::CameraIntrinsics &camera_intrinsics,
-                               libmv::Tracks *normalized_tracks);
-
-libmv::Marker libmv_projectMarker(const libmv::EuclideanPoint &point,
-                                  const libmv::EuclideanCamera &camera,
-                                  const libmv::CameraIntrinsics &intrinsics);
-
-#endif
index 5458d88980064490c84c13f32753999e86b1cedc..487b19b6d21140eae22cce3e63913bc009ea4b5d 100644 (file)
@@ -1789,13 +1789,19 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
        if (ibuf->rect_float) {
                if (undistort) {
                        libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics,
-                                                            ibuf->rect_float, resibuf->rect_float,
-                                                            ibuf->x, ibuf->y, overscan, ibuf->channels);
+                                                            ibuf->rect_float,
+                                                            ibuf->x, ibuf->y,
+                                                            overscan,
+                                                            ibuf->channels,
+                                                            resibuf->rect_float);
                }
                else {
                        libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics,
-                                                          ibuf->rect_float, resibuf->rect_float,
-                                                          ibuf->x, ibuf->y, overscan, ibuf->channels);
+                                                          ibuf->rect_float,
+                                                          ibuf->x, ibuf->y,
+                                                          overscan,
+                                                          ibuf->channels,
+                                                          resibuf->rect_float);
                }
 
                if (ibuf->rect)
@@ -1804,13 +1810,19 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
        else {
                if (undistort) {
                        libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
-                                                           (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
-                                                           ibuf->x, ibuf->y, overscan, ibuf->channels);
+                                                           (unsigned char *)ibuf->rect,
+                                                           ibuf->x, ibuf->y,
+                                                           overscan,
+                                                           ibuf->channels,
+                                                           (unsigned char *)resibuf->rect);
                }
                else {
                        libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
-                                                         (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
-                                                         ibuf->x, ibuf->y, overscan, ibuf->channels);
+                                                         (unsigned char *)ibuf->rect,
+                                                         ibuf->x, ibuf->y,
+                                                         overscan,
+                                                         ibuf->channels,
+                                                         (unsigned char *)resibuf->rect);
                }
        }
 
@@ -2017,14 +2029,14 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
        }
 
        if (search_ibuf->rect_float) {
-               libmv_samplePlanarPatch(search_ibuf->rect_float,
-                                       search_ibuf->x, search_ibuf->y, 4,
-                                       src_pixel_x, src_pixel_y,
-                                       num_samples_x, num_samples_y,
-                                       mask,
-                                       pattern_ibuf->rect_float,
-                                       &warped_position_x,
-                                       &warped_position_y);
+               libmv_samplePlanarPatchFloat(search_ibuf->rect_float,
+                                            search_ibuf->x, search_ibuf->y, 4,
+                                            src_pixel_x, src_pixel_y,
+                                            num_samples_x, num_samples_y,
+                                            mask,
+                                            pattern_ibuf->rect_float,
+                                            &warped_position_x,
+                                            &warped_position_y);
        }
        else {
                libmv_samplePlanarPatchByte((unsigned char *) search_ibuf->rect,