include/opencv2/stitching/detail/seam_finders.hpp
Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                          License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_STITCHING_SEAM_FINDERS_HPP__
00044 #define __OPENCV_STITCHING_SEAM_FINDERS_HPP__
00045 
00046 #include <set>
00047 #include "opencv2/core/core.hpp"
00048 #include "opencv2/opencv_modules.hpp"
00049 
00050 namespace cv {
00051 namespace detail {
00052 
00053 class CV_EXPORTS SeamFinder
00054 {
00055 public:
00056     virtual ~SeamFinder() {}
00057     virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
00058                       std::vector<Mat> &masks) = 0;
00059 };
00060 
00061 
00062 class CV_EXPORTS NoSeamFinder : public SeamFinder
00063 {
00064 public:
00065     void find(const std::vector<Mat>&, const std::vector<Point>&, std::vector<Mat>&) {}
00066 };
00067 
00068 
00069 class CV_EXPORTS PairwiseSeamFinder : public SeamFinder
00070 {
00071 public:
00072     virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
00073                       std::vector<Mat> &masks);
00074 
00075 protected:
00076     void run();
00077     virtual void findInPair(size_t first, size_t second, Rect roi) = 0;
00078 
00079     std::vector<Mat> images_;
00080     std::vector<Size> sizes_;
00081     std::vector<Point> corners_;
00082     std::vector<Mat> masks_;
00083 };
00084 
00085 
00086 class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder
00087 {
00088 public:
00089     virtual void find(const std::vector<Size> &size, const std::vector<Point> &corners,
00090                       std::vector<Mat> &masks);
00091 private:
00092     void findInPair(size_t first, size_t second, Rect roi);
00093 };
00094 
00095 
00096 class CV_EXPORTS DpSeamFinder : public SeamFinder
00097 {
00098 public:
00099     enum CostFunction { COLOR, COLOR_GRAD };
00100 
00101     DpSeamFinder(CostFunction costFunc = COLOR);
00102 
00103     CostFunction costFunction() const { return costFunc_; }
00104     void setCostFunction(CostFunction val) { costFunc_ = val; }
00105 
00106     virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
00107                       std::vector<Mat> &masks);
00108 
00109 private:
00110     enum ComponentState
00111     {
00112         FIRST = 1, SECOND = 2, INTERS = 4,
00113         INTERS_FIRST = INTERS | FIRST,
00114         INTERS_SECOND = INTERS | SECOND
00115     };
00116 
00117     class ImagePairLess
00118     {
00119     public:
00120         ImagePairLess(const std::vector<Mat> &images, const std::vector<Point> &corners)
00121             : src_(&images[0]), corners_(&corners[0]) {}
00122 
00123         bool operator() (const std::pair<size_t, size_t> &l, const std::pair<size_t, size_t> &r) const
00124         {
00125             Point c1 = corners_[l.first] + Point(src_[l.first].cols / 2, src_[l.first].rows / 2);
00126             Point c2 = corners_[l.second] + Point(src_[l.second].cols / 2, src_[l.second].rows / 2);
00127             int d1 = (c1 - c2).dot(c1 - c2);
00128 
00129             c1 = corners_[r.first] + Point(src_[r.first].cols / 2, src_[r.first].rows / 2);
00130             c2 = corners_[r.second] + Point(src_[r.second].cols / 2, src_[r.second].rows / 2);
00131             int d2 = (c1 - c2).dot(c1 - c2);
00132 
00133             return d1 < d2;
00134         }
00135 
00136     private:
00137         const Mat *src_;
00138         const Point *corners_;
00139     };
00140 
00141     class ClosePoints
00142     {
00143     public:
00144         ClosePoints(int minDist) : minDist_(minDist) {}
00145 
00146         bool operator() (const Point &p1, const Point &p2) const
00147         {
00148             int dist2 = (p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y);
00149             return dist2 < minDist_ * minDist_;
00150         }
00151 
00152     private:
00153         int minDist_;
00154     };
00155 
00156     void process(
00157             const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
00158 
00159     void findComponents();
00160 
00161     void findEdges();
00162 
00163     void resolveConflicts(
00164             const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
00165 
00166     void computeGradients(const Mat &image1, const Mat &image2);
00167 
00168     bool hasOnlyOneNeighbor(int comp);
00169 
00170     bool closeToContour(int y, int x, const Mat_<uchar> &contourMask);
00171 
00172     bool getSeamTips(int comp1, int comp2, Point &p1, Point &p2);
00173 
00174     void computeCosts(
00175             const Mat &image1, const Mat &image2, Point tl1, Point tl2,
00176             int comp, Mat_<float> &costV, Mat_<float> &costH);
00177 
00178     bool estimateSeam(
00179             const Mat &image1, const Mat &image2, Point tl1, Point tl2, int comp,
00180             Point p1, Point p2, std::vector<Point> &seam, bool &isHorizontal);
00181 
00182     void updateLabelsUsingSeam(
00183             int comp1, int comp2, const std::vector<Point> &seam, bool isHorizontalSeam);
00184 
00185     CostFunction costFunc_;
00186 
00187     // processing images pair data
00188     Point unionTl_, unionBr_;
00189     Size unionSize_;
00190     Mat_<uchar> mask1_, mask2_;
00191     Mat_<uchar> contour1mask_, contour2mask_;
00192     Mat_<float> gradx1_, grady1_;
00193     Mat_<float> gradx2_, grady2_;
00194 
00195     // components data
00196     int ncomps_;
00197     Mat_<int> labels_;
00198     std::vector<ComponentState> states_;
00199     std::vector<Point> tls_, brs_;
00200     std::vector<std::vector<Point> > contours_;
00201     std::set<std::pair<int, int> > edges_;
00202 };
00203 
00204 
00205 class CV_EXPORTS GraphCutSeamFinderBase
00206 {
00207 public:
00208     enum { COST_COLOR, COST_COLOR_GRAD };
00209 };
00210 
00211 
00212 class CV_EXPORTS GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
00213 {
00214 public:
00215     GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
00216                        float bad_region_penalty = 1000.f);
00217 
00218     ~GraphCutSeamFinder();
00219 
00220     void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
00221               std::vector<Mat> &masks);
00222 
00223 private:
00224     // To avoid GCGraph dependency
00225     class Impl;
00226     Ptr<PairwiseSeamFinder> impl_;
00227 };
00228 
00229 
00230 #ifdef HAVE_OPENCV_GPU
00231 class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
00232 {
00233 public:
00234     GraphCutSeamFinderGpu(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
00235                           float bad_region_penalty = 1000.f)
00236                           : cost_type_(cost_type), terminal_cost_(terminal_cost),
00237                             bad_region_penalty_(bad_region_penalty) {}
00238 
00239     void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
00240               std::vector<cv::Mat> &masks);
00241     void findInPair(size_t first, size_t second, Rect roi);
00242 
00243 private:
00244     void setGraphWeightsColor(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &mask1, const cv::Mat &mask2,
00245                               cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
00246     void setGraphWeightsColorGrad(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &dx1, const cv::Mat &dx2,
00247                                   const cv::Mat &dy1, const cv::Mat &dy2, const cv::Mat &mask1, const cv::Mat &mask2,
00248                                   cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
00249     std::vector<Mat> dx_, dy_;
00250     int cost_type_;
00251     float terminal_cost_;
00252     float bad_region_penalty_;
00253 };
00254 #endif
00255 
00256 } // namespace detail
00257 } // namespace cv
00258 
00259 #endif // __OPENCV_STITCHING_SEAM_FINDERS_HPP__