converter stereo correspondence algorithms to the new style
authorVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Thu, 21 Mar 2013 21:05:30 +0000 (01:05 +0400)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Thu, 21 Mar 2013 21:05:30 +0000 (01:05 +0400)
modules/calib3d/include/opencv2/calib3d.hpp
modules/calib3d/src/compat_stereo.cpp
modules/calib3d/src/stereobm.cpp
modules/calib3d/src/stereosgbm.cpp
modules/calib3d/test/test_stereomatching.cpp
modules/gpu/perf/perf_calib3d.cpp
samples/cpp/stereo_match.cpp
samples/cpp/tutorial_code/calib3d/stereoBM/SBM_Sample.cpp

index 989912c..de44148 100644 (file)
@@ -12,6 +12,7 @@
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -372,6 +373,8 @@ CVAPI(void)  cvReprojectImageTo3D( const CvArr* disparityImage,
 #ifdef __cplusplus
 }
 
+template<> CV_EXPORTS void cv::Ptr<CvStereoBMState>::delete_obj();
+
 //////////////////////////////////////////////////////////////////////////////////////////
 class CV_EXPORTS CvLevMarq
 {
@@ -673,84 +676,95 @@ CV_EXPORTS_W void correctMatches( InputArray F, InputArray points1, InputArray p
 class CV_EXPORTS_W StereoMatcher : public Algorithm
 {
 public:
+    enum { DISP_SHIFT=4, DISP_SCALE=(1 << DISP_SHIFT) };
+
     CV_WRAP virtual void compute( InputArray left, InputArray right,
                                   OutputArray disparity ) = 0;
-};
 
-enum { STEREO_DISP_SCALE=16, STEREO_PREFILTER_NORMALIZED_RESPONSE = 0, STEREO_PREFILTER_XSOBEL = 1 };
+    CV_WRAP virtual int getMinDisparity() const = 0;
+    CV_WRAP virtual void setMinDisparity(int minDisparity) = 0;
 
-CV_EXPORTS Ptr<StereoMatcher> createStereoBM(int numDisparities=0, int SADWindowSize=21);
+    CV_WRAP virtual int getNumDisparities() const = 0;
+    CV_WRAP virtual void setNumDisparities(int numDisparities) = 0;
 
-CV_EXPORTS Ptr<StereoMatcher> createStereoSGBM(int minDisparity, int numDisparities, int SADWindowSize,
-                                               int P1=0, int P2=0, int disp12MaxDiff=0,
-                                               int preFilterCap=0, int uniquenessRatio=0,
-                                               int speckleWindowSize=0, int speckleRange=0,
-                                               bool fullDP=false);
+    CV_WRAP virtual int getBlockSize() const = 0;
+    CV_WRAP virtual void setBlockSize(int blockSize) = 0;
 
-template<> CV_EXPORTS void Ptr<CvStereoBMState>::delete_obj();
+    CV_WRAP virtual int getSpeckleWindowSize() const = 0;
+    CV_WRAP virtual void setSpeckleWindowSize(int speckleWindowSize) = 0;
+
+    CV_WRAP virtual int getSpeckleRange() const = 0;
+    CV_WRAP virtual void setSpeckleRange(int speckleRange) = 0;
+
+    CV_WRAP virtual int getDisp12MaxDiff() const = 0;
+    CV_WRAP virtual void setDisp12MaxDiff(int disp12MaxDiff) = 0;
+};
 
-// to be moved to "compat" module
-class CV_EXPORTS_W StereoBM
+    
+class CV_EXPORTS_W StereoBM : public StereoMatcher
 {
 public:
-    enum { PREFILTER_NORMALIZED_RESPONSE = 0, PREFILTER_XSOBEL = 1,
-           BASIC_PRESET=0, FISH_EYE_PRESET=1, NARROW_PRESET=2 };
-
-    //! the default constructor
-    CV_WRAP StereoBM();
-    //! the full constructor taking the camera-specific preset, number of disparities and the SAD window size
-    CV_WRAP StereoBM(int preset, int ndisparities=0, int SADWindowSize=21);
-    //! the method that reinitializes the state. The previous content is destroyed
-    void init(int preset, int ndisparities=0, int SADWindowSize=21);
-    //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair
-    CV_WRAP_AS(compute) void operator()( InputArray left, InputArray right,
-                                         OutputArray disparity, int disptype=CV_16S );
-
-    //! pointer to the underlying CvStereoBMState
-    Ptr<CvStereoBMState> state;
+    enum { PREFILTER_NORMALIZED_RESPONSE = 0, PREFILTER_XSOBEL = 1 };
+
+    CV_WRAP virtual int getPreFilterType() const = 0;
+    CV_WRAP virtual void setPreFilterType(int preFilterType) = 0;
+
+    CV_WRAP virtual int getPreFilterSize() const = 0;
+    CV_WRAP virtual void setPreFilterSize(int preFilterSize) = 0;
+
+    CV_WRAP virtual int getPreFilterCap() const = 0;
+    CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
+
+    CV_WRAP virtual int getTextureThreshold() const = 0;
+    CV_WRAP virtual void setTextureThreshold(int textureThreshold) = 0;
+
+    CV_WRAP virtual int getUniquenessRatio() const = 0;
+    CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
+
+    CV_WRAP virtual int getSmallerBlockSize() const = 0;
+    CV_WRAP virtual void setSmallerBlockSize(int blockSize) = 0;
+
+    CV_WRAP virtual Rect getROI1() const = 0;
+    CV_WRAP virtual void setROI1(Rect roi1) = 0;
+
+    CV_WRAP virtual Rect getROI2() const = 0;
+    CV_WRAP virtual void setROI2(Rect roi2) = 0;
 };
 
+CV_EXPORTS Ptr<StereoBM> createStereoBM(int numDisparities=0, int blockSize=21);
 
-// to be moved to "compat" module
-class CV_EXPORTS_W StereoSGBM
+
+class CV_EXPORTS_W StereoSGBM : public StereoMatcher
 {
 public:
-    enum { DISP_SHIFT=4, DISP_SCALE = (1<<DISP_SHIFT) };
-
-    //! the default constructor
-    CV_WRAP StereoSGBM();
-
-    //! the full constructor taking all the necessary algorithm parameters
-    CV_WRAP StereoSGBM(int minDisparity, int numDisparities, int SADWindowSize,
-               int P1=0, int P2=0, int disp12MaxDiff=0,
-               int preFilterCap=0, int uniquenessRatio=0,
-               int speckleWindowSize=0, int speckleRange=0,
-               bool fullDP=false);
-    //! the destructor
-    virtual ~StereoSGBM();
-
-    //! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair
-    CV_WRAP_AS(compute) virtual void operator()(InputArray left, InputArray right,
-                                                OutputArray disp);
-
-    CV_PROP_RW int minDisparity;
-    CV_PROP_RW int numberOfDisparities;
-    CV_PROP_RW int SADWindowSize;
-    CV_PROP_RW int preFilterCap;
-    CV_PROP_RW int uniquenessRatio;
-    CV_PROP_RW int P1;
-    CV_PROP_RW int P2;
-    CV_PROP_RW int speckleWindowSize;
-    CV_PROP_RW int speckleRange;
-    CV_PROP_RW int disp12MaxDiff;
-    CV_PROP_RW bool fullDP;
-
-protected:
-    Ptr<StereoMatcher> sm;
+    enum { MODE_SGBM=0, MODE_HH=1 };
+
+    CV_WRAP virtual int getPreFilterCap() const = 0;
+    CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
+
+    CV_WRAP virtual int getUniquenessRatio() const = 0;
+    CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
+
+    CV_WRAP virtual int getP1() const = 0;
+    CV_WRAP virtual void setP1(int P1) = 0;
+
+    CV_WRAP virtual int getP2() const = 0;
+    CV_WRAP virtual void setP2(int P2) = 0;
+
+    CV_WRAP virtual int getMode() const = 0;
+    CV_WRAP virtual void setMode(int mode) = 0;
 };
 
+
+CV_EXPORTS Ptr<StereoSGBM> createStereoSGBM(int minDisparity, int numDisparities, int blockSize,
+                                            int P1=0, int P2=0, int disp12MaxDiff=0,
+                                            int preFilterCap=0, int uniquenessRatio=0,
+                                            int speckleWindowSize=0, int speckleRange=0,
+                                            int mode=StereoSGBM::MODE_SGBM);
+
 //! filters off speckles (small regions of incorrectly computed disparity)
-CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal, int maxSpeckleSize, double maxDiff,
+CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal,
+                                  int maxSpeckleSize, double maxDiff,
                                   InputOutputArray buf=noArray() );
 
 //! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify())
index 7b9ed33..f1d9834 100644 (file)
@@ -124,93 +124,3 @@ void cvValidateDisparity( CvArr* _disp, const CvArr* _cost, int minDisparity,
     cv::Mat disp = cv::cvarrToMat(_disp), cost = cv::cvarrToMat(_cost);
     cv::validateDisparity( disp, cost, minDisparity, numberOfDisparities, disp12MaxDiff );
 }
-
-namespace cv
-{
-
-StereoBM::StereoBM()
-{ init(BASIC_PRESET); }
-
-StereoBM::StereoBM(int _preset, int _ndisparities, int _SADWindowSize)
-{ init(_preset, _ndisparities, _SADWindowSize); }
-
-void StereoBM::init(int _preset, int _ndisparities, int _SADWindowSize)
-{
-    state = cvCreateStereoBMState(_preset, _ndisparities);
-    state->SADWindowSize = _SADWindowSize;
-}
-
-void StereoBM::operator()( InputArray _left, InputArray _right,
-                          OutputArray _disparity, int disptype )
-{
-    Mat left = _left.getMat(), right = _right.getMat();
-    CV_Assert( disptype == CV_16S || disptype == CV_32F );
-    _disparity.create(left.size(), disptype);
-    Mat disp = _disparity.getMat();
-
-    CvMat left_c = left, right_c = right, disp_c = disp;
-    cvFindStereoCorrespondenceBM(&left_c, &right_c, &disp_c, state);
-}
-
-
-StereoSGBM::StereoSGBM()
-{
-    minDisparity = numberOfDisparities = 0;
-    SADWindowSize = 0;
-    P1 = P2 = 0;
-    disp12MaxDiff = 0;
-    preFilterCap = 0;
-    uniquenessRatio = 0;
-    speckleWindowSize = 0;
-    speckleRange = 0;
-    fullDP = false;
-
-    sm = createStereoSGBM(0, 0, 0);
-}
-
-StereoSGBM::StereoSGBM( int _minDisparity, int _numDisparities, int _SADWindowSize,
-                       int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap,
-                       int _uniquenessRatio, int _speckleWindowSize, int _speckleRange,
-                       bool _fullDP )
-{
-    minDisparity = _minDisparity;
-    numberOfDisparities = _numDisparities;
-    SADWindowSize = _SADWindowSize;
-    P1 = _P1;
-    P2 = _P2;
-    disp12MaxDiff = _disp12MaxDiff;
-    preFilterCap = _preFilterCap;
-    uniquenessRatio = _uniquenessRatio;
-    speckleWindowSize = _speckleWindowSize;
-    speckleRange = _speckleRange;
-    fullDP = _fullDP;
-
-    sm = createStereoSGBM(0, 0, 0);
-}
-
-StereoSGBM::~StereoSGBM()
-{
-}
-
-void StereoSGBM::operator ()( InputArray _left, InputArray _right,
-                             OutputArray _disp )
-{
-    sm->set("minDisparity", minDisparity);
-    sm->set("numDisparities", numberOfDisparities);
-    sm->set("SADWindowSize", SADWindowSize);
-    sm->set("P1", P1);
-    sm->set("P2", P2);
-    sm->set("disp12MaxDiff", disp12MaxDiff);
-    sm->set("preFilterCap", preFilterCap);
-    sm->set("uniquenessRatio", uniquenessRatio);
-    sm->set("speckleWindowSize", speckleWindowSize);
-    sm->set("speckleRange", speckleRange);
-    sm->set("fullDP", fullDP);
-
-    sm->compute(_left, _right, _disp);
-}
-
-}
-
-
-
index 158881b..a005c66 100644 (file)
@@ -56,7 +56,7 @@ struct StereoBMParams
 {
     StereoBMParams(int _numDisparities=64, int _SADWindowSize=21)
     {
-        preFilterType = STEREO_PREFILTER_XSOBEL;
+        preFilterType = StereoBM::PREFILTER_XSOBEL;
         preFilterSize = 9;
         preFilterCap = 31;
         SADWindowSize = _SADWindowSize;
@@ -676,7 +676,7 @@ struct PrefilterInvoker : public ParallelLoopBody
     {
         for( int i = range.start; i < range.end; i++ )
         {
-            if( state->preFilterType == STEREO_PREFILTER_NORMALIZED_RESPONSE )
+            if( state->preFilterType == StereoBM::PREFILTER_NORMALIZED_RESPONSE )
                 prefilterNorm( *imgs0[i], *imgs[i], state->preFilterSize, state->preFilterCap, buf[i] );
             else
                 prefilterXSobel( *imgs0[i], *imgs[i], state->preFilterCap );
@@ -771,8 +771,7 @@ protected:
     Rect validDisparityRect;
 };
 
-    
-class StereoBMImpl : public StereoMatcher
+class StereoBMImpl : public StereoBM
 {
 public:
     StereoBMImpl()
@@ -802,8 +801,8 @@ public:
         disparr.create(left0.size(), dtype);
         Mat disp0 = disparr.getMat();
 
-        if( params.preFilterType != STEREO_PREFILTER_NORMALIZED_RESPONSE &&
-            params.preFilterType != STEREO_PREFILTER_XSOBEL )
+        if( params.preFilterType != PREFILTER_NORMALIZED_RESPONSE &&
+            params.preFilterType != PREFILTER_XSOBEL )
             CV_Error( CV_StsOutOfRange, "preFilterType must be = CV_STEREO_BM_NORMALIZED_RESPONSE" );
 
         if( params.preFilterSize < 5 || params.preFilterSize > 255 || params.preFilterSize % 2 == 0 )
@@ -901,33 +900,95 @@ public:
             disp.convertTo(disp0, disp0.type(), 1./(1 << DISPARITY_SHIFT), 0);
     }
 
-    AlgorithmInfo* info() const;
+    AlgorithmInfo* info() const { return 0; }
+
+    int getMinDisparity() const { return params.minDisparity; }
+    void setMinDisparity(int minDisparity) { params.minDisparity = minDisparity; }
+
+    int getNumDisparities() const { return params.numDisparities; }
+    void setNumDisparities(int numDisparities) { params.numDisparities = numDisparities; }
+
+    int getBlockSize() const { return params.SADWindowSize; }
+    void setBlockSize(int blockSize) { params.SADWindowSize = blockSize; }
+
+    int getSpeckleWindowSize() const { return params.speckleWindowSize; }
+    void setSpeckleWindowSize(int speckleWindowSize) { params.speckleWindowSize = speckleWindowSize; }
+
+    int getSpeckleRange() const { return params.speckleRange; }
+    void setSpeckleRange(int speckleRange) { params.speckleRange = speckleRange; }
+
+    int getDisp12MaxDiff() const { return params.disp12MaxDiff; }
+    void setDisp12MaxDiff(int disp12MaxDiff) { params.disp12MaxDiff = disp12MaxDiff; }
+
+    int getPreFilterType() const { return params.preFilterType; }
+    void setPreFilterType(int preFilterType) { params.preFilterType = preFilterType; }
+
+    int getPreFilterSize() const { return params.preFilterSize; }
+    void setPreFilterSize(int preFilterSize) { params.preFilterSize = preFilterSize; }
+
+    int getPreFilterCap() const { return params.preFilterCap; }
+    void setPreFilterCap(int preFilterCap) { params.preFilterCap = preFilterCap; }
+
+    int getTextureThreshold() const { return params.textureThreshold; }
+    void setTextureThreshold(int textureThreshold) { params.textureThreshold = textureThreshold; }
+
+    int getUniquenessRatio() const { return params.uniquenessRatio; }
+    void setUniquenessRatio(int uniquenessRatio) { params.uniquenessRatio = uniquenessRatio; }
+
+    int getSmallerBlockSize() const { return 0; }
+    void setSmallerBlockSize(int) {}
+
+    Rect getROI1() const { return params.roi1; }
+    void setROI1(Rect roi1) { params.roi1 = roi1; }
+
+    Rect getROI2() const { return params.roi2; }
+    void setROI2(Rect roi2) { params.roi2 = roi2; }
+
+    void write(FileStorage& fs) const
+    {
+        fs << "name" << name_
+        << "minDisparity" << params.minDisparity
+        << "numDisparities" << params.numDisparities
+        << "blockSize" << params.SADWindowSize
+        << "speckleWindowSize" << params.speckleWindowSize
+        << "speckleRange" << params.speckleRange
+        << "disp12MaxDiff" << params.disp12MaxDiff
+        << "preFilterType" << params.preFilterType
+        << "preFilterSize" << params.preFilterSize
+        << "preFilterCap" << params.preFilterCap
+        << "textureThreshold" << params.textureThreshold
+        << "uniquenessRatio" << params.uniquenessRatio;
+    }
+
+    void read(const FileNode& fn)
+    {
+        CV_Assert( (std::string)fn["name"] == std::string(name_) );
+        params.minDisparity = (int)fn["minDisparity"];
+        params.numDisparities = (int)fn["numDisparities"];
+        params.SADWindowSize = (int)fn["blockSize"];
+        params.speckleWindowSize = (int)fn["speckleWindowSize"];
+        params.speckleRange = (int)fn["speckleRange"];
+        params.disp12MaxDiff = (int)fn["disp12MaxDiff"];
+        params.preFilterType = (int)fn["preFilterType"];
+        params.preFilterSize = (int)fn["preFilterSize"];
+        params.preFilterCap = (int)fn["preFilterCap"];
+        params.textureThreshold = (int)fn["textureThreshold"];
+        params.uniquenessRatio = (int)fn["uniquenessRatio"];
+        params.roi1 = params.roi2 = Rect();
+    }
 
     StereoBMParams params;
     Mat preFilteredImg0, preFilteredImg1, cost, dispbuf;
     Mat slidingSumBuf;
+
+    static const char* name_;
 };
 
-#define add_param(n) \
-    obj.info()->addParam(obj, #n, obj.params.n)
-
-CV_INIT_ALGORITHM(StereoBMImpl, "StereoMatcher.BM",
-                  add_param(preFilterType);
-                  add_param(preFilterSize);
-                  add_param(preFilterCap);
-                  add_param(SADWindowSize);
-                  add_param(minDisparity);
-                  add_param(numDisparities);
-                  add_param(textureThreshold);
-                  add_param(uniquenessRatio);
-                  add_param(speckleRange);
-                  add_param(speckleWindowSize);
-                  add_param(disp12MaxDiff);
-                  add_param(dispType));
+const char* StereoBMImpl::name_ = "StereoMatcher.BM";
 
 }
 
-cv::Ptr<cv::StereoMatcher> cv::createStereoBM(int _numDisparities, int _SADWindowSize)
+cv::Ptr<cv::StereoBM> cv::createStereoBM(int _numDisparities, int _SADWindowSize)
 {
     return new StereoBMImpl(_numDisparities, _SADWindowSize);
 }
index 026201f..d46c411 100644 (file)
@@ -75,13 +75,13 @@ struct StereoSGBMParams
         uniquenessRatio = 0;
         speckleWindowSize = 0;
         speckleRange = 0;
-        fullDP = false;
+        mode = StereoSGBM::MODE_SGBM;
     }
 
     StereoSGBMParams( int _minDisparity, int _numDisparities, int _SADWindowSize,
                       int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap,
                       int _uniquenessRatio, int _speckleWindowSize, int _speckleRange,
-                      bool _fullDP )
+                      int _mode )
     {
         minDisparity = _minDisparity;
         numDisparities = _numDisparities;
@@ -93,7 +93,7 @@ struct StereoSGBMParams
         uniquenessRatio = _uniquenessRatio;
         speckleWindowSize = _speckleWindowSize;
         speckleRange = _speckleRange;
-        fullDP = _fullDP;
+        mode = _mode;
     }
 
     int minDisparity;
@@ -106,7 +106,7 @@ struct StereoSGBMParams
     int speckleWindowSize;
     int speckleRange;
     int disp12MaxDiff;
-    bool fullDP;
+    int mode;
 };
 
 /*
@@ -328,8 +328,8 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
 #endif
 
     const int ALIGN = 16;
-    const int DISP_SHIFT = StereoSGBM::DISP_SHIFT;
-    const int DISP_SCALE = StereoSGBM::DISP_SCALE;
+    const int DISP_SHIFT = StereoMatcher::DISP_SHIFT;
+    const int DISP_SCALE = (1 << DISP_SHIFT);
     const CostType MAX_COST = SHRT_MAX;
 
     int minD = params.minDisparity, maxD = minD + params.numDisparities;
@@ -344,7 +344,8 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
     int D = maxD - minD, width1 = maxX1 - minX1;
     int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE;
     int SW2 = SADWindowSize.width/2, SH2 = SADWindowSize.height/2;
-    int npasses = params.fullDP ? 2 : 1;
+    bool fullDP = params.mode == StereoSGBM::MODE_HH;
+    int npasses = fullDP ? 2 : 1;
     const int TAB_OFS = 256*4, TAB_SIZE = 256 + TAB_OFS*2;
     PixType clipTab[TAB_SIZE];
 
@@ -373,7 +374,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
     // we keep pixel difference cost (C) and the summary cost over NR directions (S).
     // we also keep all the partial costs for the previous line L_r(x,d) and also min_k L_r(x, k)
     size_t costBufSize = width1*D;
-    size_t CSBufSize = costBufSize*(params.fullDP ? height : 1);
+    size_t CSBufSize = costBufSize*(fullDP ? height : 1);
     size_t minLrSize = (width1 + LrBorder*2)*NR2, LrSize = minLrSize*D2;
     int hsumBufNRows = SH2*2 + 2;
     size_t totalBufSize = (LrSize + minLrSize)*NLR*sizeof(CostType) + // minLr[] and Lr[]
@@ -434,8 +435,8 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
         {
             int x, d;
             DispType* disp1ptr = disp1.ptr<DispType>(y);
-            CostType* C = Cbuf + (!params.fullDP ? 0 : y*costBufSize);
-            CostType* S = Sbuf + (!params.fullDP ? 0 : y*costBufSize);
+            CostType* C = Cbuf + (!fullDP ? 0 : y*costBufSize);
+            CostType* S = Sbuf + (!fullDP ? 0 : y*costBufSize);
 
             if( pass == 1 ) // compute C on the first pass, and reuse it on the second pass, if any.
             {
@@ -460,7 +461,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
                         if( y > 0 )
                         {
                             const CostType* hsumSub = hsumBuf + (std::max(y - SH2 - 1, 0) % hsumBufNRows)*costBufSize;
-                            const CostType* Cprev = !params.fullDP || y == 0 ? C : C - costBufSize;
+                            const CostType* Cprev = !fullDP || y == 0 ? C : C - costBufSize;
 
                             for( x = D; x < width1*D; x += D )
                             {
@@ -828,8 +829,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
     }
 }
 
-
-class StereoSGBMImpl : public StereoMatcher
+class StereoSGBMImpl : public StereoSGBM
 {
 public:
     StereoSGBMImpl()
@@ -840,12 +840,12 @@ public:
     StereoSGBMImpl( int _minDisparity, int _numDisparities, int _SADWindowSize,
                     int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap,
                     int _uniquenessRatio, int _speckleWindowSize, int _speckleRange,
-                    bool _fullDP )
+                    int _mode )
     {
         params = StereoSGBMParams( _minDisparity, _numDisparities, _SADWindowSize,
                                    _P1, _P2, _disp12MaxDiff, _preFilterCap,
                                    _uniquenessRatio, _speckleWindowSize, _speckleRange,
-                                   _fullDP );
+                                   _mode );
     }
 
     void compute( InputArray leftarr, InputArray rightarr, OutputArray disparr )
@@ -861,47 +861,98 @@ public:
         medianBlur(disp, disp, 3);
 
         if( params.speckleWindowSize > 0 )
-            filterSpeckles(disp, (params.minDisparity - 1)*STEREO_DISP_SCALE, params.speckleWindowSize,
-                           STEREO_DISP_SCALE*params.speckleRange, buffer);
+            filterSpeckles(disp, (params.minDisparity - 1)*StereoMatcher::DISP_SCALE, params.speckleWindowSize,
+                           StereoMatcher::DISP_SCALE*params.speckleRange, buffer);
     }
 
-    AlgorithmInfo* info() const;
+    AlgorithmInfo* info() const { return 0; }
+
+    int getMinDisparity() const { return params.minDisparity; }
+    void setMinDisparity(int minDisparity) { params.minDisparity = minDisparity; }
+
+    int getNumDisparities() const { return params.numDisparities; }
+    void setNumDisparities(int numDisparities) { params.numDisparities = numDisparities; }
+
+    int getBlockSize() const { return params.SADWindowSize; }
+    void setBlockSize(int blockSize) { params.SADWindowSize = blockSize; }
+
+    int getSpeckleWindowSize() const { return params.speckleWindowSize; }
+    void setSpeckleWindowSize(int speckleWindowSize) { params.speckleWindowSize = speckleWindowSize; }
+
+    int getSpeckleRange() const { return params.speckleRange; }
+    void setSpeckleRange(int speckleRange) { params.speckleRange = speckleRange; }
+
+    int getDisp12MaxDiff() const { return params.disp12MaxDiff; }
+    void setDisp12MaxDiff(int disp12MaxDiff) { params.disp12MaxDiff = disp12MaxDiff; }
+
+    int getPreFilterCap() const { return params.preFilterCap; }
+    void setPreFilterCap(int preFilterCap) { params.preFilterCap = preFilterCap; }
+
+    int getUniquenessRatio() const { return params.uniquenessRatio; }
+    void setUniquenessRatio(int uniquenessRatio) { params.uniquenessRatio = uniquenessRatio; }
+
+    int getP1() const { return params.P1; }
+    void setP1(int P1) { params.P1 = P1; }
+
+    int getP2() const { return params.P2; }
+    void setP2(int P2) { params.P2 = P2; }
+
+    int getMode() const { return params.mode; }
+    void setMode(int mode) { params.mode = mode; }
+
+    void write(FileStorage& fs) const
+    {
+        fs << "name" << name_
+        << "minDisparity" << params.minDisparity
+        << "numDisparities" << params.numDisparities
+        << "blockSize" << params.SADWindowSize
+        << "speckleWindowSize" << params.speckleWindowSize
+        << "speckleRange" << params.speckleRange
+        << "disp12MaxDiff" << params.disp12MaxDiff
+        << "preFilterCap" << params.preFilterCap
+        << "uniquenessRatio" << params.uniquenessRatio
+        << "P1" << params.P1
+        << "P2" << params.P2
+        << "mode" << params.mode;
+    }
+
+    void read(const FileNode& fn)
+    {
+        CV_Assert( (std::string)fn["name"] == std::string(name_) );
+        params.minDisparity = (int)fn["minDisparity"];
+        params.numDisparities = (int)fn["numDisparities"];
+        params.SADWindowSize = (int)fn["blockSize"];
+        params.speckleWindowSize = (int)fn["speckleWindowSize"];
+        params.speckleRange = (int)fn["speckleRange"];
+        params.disp12MaxDiff = (int)fn["disp12MaxDiff"];
+        params.preFilterCap = (int)fn["preFilterCap"];
+        params.uniquenessRatio = (int)fn["uniquenessRatio"];
+        params.P1 = (int)fn["P1"];
+        params.P2 = (int)fn["P2"];
+        params.mode = (int)fn["mode"];
+    }
 
     StereoSGBMParams params;
     Mat buffer;
+    static const char* name_;
 };
 
+const char* StereoSGBMImpl::name_ = "StereoMatcher.SGBM";
+
 
-Ptr<StereoMatcher> createStereoSGBM(int minDisparity, int numDisparities, int SADWindowSize,
-                                    int P1, int P2, int disp12MaxDiff,
-                                    int preFilterCap, int uniquenessRatio,
-                                    int speckleWindowSize, int speckleRange,
-                                    bool fullDP)
+Ptr<StereoSGBM> createStereoSGBM(int minDisparity, int numDisparities, int SADWindowSize,
+                                 int P1, int P2, int disp12MaxDiff,
+                                 int preFilterCap, int uniquenessRatio,
+                                 int speckleWindowSize, int speckleRange,
+                                 int mode)
 {
     return new StereoSGBMImpl(minDisparity, numDisparities, SADWindowSize,
                               P1, P2, disp12MaxDiff,
                               preFilterCap, uniquenessRatio,
                               speckleWindowSize, speckleRange,
-                              fullDP);
+                              mode);
 }
 
-
-#define add_param(n) \
-    obj.info()->addParam(obj, #n, obj.params.n)
-
-CV_INIT_ALGORITHM(StereoSGBMImpl, "StereoMatcher.SGBM",
-                  add_param(minDisparity);
-                  add_param(numDisparities);
-                  add_param(SADWindowSize);
-                  add_param(preFilterCap);
-                  add_param(uniquenessRatio);
-                  add_param(P1);
-                  add_param(P2);
-                  add_param(speckleWindowSize);
-                  add_param(speckleRange);
-                  add_param(disp12MaxDiff);
-                  add_param(fullDP));
-
 Rect getValidDisparityROI( Rect roi1, Rect roi2,
                           int minDisparity,
                           int numberOfDisparities,
index 4b35dad..372e9f5 100644 (file)
@@ -700,8 +700,10 @@ protected:
         Mat leftImg; cvtColor( _leftImg, leftImg, CV_BGR2GRAY );
         Mat rightImg; cvtColor( _rightImg, rightImg, CV_BGR2GRAY );
 
-        StereoBM bm( StereoBM::BASIC_PRESET, params.ndisp, params.winSize );
-        bm( leftImg, rightImg, leftDisp, CV_32F );
+        Ptr<StereoBM> bm = createStereoBM( params.ndisp, params.winSize );
+        Mat tempDisp;
+        bm->compute( leftImg, rightImg, tempDisp );
+        tempDisp.convertTo(leftDisp, CV_32F, 1./StereoMatcher::DISP_SCALE);
         return params.winSize/2;
     }
 };
@@ -751,10 +753,13 @@ protected:
     {
         RunParams params = caseRunParams[caseIdx];
         assert( params.ndisp%16 == 0 );
-        StereoSGBM sgbm( 0, params.ndisp, params.winSize, 10*params.winSize*params.winSize, 40*params.winSize*params.winSize,
-                         1, 63, 10, 100, 32, params.fullDP );
-        sgbm( leftImg, rightImg, leftDisp );
-        assert( leftDisp.type() == CV_16SC1 );
+        Ptr<StereoSGBM> sgbm = createStereoSGBM( 0, params.ndisp, params.winSize,
+                                                 10*params.winSize*params.winSize,
+                                                 40*params.winSize*params.winSize,
+                                                 1, 63, 10, 100, 32, params.fullDP ?
+                                                 StereoSGBM::MODE_HH : StereoSGBM::MODE_SGBM );
+        sgbm->compute( leftImg, rightImg, leftDisp );
+        CV_Assert( leftDisp.type() == CV_16SC1 );
         leftDisp/=16;
         return 0;
     }
index b174d9a..1387e04 100644 (file)
@@ -37,11 +37,11 @@ PERF_TEST_P(ImagePair, Calib3D_StereoBM,
     }
     else
     {
-        cv::StereoBM bm(preset, ndisp);
+        cv::Ptr<cv::StereoBM> bm = cv::createStereoBM(ndisp);
 
         cv::Mat dst;
 
-        TEST_CYCLE() bm(imgLeft, imgRight, dst);
+        TEST_CYCLE() bm->compute(imgLeft, imgRight, dst);
 
         CPU_SANITY_CHECK(dst);
     }
index 743185e..2d4bb5f 100644 (file)
@@ -67,8 +67,8 @@ int main(int argc, char** argv)
     bool no_display = false;
     float scale = 1.f;
 
-    Ptr<StereoMatcher> bm = createStereoBM(16,9);
-    Ptr<StereoMatcher> sgbm = createStereoSGBM(0,16,3);
+    Ptr<StereoBM> bm = createStereoBM(16,9);
+    Ptr<StereoSGBM> sgbm = createStereoSGBM(0,16,3);
     StereoVar var;
 
     for( int i = 1; i < argc; i++ )
@@ -221,33 +221,33 @@ int main(int argc, char** argv)
 
     numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : ((img_size.width/8) + 15) & -16;
 
-    //bm->set("roi1", roi1);
-    //bm->set("roi2", roi2);
-    bm->set("preFilterCap", 31);
-    bm->set("SADWindowSize", SADWindowSize > 0 ? SADWindowSize : 9);
-    bm->set("minDisparity", 0);
-    bm->set("numDisparities", numberOfDisparities);
-    bm->set("textureThreshold", 10);
-    bm->set("uniquenessRatio", 15);
-    bm->set("speckleWindowSize", 100);
-    bm->set("speckleRange", 32);
-    bm->set("disp12MaxDiff", 1);
-
-    sgbm->set("preFilterCap", 63);
+    bm->setROI1(roi1);
+    bm->setROI2(roi2);
+    bm->setPreFilterCap(31);
+    bm->setBlockSize(SADWindowSize > 0 ? SADWindowSize : 9);
+    bm->setMinDisparity(0);
+    bm->setNumDisparities(numberOfDisparities);
+    bm->setTextureThreshold(10);
+    bm->setUniquenessRatio(15);
+    bm->setSpeckleWindowSize(100);
+    bm->setSpeckleRange(32);
+    bm->setDisp12MaxDiff(1);
+
+    sgbm->setPreFilterCap(63);
     int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
-    sgbm->set("SADWindowSize", sgbmWinSize);
+    sgbm->setBlockSize(sgbmWinSize);
 
     int cn = img1.channels();
 
-    sgbm->set("P1", 8*cn*sgbmWinSize*sgbmWinSize);
-    sgbm->set("P2", 32*cn*sgbmWinSize*sgbmWinSize);
-    sgbm->set("minDisparity", 0);
-    sgbm->set("numDisparities", numberOfDisparities);
-    sgbm->set("uniquenessRatio", 10);
-    sgbm->set("speckleWindowSize", 100);
-    sgbm->set("speckleRange", 32);
-    sgbm->set("disp12MaxDiff", 1);
-    sgbm->set("fullDP", alg == STEREO_HH);
+    sgbm->setP1(8*cn*sgbmWinSize*sgbmWinSize);
+    sgbm->setP2(32*cn*sgbmWinSize*sgbmWinSize);
+    sgbm->setMinDisparity(0);
+    sgbm->setNumDisparities(numberOfDisparities);
+    sgbm->setUniquenessRatio(10);
+    sgbm->setSpeckleWindowSize(100);
+    sgbm->setSpeckleRange(32);
+    sgbm->setDisp12MaxDiff(1);
+    sgbm->setMode(alg == STEREO_HH ? StereoSGBM::MODE_HH : StereoSGBM::MODE_SGBM);
 
     var.levels = 3;                                 // ignored with USE_AUTO_PARAMS
     var.pyrScale = 0.5;                             // ignored with USE_AUTO_PARAMS
index 13d5aa8..18244c5 100644 (file)
@@ -39,12 +39,10 @@ int main( int argc, char** argv )
   int ndisparities = 16*5;   /**< Range of disparity */
   int SADWindowSize = 21; /**< Size of the block window. Must be odd */
 
-  StereoBM sbm( StereoBM::BASIC_PRESET,
-                                ndisparities,
-                SADWindowSize );
+  Ptr<StereoBM> sbm = createStereoBM( ndisparities, SADWindowSize );
 
   //-- 3. Calculate the disparity image
-  sbm( imgLeft, imgRight, imgDisparity16S, CV_16S );
+  sbm->compute( imgLeft, imgRight, imgDisparity16S );
 
   //-- Check its extreme values
   double minVal; double maxVal;