Added support of 8UC3
authoralexey.spizhevoy <alexey.spizhevoy@itseez.com>
Mon, 6 Aug 2012 07:20:54 +0000 (11:20 +0400)
committerAlexey Spizhevoy <alexey.spizhevoy@itseez.com>
Tue, 7 Aug 2012 12:24:21 +0000 (16:24 +0400)
modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp
modules/stitching/src/seam_finders.cpp

index 009f853..7a19e45 100644 (file)
@@ -98,7 +98,7 @@ class CV_EXPORTS DpSeamFinder : public SeamFinder
 public:\r
     enum CostFunction { COLOR, COLOR_GRAD };\r
 \r
-    DpSeamFinder(CostFunction costFunc = COLOR_GRAD);\r
+    DpSeamFinder(CostFunction costFunc = COLOR);\r
 \r
     CostFunction costFunction() const { return costFunc_; }\r
     void setCostFunction(CostFunction val) { costFunc_ = val; }\r
@@ -169,10 +169,10 @@ private:
 \r
     bool closeToContour(int y, int x, const Mat_<uchar> &contourMask);\r
 \r
-    bool getSeamTips(int c1, int c2, Point &p1, Point &p2);\r
+    bool getSeamTips(int c1, int c2, Point &p1, Point &p2);    \r
 \r
     void computeCosts(const Mat &image1, const Mat &image2, Point tl1, Point tl2,\r
-                      int c, Mat_<float> &costV, Mat_<float> &costH);\r
+                      int c, Mat_<float> &costV, Mat_<float> &costH);   \r
 \r
     bool estimateSeam(\r
             const Mat &image1, const Mat &image2, Point tl1, Point tl2, int c,\r
index c155d07..cf733c9 100644 (file)
@@ -509,8 +509,6 @@ void DpSeamFinder::resolveConflicts(const Mat &image1, const Mat &image2,
 void DpSeamFinder::computeGradients(const Mat &image1, const Mat &image2)\r
 {\r
     CV_Assert(costFunction() == COLOR_GRAD);\r
-    CV_Assert(image1.type() == CV_32FC3);\r
-    CV_Assert(image2.type() == CV_32FC3);\r
 \r
     Mat gray;\r
     cvtColor(image1, gray, CV_BGR2GRAY);\r
@@ -603,8 +601,7 @@ bool DpSeamFinder::getSeamTips(int c1, int c2, Point &p1, Point &p2)
 \r
     // select two most distant clusters\r
 \r
-    int idx[2];\r
-\r
+    int idx[2] = {-1,-1};\r
     double maxDist = -numeric_limits<double>::max();\r
 \r
     for (int i = 0; i < nlabels-1; ++i)\r
@@ -658,14 +655,35 @@ bool DpSeamFinder::getSeamTips(int c1, int c2, Point &p1, Point &p2)
 }\r
 \r
 \r
+namespace\r
+{\r
+\r
+template <typename T>\r
+inline float diffL2Square(const Mat &image1, int y1, int x1, const Mat &image2, int y2, int x2)\r
+{\r
+    const T *r1 = image1.ptr<T>(y1);\r
+    const T *r2 = image2.ptr<T>(y2);\r
+    return static_cast<float>(sqr(r1[3*x1] - r2[3*x2]) + sqr(r1[3*x1+1] - r2[3*x2+1]) +\r
+                              sqr(r1[3*x1+2] - r2[3*x2+2]));\r
+}\r
+\r
+} // namespace\r
+\r
+\r
 void DpSeamFinder::computeCosts(const Mat &image1, const Mat &image2, Point tl1, Point tl2,\r
                                 int c, Mat_<float> &costV, Mat_<float> &costH)\r
 {\r
-    CV_Assert(image1.type() == CV_32FC3);\r
-    CV_Assert(image2.type() == CV_32FC3);\r
     CV_Assert(states_[c] & INTERS);\r
 \r
-    // compute costs\r
+    // compute costs    \r
+\r
+    float (*diff)(const Mat&, int, int, const Mat&, int, int) = 0;\r
+    if (image1.type() == CV_32FC3 && image2.type() == CV_32FC3)\r
+        diff = diffL2Square<float>;\r
+    else if (image1.type() == CV_8UC3 && image2.type() == CV_8UC3)\r
+        diff = diffL2Square<uchar>;\r
+    else\r
+        CV_Error(CV_StsBadArg, "both images must have CV_32FC3 or CV_8UC3 type");\r
 \r
     int l = c+1;\r
     Rect roi(tls_[c], brs_[c]);\r
@@ -684,18 +702,14 @@ void DpSeamFinder::computeCosts(const Mat &image1, const Mat &image2, Point tl1,
         {\r
             if (labels_(y, x) == l && x > 0 && labels_(y, x-1) == l)\r
             {\r
-                const Point3f &pr1 = image1.at<Point3f>(y + dy1, x + dx1);\r
-                const Point3f &pl1 = image1.at<Point3f>(y + dy1, x + dx1 - 1);\r
-                const Point3f &pr2 = image2.at<Point3f>(y + dy2, x + dx2);\r
-                const Point3f &pl2 = image2.at<Point3f>(y + dy2, x + dx2 - 1);\r
-\r
-                float costColor = (normL2(pl1, pr2) + normL2(pl2, pr1)) / 2;\r
+                float costColor = (diff(image1, y + dy1, x + dx1 - 1, image2, y + dy2, x + dx2) +\r
+                                   diff(image1, y + dy1, x + dx1, image2, y + dy2, x + dx2 - 1)) / 2;\r
                 if (costFunc_ == COLOR)\r
                     costV(y - roi.y, x - roi.x) = costColor;\r
                 else if (costFunc_ == COLOR_GRAD)\r
                 {\r
-                    float costGrad = fabs(gradx1_(y + dy1, x + dx1)) + fabs(gradx1_(y + dy1, x + dx1 - 1)) +\r
-                                     fabs(gradx2_(y + dy2, x + dx2)) + fabs(gradx2_(y + dy2, x + dx2 - 1)) + 1.f;\r
+                    float costGrad = std::abs(gradx1_(y + dy1, x + dx1)) + std::abs(gradx1_(y + dy1, x + dx1 - 1)) +\r
+                                     std::abs(gradx2_(y + dy2, x + dx2)) + std::abs(gradx2_(y + dy2, x + dx2 - 1)) + 1.f;\r
                     costV(y - roi.y, x - roi.x) = costColor / costGrad;\r
                 }\r
             }\r
@@ -712,18 +726,14 @@ void DpSeamFinder::computeCosts(const Mat &image1, const Mat &image2, Point tl1,
         {\r
             if (labels_(y, x) == l && y > 0 && labels_(y-1, x) == l)\r
             {\r
-                const Point3f &pd1 = image1.at<Point3f>(y + dy1, x + dx1);\r
-                const Point3f &pu1 = image1.at<Point3f>(y + dy1 - 1, x + dx1);\r
-                const Point3f &pd2 = image2.at<Point3f>(y + dy2, x + dx2);\r
-                const Point3f &pu2 = image2.at<Point3f>(y + dy2 - 1, x + dx2);\r
-\r
-                float costColor = (normL2(pu1, pd2) + normL2(pu2, pd1)) / 2;\r
+                float costColor = (diff(image1, y + dy1 - 1, x + dx1, image2, y + dy2, x + dx2) +\r
+                                   diff(image1, y + dy1, x + dx1, image2, y + dy2 - 1, x + dx2)) / 2;\r
                 if (costFunc_ == COLOR)\r
                     costH(y - roi.y, x - roi.x) = costColor;\r
                 else if (costFunc_ == COLOR_GRAD)\r
                 {\r
-                    float costGrad = fabs(grady1_(y + dy1, x + dx1)) + fabs(grady1_(y + dy1 - 1, x + dx1)) +\r
-                                     fabs(grady2_(y + dy2, x + dx2)) + fabs(grady2_(y + dy2 - 1, x + dx2)) + 1.f;\r
+                    float costGrad = std::abs(grady1_(y + dy1, x + dx1)) + std::abs(grady1_(y + dy1 - 1, x + dx1)) +\r
+                                     std::abs(grady2_(y + dy2, x + dx2)) + std::abs(grady2_(y + dy2 - 1, x + dx2)) + 1.f;\r
                     costH(y - roi.y, x - roi.x) = costColor / costGrad;\r
                 }\r
             }\r