Commit: 3a7d62cd1f5e06e22af1642fc5f4aab59bace585 Author: Ivan Perevala Date: Wed Sep 30 15:12:14 2020 +0200 Branches: master https://developer.blender.org/rB3a7d62cd1f5e06e22af1642fc5f4aab59bace585
Tracking: Implement Brown-Conrady distortion model Implemented Brown-Conrady lens distortion model with 4 radial and 2 tangential coefficients to improve compatibility with other software, such as Agisoft Photoscan/Metashapes, 3DF Zephir, RealityCapture, Bentley ContextCapture, Alisevision Meshroom(opensource). Also older programs: Bundler, CPMVS. In general terms, most photogrammetric software. The new model is available under the distortion model menu in Lens settings. For tests and demos check the original patch. Reviewed By: sergey Differential Revision: https://developer.blender.org/D9037 =================================================================== M intern/libmv/intern/camera_intrinsics.cc M intern/libmv/intern/camera_intrinsics.h M intern/libmv/libmv/simple_pipeline/bundle.cc M intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc M intern/libmv/libmv/simple_pipeline/camera_intrinsics.h M intern/libmv/libmv/simple_pipeline/distortion_models.cc M intern/libmv/libmv/simple_pipeline/distortion_models.h M source/blender/blenkernel/intern/movieclip.c M source/blender/blenkernel/intern/tracking_util.c M source/blender/makesdna/DNA_tracking_types.h M source/blender/makesrna/intern/rna_tracking.c =================================================================== diff --git a/intern/libmv/intern/camera_intrinsics.cc b/intern/libmv/intern/camera_intrinsics.cc index 554c4350b0a..628637e12cc 100644 --- a/intern/libmv/intern/camera_intrinsics.cc +++ b/intern/libmv/intern/camera_intrinsics.cc @@ -25,6 +25,7 @@ using libmv::CameraIntrinsics; using libmv::DivisionCameraIntrinsics; using libmv::PolynomialCameraIntrinsics; using libmv::NukeCameraIntrinsics; +using libmv::BrownCameraIntrinsics; libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew( const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options) { @@ -64,6 +65,14 @@ libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy( *nuke_intrinsics); break; } + case libmv::DISTORTION_MODEL_BROWN: + { + const BrownCameraIntrinsics *brown_intrinsics = + static_cast<const BrownCameraIntrinsics*>(orig_intrinsics); + new_intrinsics = LIBMV_OBJECT_NEW(BrownCameraIntrinsics, + *brown_intrinsics); + break; + } default: assert(!"Unknown distortion model"); } @@ -164,6 +173,35 @@ void libmv_cameraIntrinsicsUpdate( break; } + case LIBMV_DISTORTION_MODEL_BROWN: + { + assert(camera_intrinsics->GetDistortionModelType() == + libmv::DISTORTION_MODEL_BROWN); + + BrownCameraIntrinsics *brown_intrinsics = + (BrownCameraIntrinsics *) camera_intrinsics; + + double k1 = libmv_camera_intrinsics_options->brown_k1; + double k2 = libmv_camera_intrinsics_options->brown_k2; + double k3 = libmv_camera_intrinsics_options->brown_k3; + double k4 = libmv_camera_intrinsics_options->brown_k4; + + if (brown_intrinsics->k1() != k1 || + brown_intrinsics->k2() != k2 || + brown_intrinsics->k3() != k3 || + brown_intrinsics->k4() != k4) { + brown_intrinsics->SetRadialDistortion(k1, k2, k3, k4); + } + + double p1 = libmv_camera_intrinsics_options->brown_p1; + double p2 = libmv_camera_intrinsics_options->brown_p2; + + if (brown_intrinsics->p1() != p1 || brown_intrinsics->p2() != p2) { + brown_intrinsics->SetTangentialDistortion(p1, p2); + } + break; + } + default: assert(!"Unknown distortion model"); } @@ -228,6 +266,21 @@ void libmv_cameraIntrinsicsExtractOptions( break; } + case libmv::DISTORTION_MODEL_BROWN: + { + const BrownCameraIntrinsics *brown_intrinsics = + static_cast<const BrownCameraIntrinsics *>(camera_intrinsics); + camera_intrinsics_options->distortion_model = + LIBMV_DISTORTION_MODEL_BROWN; + camera_intrinsics_options->brown_k1 = brown_intrinsics->k1(); + camera_intrinsics_options->brown_k2 = brown_intrinsics->k2(); + camera_intrinsics_options->brown_k3 = brown_intrinsics->k3(); + camera_intrinsics_options->brown_k4 = brown_intrinsics->k4(); + camera_intrinsics_options->brown_p1 = brown_intrinsics->p1(); + camera_intrinsics_options->brown_p2 = brown_intrinsics->p2(); + break; + } + default: assert(!"Unknown distortion model"); } @@ -366,6 +419,23 @@ static void libmv_cameraIntrinsicsFillFromOptions( break; } + case LIBMV_DISTORTION_MODEL_BROWN: + { + BrownCameraIntrinsics *brown_intrinsics = + static_cast<BrownCameraIntrinsics*>(camera_intrinsics); + + brown_intrinsics->SetRadialDistortion( + camera_intrinsics_options->brown_k1, + camera_intrinsics_options->brown_k2, + camera_intrinsics_options->brown_k3, + camera_intrinsics_options->brown_k4); + brown_intrinsics->SetTangentialDistortion( + camera_intrinsics_options->brown_p1, + camera_intrinsics_options->brown_p2); + + break; + } + default: assert(!"Unknown distortion model"); } @@ -384,6 +454,9 @@ CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions( case LIBMV_DISTORTION_MODEL_NUKE: camera_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics); break; + case LIBMV_DISTORTION_MODEL_BROWN: + camera_intrinsics = LIBMV_OBJECT_NEW(BrownCameraIntrinsics); + break; default: assert(!"Unknown distortion model"); } diff --git a/intern/libmv/intern/camera_intrinsics.h b/intern/libmv/intern/camera_intrinsics.h index b3d259893bd..eb6176770ec 100644 --- a/intern/libmv/intern/camera_intrinsics.h +++ b/intern/libmv/intern/camera_intrinsics.h @@ -30,6 +30,7 @@ enum { LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0, LIBMV_DISTORTION_MODEL_DIVISION = 1, LIBMV_DISTORTION_MODEL_NUKE = 2, + LIBMV_DISTORTION_MODEL_BROWN = 3, }; typedef struct libmv_CameraIntrinsicsOptions { @@ -49,6 +50,10 @@ typedef struct libmv_CameraIntrinsicsOptions { // Nuke distortion model. double nuke_k1, nuke_k2; + + // Brown-Conrady distortion model. + double brown_k1, brown_k2, brown_k3, brown_k4; + double brown_p1, brown_p2; } libmv_CameraIntrinsicsOptions; libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew( diff --git a/intern/libmv/libmv/simple_pipeline/bundle.cc b/intern/libmv/libmv/simple_pipeline/bundle.cc index 22ab0cdf864..c055846318a 100644 --- a/intern/libmv/libmv/simple_pipeline/bundle.cc +++ b/intern/libmv/libmv/simple_pipeline/bundle.cc @@ -50,6 +50,7 @@ enum { OFFSET_K1, OFFSET_K2, OFFSET_K3, + OFFSET_K4, OFFSET_P1, OFFSET_P2, @@ -135,6 +136,26 @@ void ApplyDistortionModelUsingIntrinsicsBlock( LOG(FATAL) << "Unsupported distortion model."; return; } + + case DISTORTION_MODEL_BROWN: + { + const T& k1 = intrinsics_block[OFFSET_K1]; + const T& k2 = intrinsics_block[OFFSET_K2]; + const T& k3 = intrinsics_block[OFFSET_K3]; + const T& k4 = intrinsics_block[OFFSET_K4]; + const T& p1 = intrinsics_block[OFFSET_P1]; + const T& p2 = intrinsics_block[OFFSET_P2]; + + ApplyBrownDistortionModel(focal_length, + focal_length, + principal_point_x, + principal_point_y, + k1, k2, k3, k4, + p1, p2, + normalized_x, normalized_y, + distorted_x, distorted_y); + return; + } } LOG(FATAL) << "Unknown distortion model."; @@ -168,6 +189,7 @@ void InvertDistortionModelUsingIntrinsicsBlock( switch (invariant_intrinsics->GetDistortionModelType()) { case DISTORTION_MODEL_POLYNOMIAL: case DISTORTION_MODEL_DIVISION: + case DISTORTION_MODEL_BROWN: LOG(FATAL) << "Unsupported distortion model."; return; @@ -783,8 +805,9 @@ void EuclideanBundleCommonIntrinsics( MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P2, OFFSET_P2); #undef MAYBE_SET_CONSTANT - // Always set K3 constant, it's not used at the moment. + // Always set K3 and K4 constant, it's not used at the moment. constant_intrinsics.push_back(OFFSET_K3); + constant_intrinsics.push_back(OFFSET_K4); ceres::SubsetParameterization *subset_parameterization = new ceres::SubsetParameterization(OFFSET_MAX, constant_intrinsics); diff --git a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc index c7c827fcd66..052714bbb3e 100644 --- a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc +++ b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc @@ -296,6 +296,72 @@ void NukeCameraIntrinsics::InvertIntrinsics(double image_x, normalized_y); } +// Brown model. + +BrownCameraIntrinsics::BrownCameraIntrinsics() + : CameraIntrinsics() { + SetRadialDistortion(0.0, 0.0, 0.0, 0.0); + SetTangentialDistortion(0.0, 0.0); +} + +BrownCameraIntrinsics::BrownCameraIntrinsics( + const BrownCameraIntrinsics &from) + : CameraIntrinsics(from) { + SetRadialDistortion(from.k1(), from.k2(), from.k3(), from.k4()); + SetTangentialDistortion(from.p1(), from.p2()); +} + +void BrownCameraIntrinsics::SetRadialDistortion(double k1, + double k2, + double k3, + double k4) { + parameters_[OFFSET_K1] = k1; + parameters_[OFFSET_K2] = k2; + parameters_[OFFSET_K3] = k3; + parameters_[OFFSET_K4] = k4; + ResetLookupGrids(); +} + +void BrownCameraIntrinsics::SetTangentialDistortion(double p1, + double p2) { + parameters_[OFFSET_P1] = p1; + parameters_[OFFSET_P2] = p2; + ResetLookupGrids(); +} + +void BrownCameraIntrinsics::ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const { + ApplyBrownDistortionModel(focal_length_x(), + focal_length_y(), + principal_point_x(), + principal_point_y(), + k1(), k2(), k3(), k4(), + p1(), p2(), + normalized_x, + normalized_y, + image_x, + image_y); +} + +void BrownCameraIntrinsics::InvertIntrinsics( + double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const { + InvertBrownDistortionModel(focal_length_x(), + focal_length_y(), + principal_point_x(), + principal_point_y(), + k1(), k2(), k3(), k4(), + p1(), p2(), + image_x, + image_y, + normalized_x, + normalized_y); +} + std::ostream& operator <<(std::ostream &os, cons @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
