fixed BA error calculation in opencv_stitching, added draft version of waveCorrect
authorAlexey Spizhevoy <no@email>
Thu, 5 May 2011 15:12:36 +0000 (15:12 +0000)
committerAlexey Spizhevoy <no@email>
Thu, 5 May 2011 15:12:36 +0000 (15:12 +0000)
modules/stitching/blenders.hpp
modules/stitching/main.cpp
modules/stitching/motion_estimators.cpp
modules/stitching/motion_estimators.hpp

index 26c630968e4ae618dd73562cd2fde564d6551990..b9a143951f56e8dd7631fd95ef95987eb6522df8 100644 (file)
@@ -39,7 +39,7 @@ private:
 class MultiBandBlender : public Blender
 {
 public:
-    MultiBandBlender(int num_bands = 10) : num_bands_(num_bands) {}
+    MultiBandBlender(int num_bands = 7) : num_bands_(num_bands) {}
 
 private:
     cv::Point blend(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &masks,
index 38e512406aaac36481bed3b77a79a1a4ea6fc579..5f8fce31022c4886d93ab9e509fc5a1d30e084be 100644 (file)
@@ -14,7 +14,8 @@ void printUsage()
     cout << "Rotation model images stitcher.\n" \r
         << "Usage: opencv_stitching img1 img2 [...imgN]\n" \r
         << "\t[--matchconf <0.0-1.0>]\n"\r
-        << "\t[--ba (ray_space|focal_ray_space)]\n"\r
+        << "\t[--ba (ray|focal_ray)]\n"\r
+        //<< "\t[--wavecorrect (no|yes)]\n"\r
         << "\t[--warp (plane|cylindrical|spherical)]\n" \r
         << "\t[--seam (no|voronoi|graphcut)]\n" \r
         << "\t[--blend (no|feather|multiband)]\n"\r
@@ -28,6 +29,7 @@ int main(int argc, char* argv[])
     vector<Mat> images;\r
     string result_name = "result.png";\r
     int ba_space = BundleAdjuster::RAY_SPACE;\r
+    bool wave_correct = false;\r
     int warp_type = Warper::SPHERICAL;\r
     bool user_match_conf = false;\r
     float match_conf = 0.55f;\r
@@ -55,9 +57,9 @@ int main(int argc, char* argv[])
         }\r
         else if (string(argv[i]) == "--ba")\r
         {\r
-            if (string(argv[i + 1]) == "ray_space")\r
+            if (string(argv[i + 1]) == "ray")\r
                 ba_space = BundleAdjuster::RAY_SPACE;\r
-            else if (string(argv[i + 1]) == "focal_ray_space")\r
+            else if (string(argv[i + 1]) == "focal_ray")\r
                 ba_space = BundleAdjuster::FOCAL_RAY_SPACE;\r
             else\r
             {\r
@@ -66,6 +68,19 @@ int main(int argc, char* argv[])
             }\r
             i++;\r
         }\r
+        //else if (string(argv[i]) == "--wavecorrect")\r
+        //{\r
+        //    if (string(argv[i + 1]) == "no")\r
+        //        wave_correct = false;\r
+        //    else if (string(argv[i + 1]) == "yes")\r
+        //        wave_correct = true;\r
+        //    else\r
+        //    {\r
+        //        cout << "Bad wave correct flag value\n";\r
+        //        return -1;\r
+        //    }\r
+        //    i++;\r
+        //}\r
         else if (string(argv[i]) == "--warp")\r
         {\r
             if (string(argv[i + 1]) == "plane")\r
@@ -164,6 +179,17 @@ int main(int argc, char* argv[])
     BundleAdjuster adjuster(ba_space);\r
     adjuster(images, features, pairwise_matches, cameras);\r
 \r
+    if (wave_correct)\r
+    {\r
+        LOGLN("Wave correcting...");\r
+        vector<Mat> rmats;\r
+        for (size_t i = 0; i < cameras.size(); ++i)\r
+            rmats.push_back(cameras[i].M);\r
+        waveCorrect(rmats);\r
+        for (size_t i = 0; i < cameras.size(); ++i)\r
+            cameras[i].M = rmats[i];\r
+    }\r
+\r
     // Find median focal length\r
     vector<double> focals;\r
     for (size_t i = 0; i < cameras.size(); ++i)\r
index a40afd4302b76e33c127eca557a1c5c35845c4b5..952077ae957039ccd8af90ab8bb3862218ea26bf 100644 (file)
@@ -19,8 +19,8 @@ namespace
     public:
         inline CpuSurfFeaturesFinder() 
         {
-            detector_ = new SurfFeatureDetector(500.0);
-            extractor_ = new SurfDescriptorExtractor;
+            detector_ = new SurfFeatureDetector(500);
+            extractor_ = new SurfDescriptorExtractor();
         }
 
     protected:
@@ -491,17 +491,8 @@ void BundleAdjuster::estimate(const vector<Mat> &images, const vector<ImageFeatu
 
     edges_.clear();
     for (int i = 0; i < num_images_ - 1; ++i)
-    {
         for (int j = i + 1; j < num_images_; ++j)
-        {
-            int pair_idx = i * num_images_ + j;
-            const MatchesInfo& mi = pairwise_matches_[pair_idx];
-            float ni = static_cast<float>(mi.num_inliers);
-            float nf = static_cast<float>(mi.matches.size());
-            if (ni / (8.f + 0.3f * nf) > 1.f)
-                edges_.push_back(make_pair(i, j));
-        }
-    }
+            edges_.push_back(make_pair(i, j));
 
     total_num_matches_ = 0;
     for (size_t i = 0; i < edges_.size(); ++i)
@@ -683,6 +674,43 @@ void BundleAdjuster::calcJacobian()
 }
 
 
+//////////////////////////////////////////////////////////////////////////////
+
+// TODO test on adobe/halfdome
+void waveCorrect(vector<Mat> &rmats)
+{
+    float data[9];
+    Mat r0(1, 3, CV_32F, data);
+    Mat r1(1, 3, CV_32F, data + 3);
+    Mat r2(1, 3, CV_32F, data + 6);
+    Mat R(3, 3, CV_32F, data);
+
+    Mat cov = Mat::zeros(3, 3, CV_32F);
+    for (size_t i = 0; i < rmats.size(); ++i)
+    {   
+        Mat r0 = rmats[i].col(0);
+        cov += r0 * r0.t();
+    }
+
+    SVD svd;
+    svd(cov, SVD::FULL_UV);
+    svd.vt.row(2).copyTo(r1);
+    if (determinant(svd.vt) < 0)
+        r1 *= -1;
+
+    Mat avgz = Mat::zeros(3, 1, CV_32F);
+    for (size_t i = 0; i < rmats.size(); ++i)
+        avgz += rmats[i].col(2);
+    avgz.t().cross(r1).copyTo(r0);
+    normalize(r0, r0);
+
+    r0.cross(r1).copyTo(r2);
+
+    for (size_t i = 0; i < rmats.size(); ++i)
+        rmats[i] = R * rmats[i];
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 
 void findMaxSpanningTree(int num_images, const vector<MatchesInfo> &pairwise_matches,
index 8540114577038b85ae433826e7680afc0297f54f..02d4023ab05db765e1097dde8279597b940a6c36 100644 (file)
@@ -148,6 +148,9 @@ private:
 };
 
 
+void waveCorrect(std::vector<cv::Mat> &rmats);
+
+
 //////////////////////////////////////////////////////////////////////////////
 // Auxiliary functions