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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/libmv/libmv-capi.cc')
-rw-r--r--extern/libmv/libmv-capi.cc1022
1 files changed, 503 insertions, 519 deletions
diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc
index 2d3afcd16e7..82143d50fbf 100644
--- a/extern/libmv/libmv-capi.cc
+++ b/extern/libmv/libmv-capi.cc
@@ -35,14 +35,10 @@
#undef DUMP_ALWAYS
#include "libmv-capi.h"
+#include "libmv-util.h"
-#include <cstdlib>
#include <cassert>
-#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
-# include <png.h>
-#endif
-
#include "libmv-capi_intern.h"
#include "libmv/logging/logging.h"
#include "libmv/multiview/homography.h"
@@ -58,27 +54,52 @@
#include "libmv/simple_pipeline/reconstruction_scale.h"
#include "libmv/simple_pipeline/keyframe_selection.h"
-#include "libmv/multiview/homography.h"
-
-#include "libmv/image/convolve.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 {
- libmv::EuclideanReconstruction reconstruction;
+ EuclideanReconstruction reconstruction;
/* used for per-track average error calculation after reconstruction */
- libmv::Tracks tracks;
- libmv::CameraIntrinsics intrinsics;
+ Tracks tracks;
+ CameraIntrinsics *intrinsics;
double error;
};
struct libmv_Features {
int count;
- libmv::Feature *features;
+ Feature *features;
};
/* ************ Logging ************ */
@@ -113,190 +134,6 @@ void libmv_setLoggingVerbosity(int verbosity)
google::SetCommandLineOption("v", val);
}
-/* ************ Utility ************ */
-
-static void byteBufToImage(const unsigned char *buf, int width, int height, int channels, libmv::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;
- }
- }
- }
-}
-
-static void floatBufToImage(const float *buf, int width, int height, int channels, libmv::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) = buf[a++];
- }
- }
- }
-}
-
-static void imageToFloatBuf(const libmv::FloatImage *image, int channels, float *buf)
-{
- int x, y, k, a = 0;
-
- for (y = 0; y < image->Height(); y++) {
- for (x = 0; x < image->Width(); x++) {
- for (k = 0; k < channels; k++) {
- buf[a++] = (*image)(y, x, k);
- }
- }
- }
-}
-
-static void imageToByteBuf(const libmv::FloatImage *image, int channels, unsigned char *buf)
-{
- int x, y, k, a = 0;
-
- for (y = 0; y < image->Height(); y++) {
- for (x = 0; x < image->Width(); x++) {
- for (k = 0; k < channels; k++) {
- buf[a++] = (*image)(y, x, k) * 255.0f;
- }
- }
- }
-}
-
-#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
-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);
-}
-
-static void saveImage(const char *prefix, libmv::FloatImage image, int x0, int y0)
-{
- int x, y;
- png_bytep *row_pointers;
-
- row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * image.Height());
-
- for (y = 0; y < image.Height(); y++) {
- row_pointers[y] = (png_bytep) malloc(sizeof(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++) {
- free(row_pointers[y]);
- }
- free(row_pointers);
-}
-
-static void saveBytesImage(const char *prefix, unsigned char *data, int width, int height)
-{
- int x, y;
- png_bytep *row_pointers;
-
- row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * height);
-
- for (y = 0; y < height; y++) {
- row_pointers[y] = (png_bytep) malloc(sizeof(png_byte) * 4 * width);
-
- for (x = 0; x < width; x++) {
- char pixel = data[width * y + x];
- row_pointers[y][x * 4 + 0] = pixel;
- row_pointers[y][x * 4 + 1] = pixel;
- row_pointers[y][x * 4 + 2] = pixel;
- 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, width, height, 8, PNG_COLOR_TYPE_RGBA, buf);
- }
-
- for (y = 0; y < height; y++) {
- free(row_pointers[y]);
- }
- free(row_pointers);
-}
-#endif
-
/* ************ Planar tracker ************ */
/* TrackRegion */
@@ -319,13 +156,13 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
yy2[i] = y2[i];
}
- libmv::TrackRegionOptions track_region_options;
- libmv::FloatImage image1_mask;
+ TrackRegionOptions track_region_options;
+ FloatImage image1_mask;
switch (options->motion_model) {
#define LIBMV_CONVERT(the_model) \
- case libmv::TrackRegionOptions::the_model: \
- track_region_options.mode = libmv::TrackRegionOptions::the_model; \
+ case TrackRegionOptions::the_model: \
+ track_region_options.mode = TrackRegionOptions::the_model; \
break;
LIBMV_CONVERT(TRANSLATION)
LIBMV_CONVERT(TRANSLATION_ROTATION)
@@ -355,18 +192,28 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
track_region_options.use_normalized_intensities = options->use_normalization;
if (options->image1_mask) {
- floatBufToImage(options->image1_mask, image1_width, image1_height, 1, &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. */
- libmv::FloatImage old_patch, new_patch;
- floatBufToImage(image1, image1_width, image1_height, 1, &old_patch);
- floatBufToImage(image2, image2_width, image2_height, 1, &new_patch);
-
- libmv::TrackRegionResult track_region_result;
- libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result);
+ 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) {
@@ -375,23 +222,29 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
}
/* TODO(keir): Update the termination string with failure details. */
- if (track_region_result.termination == libmv::TrackRegionResult::CONVERGENCE ||
- track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE)
+ 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)
-#if defined(DUMP_ALWAYS)
{
-#else
- if (!tracking_result) {
-#endif
- saveImage("old_patch", old_patch, x1[4], y1[4]);
- saveImage("new_patch", new_patch, x2[4], y2[4]);
+ bool need_dump = !tracking_result;
+
+# ifdef DUMP_ALWAYS
+ need_dump = true;
+# endif
- if (options->image1_mask)
- saveImage("mask", image1_mask, x2[4], y2[4]);
+ 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
@@ -404,27 +257,29 @@ void libmv_samplePlanarPatch(const float *image,
int num_samples_x, int num_samples_y,
const float *mask,
float *patch,
- double *warped_position_x, double *warped_position_y)
+ double *warped_position_x,
+ double *warped_position_y)
{
- libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
- libmv::FloatImage *libmv_mask_for_sample = NULL;
+ FloatImage libmv_image, libmv_patch, libmv_mask;
+ FloatImage *libmv_mask_for_sample = NULL;
- floatBufToImage(image, width, height, channels, &libmv_image);
+ libmv_floatBufferToImage(image, width, height, channels, &libmv_image);
if (mask) {
- floatBufToImage(mask, width, height, 1, &libmv_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);
+ SamplePlanarPatch(libmv_image,
+ xs, ys,
+ num_samples_x, num_samples_y,
+ libmv_mask_for_sample,
+ &libmv_patch,
+ warped_position_x,
+ warped_position_y);
- imageToFloatBuf(&libmv_patch, channels, patch);
+ libmv_imageToFloatBuffer(libmv_patch, patch);
}
void libmv_samplePlanarPatchByte(const unsigned char *image,
@@ -438,10 +293,10 @@ void libmv_samplePlanarPatch(const float *image,
libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
libmv::FloatImage *libmv_mask_for_sample = NULL;
- byteBufToImage(image, width, height, channels, &libmv_image);
+ libmv_byteBufferToImage(image, width, height, channels, &libmv_image);
if (mask) {
- floatBufToImage(mask, width, height, 1, &libmv_mask);
+ libmv_floatBufferToImage(mask, width, height, 1, &libmv_mask);
libmv_mask_for_sample = &libmv_mask;
}
@@ -453,34 +308,40 @@ void libmv_samplePlanarPatch(const float *image,
warped_position_x,
warped_position_y);
- imageToByteBuf(&libmv_patch, channels, patch);
+ libmv_imageToByteBuffer(libmv_patch, patch);
}
/* ************ Tracks ************ */
-struct libmv_Tracks *libmv_tracksNew(void)
+libmv_Tracks *libmv_tracksNew(void)
{
- libmv::Tracks *libmv_tracks = LIBMV_OBJECT_NEW(libmv::Tracks);
+ Tracks *libmv_tracks = LIBMV_OBJECT_NEW(Tracks);
- return (struct libmv_Tracks *)libmv_tracks;
+ return (libmv_Tracks *) libmv_tracks;
}
-void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks)
+void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
{
- using libmv::Tracks;
LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
}
-void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y, double weight)
+void libmv_tracksInsert(libmv_Tracks *libmv_tracks,
+ int image, int track,
+ double x, double y,
+ double weight)
{
- ((libmv::Tracks*) libmv_tracks)->Insert(image, track, x, y, weight);
+ ((Tracks *) libmv_tracks)->Insert(image, track, x, y, weight);
}
/* ************ Reconstruction ************ */
-class ReconstructUpdateCallback : public libmv::ProgressUpdateCallback {
+namespace {
+
+class ReconstructUpdateCallback : public ProgressUpdateCallback {
public:
- ReconstructUpdateCallback(reconstruct_progress_update_cb progress_update_callback, void *callback_customdata)
+ ReconstructUpdateCallback(
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata)
{
progress_update_callback_ = progress_update_callback;
callback_customdata_ = callback_customdata;
@@ -497,13 +358,14 @@ protected:
void *callback_customdata_;
};
-static void libmv_solveRefineIntrinsics(const libmv::Tracks &tracks,
- const int refine_intrinsics,
- const int bundle_constraints,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata,
- libmv::EuclideanReconstruction *reconstruction,
- libmv::CameraIntrinsics *intrinsics)
+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;
@@ -523,61 +385,37 @@ static void libmv_solveRefineIntrinsics(const libmv::Tracks &tracks,
progress_update_callback(callback_customdata, 1.0, "Refining solution");
- libmv::EuclideanBundleCommonIntrinsics(tracks,
- bundle_intrinsics,
- bundle_constraints,
- reconstruction,
- intrinsics);
+ EuclideanBundleCommonIntrinsics(tracks,
+ bundle_intrinsics,
+ bundle_constraints,
+ reconstruction,
+ intrinsics);
}
-static void cameraIntrinsicsFromOptions(const libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
- libmv::CameraIntrinsics *camera_intrinsics)
+void finishReconstruction(
+ const Tracks &tracks,
+ const CameraIntrinsics &camera_intrinsics,
+ libmv_Reconstruction *libmv_reconstruction,
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata)
{
- camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length,
- camera_intrinsics_options->focal_length);
-
- camera_intrinsics->SetPrincipalPoint(camera_intrinsics_options->principal_point_x,
- camera_intrinsics_options->principal_point_y);
-
- camera_intrinsics->SetRadialDistortion(camera_intrinsics_options->k1,
- camera_intrinsics_options->k2,
- camera_intrinsics_options->k3);
-
- camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width,
- camera_intrinsics_options->image_height);
-}
-
-static libmv::Tracks getNormalizedTracks(const libmv::Tracks &tracks, const libmv::CameraIntrinsics &camera_intrinsics)
-{
- libmv::vector<libmv::Marker> markers = tracks.AllMarkers();
-
- for (int i = 0; i < markers.size(); ++i) {
- camera_intrinsics.InvertIntrinsics(markers[i].x, markers[i].y,
- &(markers[i].x), &(markers[i].y));
- }
-
- return libmv::Tracks(markers);
-}
-
-static void finishReconstruction(const libmv::Tracks &tracks, const libmv::CameraIntrinsics &camera_intrinsics,
- struct libmv_Reconstruction *libmv_reconstruction,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata)
-{
- libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
/* reprojection error calculation */
progress_update_callback(callback_customdata, 1.0, "Finishing solution");
libmv_reconstruction->tracks = tracks;
- libmv_reconstruction->error = libmv::EuclideanReprojectionError(tracks, reconstruction, camera_intrinsics);
+ libmv_reconstruction->error = EuclideanReprojectionError(tracks,
+ reconstruction,
+ camera_intrinsics);
}
-static bool selectTwoKeyframesBasedOnGRICAndVariance(
- libmv::Tracks &tracks,
- libmv::Tracks &normalized_tracks,
- libmv::CameraIntrinsics &camera_intrinsics,
- int &keyframe1,
- int &keyframe2)
+bool selectTwoKeyframesBasedOnGRICAndVariance(
+ Tracks &tracks,
+ Tracks &normalized_tracks,
+ CameraIntrinsics &camera_intrinsics,
+ int &keyframe1,
+ int &keyframe2)
{
libmv::vector<int> keyframes;
@@ -607,25 +445,25 @@ static bool selectTwoKeyframesBasedOnGRICAndVariance(
int previous_keyframe = keyframes[0];
double best_error = std::numeric_limits<double>::max();
for (int i = 1; i < keyframes.size(); i++) {
- libmv::EuclideanReconstruction reconstruction;
+ EuclideanReconstruction reconstruction;
int current_keyframe = keyframes[i];
- libmv::vector<libmv::Marker> keyframe_markers =
+ libmv::vector<Marker> keyframe_markers =
normalized_tracks.MarkersForTracksInBothImages(previous_keyframe,
current_keyframe);
- libmv::Tracks keyframe_tracks(keyframe_markers);
+ Tracks keyframe_tracks(keyframe_markers);
/* get a solution from two keyframes only */
- libmv::EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- libmv::EuclideanBundle(keyframe_tracks, &reconstruction);
- libmv::EuclideanCompleteReconstruction(keyframe_tracks,
- &reconstruction, NULL);
+ EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
+ EuclideanBundle(keyframe_tracks, &reconstruction);
+ EuclideanCompleteReconstruction(keyframe_tracks,
+ &reconstruction,
+ NULL);
- double current_error =
- libmv::EuclideanReprojectionError(tracks,
- reconstruction,
- camera_intrinsics);
+ double current_error = EuclideanReprojectionError(tracks,
+ reconstruction,
+ camera_intrinsics);
LG << "Error between " << previous_keyframe
<< " and " << current_keyframe
@@ -643,26 +481,35 @@ static bool selectTwoKeyframesBasedOnGRICAndVariance(
return true;
}
-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)
+} // 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)
{
- struct libmv_Reconstruction *libmv_reconstruction = LIBMV_OBJECT_NEW(libmv_Reconstruction);
+ libmv_Reconstruction *libmv_reconstruction =
+ LIBMV_OBJECT_NEW(libmv_Reconstruction);
- libmv::Tracks &tracks = *((libmv::Tracks *) libmv_tracks);
- libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
- libmv::CameraIntrinsics &camera_intrinsics = libmv_reconstruction->intrinsics;
+ Tracks &tracks = *((Tracks *) libmv_tracks);
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback, callback_customdata);
+ ReconstructUpdateCallback(progress_update_callback,
+ callback_customdata);
/* Retrieve reconstruction options from C-API to libmv API */
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
+ CameraIntrinsics *camera_intrinsics;
+ camera_intrinsics = libmv_reconstruction->intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(
+ libmv_camera_intrinsics_options);
/* Invert the camera intrinsics */
- libmv::Tracks normalized_tracks = getNormalizedTracks(tracks, camera_intrinsics);
+ Tracks normalized_tracks;
+ libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
/* keyframe selection */
int keyframe1 = libmv_reconstruction_options->keyframe1,
@@ -675,7 +522,7 @@ struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks
selectTwoKeyframesBasedOnGRICAndVariance(tracks,
normalized_tracks,
- camera_intrinsics,
+ *camera_intrinsics,
keyframe1,
keyframe2);
@@ -687,95 +534,118 @@ struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks
/* actual reconstruction */
LG << "frames to init from: " << keyframe1 << " " << keyframe2;
- libmv::vector<libmv::Marker> keyframe_markers =
+ 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");
- libmv::EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- libmv::EuclideanBundle(normalized_tracks, &reconstruction);
- libmv::EuclideanCompleteReconstruction(normalized_tracks,
- &reconstruction, &update_callback);
+ 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);
+ 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 */
- libmv::EuclideanScaleToUnity(&reconstruction);
+ EuclideanScaleToUnity(&reconstruction);
/* finish reconstruction */
- finishReconstruction(tracks, camera_intrinsics, libmv_reconstruction,
- progress_update_callback, callback_customdata);
+ finishReconstruction(tracks,
+ *camera_intrinsics,
+ libmv_reconstruction,
+ progress_update_callback,
+ callback_customdata);
- return (struct libmv_Reconstruction *)libmv_reconstruction;
+ return (libmv_Reconstruction *) libmv_reconstruction;
}
-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)
+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)
{
- struct libmv_Reconstruction *libmv_reconstruction = LIBMV_OBJECT_NEW(libmv_Reconstruction);
+ libmv_Reconstruction *libmv_reconstruction =
+ LIBMV_OBJECT_NEW(libmv_Reconstruction);
- libmv::Tracks &tracks = *((libmv::Tracks *) libmv_tracks);
- libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
- libmv::CameraIntrinsics &camera_intrinsics = libmv_reconstruction->intrinsics;
+ Tracks &tracks = *((Tracks *) libmv_tracks);
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback, callback_customdata);
+ ReconstructUpdateCallback(progress_update_callback,
+ callback_customdata);
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
+ /* 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. */
- libmv::Tracks normalized_tracks = getNormalizedTracks(tracks, camera_intrinsics);
+ Tracks normalized_tracks;
+ libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
/* Actual reconstruction. */
- libmv::ModalSolver(normalized_tracks, &reconstruction, &update_callback);
+ ModalSolver(normalized_tracks, &reconstruction, &update_callback);
- libmv::CameraIntrinsics empty_intrinsics;
- libmv::EuclideanBundleCommonIntrinsics(normalized_tracks,
- libmv::BUNDLE_NO_INTRINSICS,
- libmv::BUNDLE_NO_TRANSLATION,
- &reconstruction,
- &empty_intrinsics);
+ 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);
+ 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);
+ finishReconstruction(tracks,
+ *camera_intrinsics,
+ libmv_reconstruction,
+ progress_update_callback,
+ callback_customdata);
- return (struct libmv_Reconstruction *)libmv_reconstruction;
+ return (libmv_Reconstruction *) libmv_reconstruction;
}
-void libmv_reconstructionDestroy(struct 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 struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
+int libmv_reprojectionPointForTrack(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int track,
+ double pos[3])
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::EuclideanPoint *point = reconstruction->PointForTrack(track);
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(track);
if (point) {
pos[0] = point->X[0];
@@ -788,35 +658,25 @@ int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction *libmv_rec
return 0;
}
-static libmv::Marker ProjectMarker(const libmv::EuclideanPoint &point,
- const libmv::EuclideanCamera &camera,
- const libmv::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;
-}
-
-double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track)
+double libmv_reprojectionErrorForTrack(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int track)
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
- libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersForTrack(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 libmv::EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
- const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+ const EuclideanCamera *camera =
+ reconstruction->CameraForImage(markers[i].image);
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(markers[i].track);
if (!camera || !point || weight == 0.0) {
continue;
@@ -824,7 +684,8 @@ double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_
num_reprojected++;
- libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
+ 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;
@@ -834,20 +695,26 @@ double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_
return total_error / num_reprojected;
}
-double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_reconstruction, int image)
+double libmv_reprojectionErrorForImage(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int image)
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
- libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersInImage(image);
- const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(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;
+ if (!camera) {
+ return 0.0;
+ }
for (int i = 0; i < markers.size(); ++i) {
- const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(markers[i].track);
if (!point) {
continue;
@@ -855,9 +722,10 @@ double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_
num_reprojected++;
- libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
- double ex = reprojected_marker.x - markers[i].x;
- double ey = reprojected_marker.y - markers[i].y;
+ 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);
}
@@ -865,11 +733,14 @@ double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_
return total_error / num_reprojected;
}
-int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction *libmv_reconstruction,
- int image, double mat[4][4])
+int libmv_reprojectionCameraForImage(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int image, double mat[4][4])
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image);
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const EuclideanCamera *camera =
+ reconstruction->CameraForImage(image);
if (camera) {
for (int j = 0; j < 3; ++j) {
@@ -899,25 +770,27 @@ int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction *libmv_re
return 0;
}
-double libmv_reprojectionError(const struct libmv_Reconstruction *libmv_reconstruction)
+double libmv_reprojectionError(
+ const libmv_Reconstruction *libmv_reconstruction)
{
return libmv_reconstruction->error;
}
-struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(struct libmv_Reconstruction *libmv_reconstruction)
+libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
+ libmv_Reconstruction *libmv_reconstruction)
{
- return (struct libmv_CameraIntrinsics *)&libmv_reconstruction->intrinsics;
+ return (libmv_CameraIntrinsics *) libmv_reconstruction->intrinsics;
}
/* ************ Feature detector ************ */
static libmv_Features *libmv_featuresFromVector(
- const libmv::vector<libmv::Feature> &features)
+ const libmv::vector<Feature> &features)
{
- struct libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
+ libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
int count = features.size();
if (count) {
- libmv_features->features = LIBMV_STRUCT_NEW(libmv::Feature, count);
+ libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
for (int i = 0; i < count; i++) {
libmv_features->features[i] = features.at(i);
@@ -933,12 +806,12 @@ static libmv_Features *libmv_featuresFromVector(
}
static void libmv_convertDetectorOptions(libmv_DetectOptions *options,
- libmv::DetectOptions *detector_options)
+ DetectOptions *detector_options)
{
switch (options->detector) {
#define LIBMV_CONVERT(the_detector) \
case LIBMV_DETECTOR_ ## the_detector: \
- detector_options->type = libmv::DetectOptions::the_detector; \
+ detector_options->type = DetectOptions::the_detector; \
break;
LIBMV_CONVERT(FAST)
LIBMV_CONVERT(MORAVEC)
@@ -953,49 +826,52 @@ static void libmv_convertDetectorOptions(libmv_DetectOptions *options,
detector_options->harris_threshold = options->harris_threshold;
}
-struct libmv_Features *libmv_detectFeaturesByte(const unsigned char *image_buffer,
- int width, int height, int channels,
- libmv_DetectOptions *options)
+libmv_Features *libmv_detectFeaturesByte(
+ const unsigned char *image_buffer,
+ int width, int height,
+ int channels,
+ libmv_DetectOptions *options)
{
// Prepare the image.
- libmv::FloatImage image;
- byteBufToImage(image_buffer, width, height, channels, &image);
+ FloatImage image;
+ libmv_byteBufferToImage(image_buffer, width, height, channels, &image);
// Configure detector.
- libmv::DetectOptions detector_options;
+ DetectOptions detector_options;
libmv_convertDetectorOptions(options, &detector_options);
// Run the detector.
- libmv::vector<libmv::Feature> detected_features;
- libmv::Detect(image, detector_options, &detected_features);
+ 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;
}
-struct libmv_Features *libmv_detectFeaturesFloat(const float *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)
{
// Prepare the image.
- libmv::FloatImage image;
- floatBufToImage(image_buffer, width, height, channels, &image);
+ FloatImage image;
+ libmv_floatBufferToImage(image_buffer, width, height, channels, &image);
// Configure detector.
- libmv::DetectOptions detector_options;
+ DetectOptions detector_options;
libmv_convertDetectorOptions(options, &detector_options);
// Run the detector.
- libmv::vector<libmv::Feature> detected_features;
- libmv::Detect(image, detector_options, &detected_features);
+ 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(struct libmv_Features *libmv_features)
+void libmv_featuresDestroy(libmv_Features *libmv_features)
{
if (libmv_features->features) {
LIBMV_STRUCT_DELETE(libmv_features->features);
@@ -1004,14 +880,16 @@ void libmv_featuresDestroy(struct libmv_Features *libmv_features)
LIBMV_STRUCT_DELETE(libmv_features);
}
-int libmv_countFeatures(const struct libmv_Features *libmv_features)
+int libmv_countFeatures(const libmv_Features *libmv_features)
{
return libmv_features->count;
}
-void libmv_getFeature(const struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size)
+void libmv_getFeature(const libmv_Features *libmv_features,
+ int number,
+ double *x, double *y, double *score, double *size)
{
- libmv::Feature feature = libmv_features->features[number];
+ Feature &feature = libmv_features->features[number];
*x = feature.x;
*y = feature.y;
@@ -1021,51 +899,67 @@ void libmv_getFeature(const struct libmv_Features *libmv_features, int number, d
/* ************ Camera intrinsics ************ */
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNewEmpty(void)
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
{
- libmv::CameraIntrinsics *camera_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics);
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
- return (struct libmv_CameraIntrinsics *) camera_intrinsics;
+ return (libmv_CameraIntrinsics *) camera_intrinsics;
}
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+ const libmv_CameraIntrinsics *libmvIntrinsics)
{
- libmv::CameraIntrinsics *camera_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics);
-
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, camera_intrinsics);
-
- return (struct libmv_CameraIntrinsics *) camera_intrinsics;
-}
-
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics *libmvIntrinsics)
-{
- libmv::CameraIntrinsics *orig_intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
- libmv::CameraIntrinsics *new_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics, *orig_intrinsics);
+ 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 (struct libmv_CameraIntrinsics *) new_intrinsics;
+ return (libmv_CameraIntrinsics *) new_intrinsics;
}
-void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics)
+void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics *libmvIntrinsics)
{
- using libmv::CameraIntrinsics;
LIBMV_OBJECT_DELETE(libmvIntrinsics, CameraIntrinsics);
}
-void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- struct libmv_CameraIntrinsics *libmv_intrinsics)
+void libmv_cameraIntrinsicsUpdate(
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+ libmv_CameraIntrinsics *libmv_intrinsics)
{
- libmv::CameraIntrinsics *camera_intrinsics = (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;
- double k1 = libmv_camera_intrinsics_options->k1;
- double k2 = libmv_camera_intrinsics_options->k2;
- double k3 = libmv_camera_intrinsics_options->k3;
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 */
+ /* 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);
@@ -1076,105 +970,192 @@ void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_cam
camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
}
- if (camera_intrinsics->k1() != k1 ||
- camera_intrinsics->k2() != k2 ||
- camera_intrinsics->k3() != k3)
- {
- camera_intrinsics->SetRadialDistortion(k1, k2, k3);
- }
-
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(struct libmv_CameraIntrinsics *libmv_intrinsics, int threads)
+void libmv_cameraIntrinsicsSetThreads(
+ libmv_CameraIntrinsics *libmv_intrinsics, int threads)
{
- libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
camera_intrinsics->SetThreads(threads);
}
-void libmv_cameraIntrinsicsExtract(const struct libmv_CameraIntrinsics *libmv_intrinsics, double *focal_length,
- double *principal_x, double *principal_y, double *k1, double *k2, double *k3,
- int *width, int *height)
+void libmv_cameraIntrinsicsExtractOptions(
+ const libmv_CameraIntrinsics *libmv_intrinsics,
+ libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
{
- libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
-
- *focal_length = camera_intrinsics->focal_length();
- *principal_x = camera_intrinsics->principal_point_x();
- *principal_y = camera_intrinsics->principal_point_y();
- *k1 = camera_intrinsics->k1();
- *k2 = camera_intrinsics->k2();
- *k3 = camera_intrinsics->k3();
-}
+ 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;
+ }
-void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
-{
- libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
+ 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;
+ }
- camera_intrinsics->Undistort(src, dst, width, height, overscan, channels);
+ default:
+ assert(!"Uknown distortion model");
+ }
}
-void libmv_cameraIntrinsicsUndistortFloat(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels)
+void libmv_cameraIntrinsicsUndistortByte(
+ const libmv_CameraIntrinsics *libmv_intrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
-
- intrinsics->Undistort(src, dst, width, height, overscan, channels);
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ camera_intrinsics->UndistortBuffer(src,
+ width, height, overscan, channels,
+ dst);
}
-void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
+void libmv_cameraIntrinsicsUndistortFloat(
+ const libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
- intrinsics->Distort(src, dst, width, height, overscan, channels);
+ CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
+ intrinsics->UndistortBuffer(src,
+ width, height, overscan, channels,
+ dst);
}
-void libmv_cameraIntrinsicsDistortFloat(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels)
+void libmv_cameraIntrinsicsDistortByte(
+ const libmv_CameraIntrinsics *libmvIntrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
-
- intrinsics->Distort(src, dst, width, height, overscan, 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)
+void libmv_cameraIntrinsicsDistortFloat(
+ const libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics camera_intrinsics;
-
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
+ 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) {
- /* do a lens undistortion if focal length is non-zero only */
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+
+ camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
- 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)
+void libmv_cameraIntrinsicsInvert(
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+ double x, double y, double *x1, double *y1)
{
- libmv::CameraIntrinsics camera_intrinsics;
-
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
-
+ /* do a lens distortion if focal length is non-zero only */
if (libmv_camera_intrinsics_options->focal_length) {
- /* do a lens distortion if focal length is non-zero only */
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+
+ camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
- 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])
+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;
@@ -1191,7 +1172,10 @@ void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2], double (*x2)[2],
LG << "x2: " << x2_mat;
libmv::EstimateHomographyOptions options;
- libmv::EstimateHomography2DFromCorrespondences(x1_mat, x2_mat, options, &H_mat);
+ libmv::EstimateHomography2DFromCorrespondences(x1_mat,
+ x2_mat,
+ options,
+ &H_mat);
LG << "H: " << H_mat;