[Bf-blender-cvs] [3a7d62cd1f5] master: Tracking: Implement Brown-Conrady distortion model

Ivan Perevala noreply at git.blender.org
Wed Sep 30 16:04:12 CEST 2020


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. @@



More information about the Bf-blender-cvs mailing list