From 562c15cbe9463ed4ce4042846cdcffad0f11bb9c Mon Sep 17 00:00:00 2001
From: Jeff McBride <mcbridejc@gmail.com>
Date: Tue, 12 Apr 2016 01:43:41 +0000
Subject: [PATCH] Don't assume all images have the same number of calibration
 points

Cast to (int) to avoid warnings

Add test for different points number case in fisheye calibration function
---
 modules/calib3d/src/fisheye.cpp       | 12 ++++++--
 modules/calib3d/test/test_fisheye.cpp | 42 +++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/modules/calib3d/src/fisheye.cpp b/modules/calib3d/src/fisheye.cpp
index 80722f2e98..45fe230db9 100644
--- a/modules/calib3d/src/fisheye.cpp
+++ b/modules/calib3d/src/fisheye.cpp
@@ -1463,8 +1463,13 @@ void cv::internal::EstimateUncertainties(InputArrayOfArrays objectPoints, InputA
     CV_Assert(!omc.empty() && omc.type() == CV_64FC3);
     CV_Assert(!Tc.empty() && Tc.type() == CV_64FC3);
 
-    Mat ex((int)(objectPoints.getMat(0).total() * objectPoints.total()), 1, CV_64FC2);
-
+    int total_ex = 0;
+    for (int image_idx = 0; image_idx < (int)objectPoints.total(); ++image_idx)
+    {
+        total_ex += (int)objectPoints.getMat(image_idx).total();
+    }
+    Mat ex(total_ex, 1, CV_64FC2);
+    int insert_idx = 0;
     for (int image_idx = 0; image_idx < (int)objectPoints.total(); ++image_idx)
     {
         Mat image, object;
@@ -1478,7 +1483,8 @@ void cv::internal::EstimateUncertainties(InputArrayOfArrays objectPoints, InputA
         std::vector<Point2d> x;
         projectPoints(object, x, om, T, params, noArray());
         Mat ex_ = (imT ? image.t() : image) - Mat(x);
-        ex_.copyTo(ex.rowRange(ex_.rows * image_idx,  ex_.rows * (image_idx + 1)));
+        ex_.copyTo(ex.rowRange(insert_idx, insert_idx + ex_.rows));
+        insert_idx += ex_.rows;
     }
 
     meanStdDev(ex, noArray(), std_err);
diff --git a/modules/calib3d/test/test_fisheye.cpp b/modules/calib3d/test/test_fisheye.cpp
index 006f378912..9ad8c64d91 100644
--- a/modules/calib3d/test/test_fisheye.cpp
+++ b/modules/calib3d/test/test_fisheye.cpp
@@ -570,6 +570,48 @@ TEST_F(fisheyeTest, stereoCalibrateFixIntrinsic)
     EXPECT_MAT_NEAR(theT, T_correct, 1e-10);
 }
 
+TEST_F(fisheyeTest, CalibrationWithDifferentPointsNumber)
+{
+  const int n_images = 2;
+
+  std::vector<std::vector<cv::Point2d> > imagePoints(n_images);
+  std::vector<std::vector<cv::Point3d> > objectPoints(n_images);
+
+  std::vector<cv::Point2d> imgPoints1(10);
+  std::vector<cv::Point2d> imgPoints2(15);
+
+  std::vector<cv::Point3d> objectPoints1(imgPoints1.size());
+  std::vector<cv::Point3d> objectPoints2(imgPoints2.size());
+
+  for (size_t i = 0; i < imgPoints1.size(); i++)
+  {
+    imgPoints1[i] = cv::Point2d((double)i, (double)i);
+    objectPoints1[i] = cv::Point3d((double)i, (double)i, 10.0);
+  }
+
+  for (size_t i = 0; i < imgPoints2.size(); i++)
+  {
+    imgPoints2[i] = cv::Point2d(i + 0.5, i + 0.5);
+    objectPoints2[i] = cv::Point3d(i + 0.5, i + 0.5, 10.0);
+  }
+
+  imagePoints[0] = imgPoints1;
+  imagePoints[1] = imgPoints2;
+  objectPoints[0] = objectPoints1;
+  objectPoints[1] = objectPoints2;
+
+  cv::Matx33d theK = cv::Matx33d::eye();
+  cv::Vec4d theD;
+
+  int flag = 0;
+  flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
+  flag |= cv::fisheye::CALIB_USE_INTRINSIC_GUESS;
+  flag |= cv::fisheye::CALIB_FIX_SKEW;
+
+  cv::fisheye::calibrate(objectPoints, imagePoints, cv::Size(100, 100), theK, theD,
+    cv::noArray(), cv::noArray(), flag, cv::TermCriteria(3, 20, 1e-6));
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 ///  fisheyeTest::