diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index ffe4b6ebf3d..41235523179 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -564,6 +564,9 @@ static void cameraIntrinsicsFromOptions(libmv::CameraIntrinsics *camera_intrinsi 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(libmv::Tracks *tracks, libmv::CameraIntrinsics *camera_intrinsics) @@ -897,17 +900,13 @@ struct libmv_CameraIntrinsics *libmv_ReconstructionExtractIntrinsics(struct libm return (struct libmv_CameraIntrinsics *)&libmv_Reconstruction->intrinsics; } -struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y, - double k1, double k2, double k3, int width, int height) +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options) { - libmv::CameraIntrinsics *intrinsics= new libmv::CameraIntrinsics(); + libmv::CameraIntrinsics *camera_intrinsics = new libmv::CameraIntrinsics(); - intrinsics->SetFocalLength(focal_length, focal_length); - intrinsics->SetPrincipalPoint(principal_x, principal_y); - intrinsics->SetRadialDistortion(k1, k2, k3); - intrinsics->SetImageSize(width, height); + cameraIntrinsicsFromOptions(camera_intrinsics, libmv_camera_intrinsics_options); - return (struct libmv_CameraIntrinsics *) intrinsics; + return (struct libmv_CameraIntrinsics *) camera_intrinsics; } struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics) @@ -925,40 +924,63 @@ void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsic delete intrinsics; } -void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length, - double principal_x, double principal_y, double k1, double k2, double k3, int width, int height) +void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmv_intrinsics, + libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options) { - libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics; - if (intrinsics->focal_length() != focal_length) - intrinsics->SetFocalLength(focal_length, focal_length); + 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; - if (intrinsics->principal_point_x() != principal_x || intrinsics->principal_point_y() != principal_y) - intrinsics->SetPrincipalPoint(principal_x, principal_y); + /* try avoid unnecessary updates so pre-computed distortion grids are not freed */ - if (intrinsics->k1() != k1 || intrinsics->k2() != k2 || intrinsics->k3() != k3) - intrinsics->SetRadialDistortion(k1, k2, k3); + if (camera_intrinsics->focal_length() != focal_length) + camera_intrinsics->SetFocalLength(focal_length, focal_length); - if (intrinsics->image_width() != width || intrinsics->image_height() != height) - intrinsics->SetImageSize(width, height); + 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->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); + } } -void libmv_CameraIntrinsicsExtract(struct libmv_CameraIntrinsics *libmvIntrinsics, double *focal_length, - double *principal_x, double *principal_y, double *k1, double *k2, double *k3, int *width, int *height) { - libmv::CameraIntrinsics *intrinsics= (libmv::CameraIntrinsics *) libmvIntrinsics; - *focal_length = intrinsics->focal_length(); - *principal_x = intrinsics->principal_point_x(); - *principal_y = intrinsics->principal_point_y(); - *k1 = intrinsics->k1(); - *k2 = intrinsics->k2(); +void libmv_CameraIntrinsicsExtract(struct libmv_CameraIntrinsics *libmv_intrinsics, double *focal_length, + double *principal_x, double *principal_y, double *k1, double *k2, double *k3, int *width, int *height) +{ + 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(); } -void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, +void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmv_intrinsics, unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) { - libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics; - intrinsics->Undistort(src, dst, width, height, overscan, channels); + camera_intrinsics->Undistort(src, dst, width, height, overscan, channels); } void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, @@ -986,85 +1008,77 @@ void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntr /* ************ distortion ************ */ -void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, - unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) +void libmv_undistortByte(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, + unsigned char *src, unsigned char *dst, int width, int height, + float overscan, int channels) { - libmv::CameraIntrinsics intrinsics; + libmv::CameraIntrinsics camera_intrinsics; - intrinsics.SetFocalLength(focal_length, focal_length); - intrinsics.SetPrincipalPoint(principal_x, principal_y); - intrinsics.SetRadialDistortion(k1, k2, k3); + cameraIntrinsicsFromOptions(&camera_intrinsics, libmv_camera_intrinsics_options); - intrinsics.Undistort(src, dst, width, height, overscan, channels); + camera_intrinsics.Undistort(src, dst, width, height, overscan, channels); } -void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, - float *src, float *dst, int width, int height, float overscan, int channels) +void libmv_undistortFloat(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, + float *src, float *dst, int width, int height, + float overscan, int channels) { - libmv::CameraIntrinsics intrinsics; + libmv::CameraIntrinsics camera_intrinsics; - intrinsics.SetFocalLength(focal_length, focal_length); - intrinsics.SetPrincipalPoint(principal_x, principal_y); - intrinsics.SetRadialDistortion(k1, k2, k3); + cameraIntrinsicsFromOptions(&camera_intrinsics, libmv_camera_intrinsics_options); - intrinsics.Undistort(src, dst, width, height, overscan, channels); + camera_intrinsics.Undistort(src, dst, width, height, overscan, channels); } -void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, - unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) +void libmv_distortByte(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, + unsigned char *src, unsigned char *dst, int width, int height, + float overscan, int channels) { - libmv::CameraIntrinsics intrinsics; + libmv::CameraIntrinsics camera_intrinsics; - intrinsics.SetFocalLength(focal_length, focal_length); - intrinsics.SetPrincipalPoint(principal_x, principal_y); - intrinsics.SetRadialDistortion(k1, k2, k3); + cameraIntrinsicsFromOptions(&camera_intrinsics, libmv_camera_intrinsics_options); - intrinsics.Distort(src, dst, width, height, overscan, channels); + camera_intrinsics.Distort(src, dst, width, height, overscan, channels); } -void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, - float *src, float *dst, int width, int height, float overscan, int channels) +void libmv_distortFloat(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, + float *src, float *dst, int width, int height, + float overscan, int channels) { - libmv::CameraIntrinsics intrinsics; + libmv::CameraIntrinsics camera_intrinsics; - intrinsics.SetFocalLength(focal_length, focal_length); - intrinsics.SetPrincipalPoint(principal_x, principal_y); - intrinsics.SetRadialDistortion(k1, k2, k3); + cameraIntrinsicsFromOptions(&camera_intrinsics, libmv_camera_intrinsics_options); - intrinsics.Distort(src, dst, width, height, overscan, channels); + camera_intrinsics.Distort(src, dst, width, height, overscan, channels); } /* ************ utils ************ */ -void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, - double x, double y, double *x1, double *y1) +void libmv_applyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, + double x, double y, double *x1, double *y1) { - libmv::CameraIntrinsics intrinsics; + libmv::CameraIntrinsics camera_intrinsics; - intrinsics.SetFocalLength(focal_length, focal_length); - intrinsics.SetPrincipalPoint(principal_x, principal_y); - intrinsics.SetRadialDistortion(k1, k2, k3); + cameraIntrinsicsFromOptions(&camera_intrinsics, libmv_camera_intrinsics_options); - if(focal_length) { + if (libmv_camera_intrinsics_options->focal_length) { /* do a lens undistortion if focal length is non-zero only */ - intrinsics.ApplyIntrinsics(x, y, x1, y1); + camera_intrinsics.ApplyIntrinsics(x, y, x1, y1); } } -void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, - double x, double y, double *x1, double *y1) +void libmv_InvertIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, + double x, double y, double *x1, double *y1) { - libmv::CameraIntrinsics intrinsics; + libmv::CameraIntrinsics camera_intrinsics; - intrinsics.SetFocalLength(focal_length, focal_length); - intrinsics.SetPrincipalPoint(principal_x, principal_y); - intrinsics.SetRadialDistortion(k1, k2, k3); + cameraIntrinsicsFromOptions(&camera_intrinsics, libmv_camera_intrinsics_options); - if(focal_length) { + if (libmv_camera_intrinsics_options->focal_length) { /* do a lens distortion if focal length is non-zero only */ - intrinsics.InvertIntrinsics(x, y, x1, y1); + camera_intrinsics.InvertIntrinsics(x, y, x1, y1); } } diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index 317f5520aa9..9ffa3e1a110 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -97,6 +97,7 @@ typedef struct libmv_cameraIntrinsicsOptions { double principal_point_x, principal_point_y; double k1, k2, k3; double p1, p2; + int image_width, image_height; } libmv_cameraIntrinsicsOptions; typedef struct libmv_reconstructionOptions { @@ -139,46 +140,45 @@ void libmv_destroyFeatures(struct libmv_Features *libmv_features); /* camera intrinsics */ struct libmv_CameraIntrinsics *libmv_ReconstructionExtractIntrinsics(struct libmv_Reconstruction *libmv_Reconstruction); -struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y, - double k1, double k2, double k3, int width, int height); +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options); -struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics); +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmv_intrinsics); -void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics); +void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmv_intrinsics); -void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length, - double principal_x, double principal_y, double k1, double k2, double k3, int width, int height); +void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmv_intrinsics, + libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options); -void libmv_CameraIntrinsicsExtract(struct libmv_CameraIntrinsics *libmvIntrinsics, double *focal_length, +void libmv_CameraIntrinsicsExtract(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_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, +void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmv_intrinsics, unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels); -void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, +void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmv_intrinsics, float *src, float *dst, int width, int height, float overscan, int channels); -void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, +void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmv_intrinsics, unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels); -void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, +void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmv_intrinsics, float *src, float *dst, int width, int height, float overscan, int channels); /* dsitortion */ -void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, +void libmv_undistortByte(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels); -void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, +void libmv_undistortFloat(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, float *src, float *dst, int width, int height, float overscan, int channels); -void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, +void libmv_distortByte(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels); -void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, +void libmv_distortFloat(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, float *src, float *dst, int width, int height, float overscan, int channels); /* utils */ -void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, +void libmv_applyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, double x, double y, double *x1, double *y1); -void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, +void libmv_InvertIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options, double x, double y, double *x1, double *y1); /* point clouds */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index de0be829e8b..f625f5c8526 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1429,6 +1429,27 @@ void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, /*********************** Distortion/Undistortion *************************/ +#ifdef WITH_LIBMV +static void cameraIntrinscisOptionsFromTracking(libmv_cameraIntrinsicsOptions *camera_intrinsics_options, + MovieTracking *tracking, int calibration_width, int calibration_height) +{ + MovieTrackingCamera *camera = &tracking->camera; + float aspy = 1.0f / tracking->camera.pixel_aspect; + + camera_intrinsics_options->focal_length = camera->focal; + + camera_intrinsics_options->principal_point_x = camera->principal[0]; + camera_intrinsics_options->principal_point_y = camera->principal[1] * aspy; + + camera_intrinsics_options->k1 = camera->k1; + camera_intrinsics_options->k2 = camera->k2; + camera_intrinsics_options->k3 = camera->k3; + + camera_intrinsics_options->image_width = calibration_width; + camera_intrinsics_options->image_height = (double) calibration_height * aspy; +} +#endif + MovieDistortion *BKE_tracking_distortion_new(void) { MovieDistortion *distortion; @@ -1441,21 +1462,17 @@ MovieDistortion *BKE_tracking_distortion_new(void) void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int calibration_width, int calibration_height) { - MovieTrackingCamera *camera = &tracking->camera; - float aspy = 1.0f / tracking->camera.pixel_aspect; - #ifdef WITH_LIBMV + libmv_cameraIntrinsicsOptions camera_intrinsics_options; + + cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, + calibration_width, calibration_height); + if (!distortion->intrinsics) { - distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, - calibration_width, calibration_height * aspy); + distortion->intrinsics = libmv_CameraIntrinsicsNew(&camera_intrinsics_options); } else { - libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, - calibration_width, calibration_height * aspy); + libmv_CameraIntrinsicsUpdate(distortion->intrinsics, &camera_intrinsics_options); } #else (void) distortion; @@ -1543,15 +1560,17 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r MovieTrackingCamera *camera = &tracking->camera; #ifdef WITH_LIBMV + libmv_cameraIntrinsicsOptions camera_intrinsics_options; double x, y; float aspy = 1.0f / tracking->camera.pixel_aspect; + cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0); + /* normalize coords */ x = (co[0] - camera->principal[0]) / camera->focal; y = (co[1] - camera->principal[1] * aspy) / camera->focal; - libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, x, y, &x, &y); + libmv_applyCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y); /* result is in image coords already */ r_co[0] = x; @@ -1568,11 +1587,13 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float MovieTrackingCamera *camera = &tracking->camera; #ifdef WITH_LIBMV + libmv_cameraIntrinsicsOptions camera_intrinsics_options; double x = co[0], y = co[1]; float aspy = 1.0f / tracking->camera.pixel_aspect; - libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, x, y, &x, &y); + cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0); + + libmv_InvertIntrinsics(&camera_intrinsics_options, x, y, &x, &y); r_co[0] = x * camera->focal + camera->principal[0]; r_co[1] = y * camera->focal + camera->principal[1] * aspy; @@ -3008,6 +3029,9 @@ static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *cam camera_intrinsics_options->k1 = context->k1; camera_intrinsics_options->k2 = context->k2; camera_intrinsics_options->k3 = context->k3; + + camera_intrinsics_options->image_width = 0; + camera_intrinsics_options->image_height = 0; } static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options,