converter stereo correspondence algorithms to the new style

pull/692/head
Vadim Pisarevsky 12 years ago
parent bbae05413d
commit 7661625c39
  1. 128
      modules/calib3d/include/opencv2/calib3d.hpp
  2. 90
      modules/calib3d/src/compat_stereo.cpp
  3. 109
      modules/calib3d/src/stereobm.cpp
  4. 127
      modules/calib3d/src/stereosgbm.cpp
  5. 17
      modules/calib3d/test/test_stereomatching.cpp
  6. 4
      modules/gpu/perf/perf_calib3d.cpp
  7. 50
      samples/cpp/stereo_match.cpp
  8. 6
      samples/cpp/tutorial_code/calib3d/stereoBM/SBM_Sample.cpp

@ -12,6 +12,7 @@
// //
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., 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. // Third party copyrights are property of their respective owners.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
@ -372,6 +373,8 @@ CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage,
#ifdef __cplusplus #ifdef __cplusplus
} }
template<> CV_EXPORTS void cv::Ptr<CvStereoBMState>::delete_obj();
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
class CV_EXPORTS CvLevMarq 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 class CV_EXPORTS_W StereoMatcher : public Algorithm
{ {
public: public:
enum { DISP_SHIFT=4, DISP_SCALE=(1 << DISP_SHIFT) };
CV_WRAP virtual void compute( InputArray left, InputArray right, CV_WRAP virtual void compute( InputArray left, InputArray right,
OutputArray disparity ) = 0; 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, CV_WRAP virtual int getBlockSize() const = 0;
int P1=0, int P2=0, int disp12MaxDiff=0, CV_WRAP virtual void setBlockSize(int blockSize) = 0;
int preFilterCap=0, int uniquenessRatio=0,
int speckleWindowSize=0, int speckleRange=0,
bool fullDP=false);
template<> CV_EXPORTS void Ptr<CvStereoBMState>::delete_obj(); CV_WRAP virtual int getSpeckleWindowSize() const = 0;
CV_WRAP virtual void setSpeckleWindowSize(int speckleWindowSize) = 0;
// to be moved to "compat" module CV_WRAP virtual int getSpeckleRange() const = 0;
class CV_EXPORTS_W StereoBM CV_WRAP virtual void setSpeckleRange(int speckleRange) = 0;
CV_WRAP virtual int getDisp12MaxDiff() const = 0;
CV_WRAP virtual void setDisp12MaxDiff(int disp12MaxDiff) = 0;
};
class CV_EXPORTS_W StereoBM : public StereoMatcher
{ {
public: public:
enum { PREFILTER_NORMALIZED_RESPONSE = 0, PREFILTER_XSOBEL = 1, enum { PREFILTER_NORMALIZED_RESPONSE = 0, PREFILTER_XSOBEL = 1 };
BASIC_PRESET=0, FISH_EYE_PRESET=1, NARROW_PRESET=2 };
CV_WRAP virtual int getPreFilterType() const = 0;
//! the default constructor CV_WRAP virtual void setPreFilterType(int preFilterType) = 0;
CV_WRAP StereoBM();
//! the full constructor taking the camera-specific preset, number of disparities and the SAD window size CV_WRAP virtual int getPreFilterSize() const = 0;
CV_WRAP StereoBM(int preset, int ndisparities=0, int SADWindowSize=21); CV_WRAP virtual void setPreFilterSize(int preFilterSize) = 0;
//! the method that reinitializes the state. The previous content is destroyed
void init(int preset, int ndisparities=0, int SADWindowSize=21); CV_WRAP virtual int getPreFilterCap() const = 0;
//! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
CV_WRAP_AS(compute) void operator()( InputArray left, InputArray right,
OutputArray disparity, int disptype=CV_16S ); CV_WRAP virtual int getTextureThreshold() const = 0;
CV_WRAP virtual void setTextureThreshold(int textureThreshold) = 0;
//! pointer to the underlying CvStereoBMState
Ptr<CvStereoBMState> state; 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 : public StereoMatcher
class CV_EXPORTS_W StereoSGBM
{ {
public: public:
enum { DISP_SHIFT=4, DISP_SCALE = (1<<DISP_SHIFT) }; enum { MODE_SGBM=0, MODE_HH=1 };
//! the default constructor CV_WRAP virtual int getPreFilterCap() const = 0;
CV_WRAP StereoSGBM(); CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
//! the full constructor taking all the necessary algorithm parameters CV_WRAP virtual int getUniquenessRatio() const = 0;
CV_WRAP StereoSGBM(int minDisparity, int numDisparities, int SADWindowSize, 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 P1=0, int P2=0, int disp12MaxDiff=0,
int preFilterCap=0, int uniquenessRatio=0, int preFilterCap=0, int uniquenessRatio=0,
int speckleWindowSize=0, int speckleRange=0, int speckleWindowSize=0, int speckleRange=0,
bool fullDP=false); int mode=StereoSGBM::MODE_SGBM);
//! 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;
};
//! filters off speckles (small regions of incorrectly computed disparity) //! 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() ); InputOutputArray buf=noArray() );
//! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify()) //! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify())

@ -124,93 +124,3 @@ void cvValidateDisparity( CvArr* _disp, const CvArr* _cost, int minDisparity,
cv::Mat disp = cv::cvarrToMat(_disp), cost = cv::cvarrToMat(_cost); cv::Mat disp = cv::cvarrToMat(_disp), cost = cv::cvarrToMat(_cost);
cv::validateDisparity( disp, cost, minDisparity, numberOfDisparities, disp12MaxDiff ); 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);
}
}

@ -56,7 +56,7 @@ struct StereoBMParams
{ {
StereoBMParams(int _numDisparities=64, int _SADWindowSize=21) StereoBMParams(int _numDisparities=64, int _SADWindowSize=21)
{ {
preFilterType = STEREO_PREFILTER_XSOBEL; preFilterType = StereoBM::PREFILTER_XSOBEL;
preFilterSize = 9; preFilterSize = 9;
preFilterCap = 31; preFilterCap = 31;
SADWindowSize = _SADWindowSize; SADWindowSize = _SADWindowSize;
@ -676,7 +676,7 @@ struct PrefilterInvoker : public ParallelLoopBody
{ {
for( int i = range.start; i < range.end; i++ ) 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] ); prefilterNorm( *imgs0[i], *imgs[i], state->preFilterSize, state->preFilterCap, buf[i] );
else else
prefilterXSobel( *imgs0[i], *imgs[i], state->preFilterCap ); prefilterXSobel( *imgs0[i], *imgs[i], state->preFilterCap );
@ -771,8 +771,7 @@ protected:
Rect validDisparityRect; Rect validDisparityRect;
}; };
class StereoBMImpl : public StereoBM
class StereoBMImpl : public StereoMatcher
{ {
public: public:
StereoBMImpl() StereoBMImpl()
@ -802,8 +801,8 @@ public:
disparr.create(left0.size(), dtype); disparr.create(left0.size(), dtype);
Mat disp0 = disparr.getMat(); Mat disp0 = disparr.getMat();
if( params.preFilterType != STEREO_PREFILTER_NORMALIZED_RESPONSE && if( params.preFilterType != PREFILTER_NORMALIZED_RESPONSE &&
params.preFilterType != STEREO_PREFILTER_XSOBEL ) params.preFilterType != PREFILTER_XSOBEL )
CV_Error( CV_StsOutOfRange, "preFilterType must be = CV_STEREO_BM_NORMALIZED_RESPONSE" ); CV_Error( CV_StsOutOfRange, "preFilterType must be = CV_STEREO_BM_NORMALIZED_RESPONSE" );
if( params.preFilterSize < 5 || params.preFilterSize > 255 || params.preFilterSize % 2 == 0 ) 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); 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; StereoBMParams params;
Mat preFilteredImg0, preFilteredImg1, cost, dispbuf; Mat preFilteredImg0, preFilteredImg1, cost, dispbuf;
Mat slidingSumBuf; Mat slidingSumBuf;
};
#define add_param(n) \ static const char* name_;
obj.info()->addParam(obj, #n, obj.params.n) };
CV_INIT_ALGORITHM(StereoBMImpl, "StereoMatcher.BM", const char* StereoBMImpl::name_ = "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));
} }
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); return new StereoBMImpl(_numDisparities, _SADWindowSize);
} }

@ -75,13 +75,13 @@ struct StereoSGBMParams
uniquenessRatio = 0; uniquenessRatio = 0;
speckleWindowSize = 0; speckleWindowSize = 0;
speckleRange = 0; speckleRange = 0;
fullDP = false; mode = StereoSGBM::MODE_SGBM;
} }
StereoSGBMParams( int _minDisparity, int _numDisparities, int _SADWindowSize, StereoSGBMParams( int _minDisparity, int _numDisparities, int _SADWindowSize,
int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap, int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap,
int _uniquenessRatio, int _speckleWindowSize, int _speckleRange, int _uniquenessRatio, int _speckleWindowSize, int _speckleRange,
bool _fullDP ) int _mode )
{ {
minDisparity = _minDisparity; minDisparity = _minDisparity;
numDisparities = _numDisparities; numDisparities = _numDisparities;
@ -93,7 +93,7 @@ struct StereoSGBMParams
uniquenessRatio = _uniquenessRatio; uniquenessRatio = _uniquenessRatio;
speckleWindowSize = _speckleWindowSize; speckleWindowSize = _speckleWindowSize;
speckleRange = _speckleRange; speckleRange = _speckleRange;
fullDP = _fullDP; mode = _mode;
} }
int minDisparity; int minDisparity;
@ -106,7 +106,7 @@ struct StereoSGBMParams
int speckleWindowSize; int speckleWindowSize;
int speckleRange; int speckleRange;
int disp12MaxDiff; int disp12MaxDiff;
bool fullDP; int mode;
}; };
/* /*
@ -328,8 +328,8 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
#endif #endif
const int ALIGN = 16; const int ALIGN = 16;
const int DISP_SHIFT = StereoSGBM::DISP_SHIFT; const int DISP_SHIFT = StereoMatcher::DISP_SHIFT;
const int DISP_SCALE = StereoSGBM::DISP_SCALE; const int DISP_SCALE = (1 << DISP_SHIFT);
const CostType MAX_COST = SHRT_MAX; const CostType MAX_COST = SHRT_MAX;
int minD = params.minDisparity, maxD = minD + params.numDisparities; 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 D = maxD - minD, width1 = maxX1 - minX1;
int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE; int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE;
int SW2 = SADWindowSize.width/2, SH2 = SADWindowSize.height/2; 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; const int TAB_OFS = 256*4, TAB_SIZE = 256 + TAB_OFS*2;
PixType clipTab[TAB_SIZE]; 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 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) // 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 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; size_t minLrSize = (width1 + LrBorder*2)*NR2, LrSize = minLrSize*D2;
int hsumBufNRows = SH2*2 + 2; int hsumBufNRows = SH2*2 + 2;
size_t totalBufSize = (LrSize + minLrSize)*NLR*sizeof(CostType) + // minLr[] and Lr[] 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; int x, d;
DispType* disp1ptr = disp1.ptr<DispType>(y); DispType* disp1ptr = disp1.ptr<DispType>(y);
CostType* C = Cbuf + (!params.fullDP ? 0 : y*costBufSize); CostType* C = Cbuf + (!fullDP ? 0 : y*costBufSize);
CostType* S = Sbuf + (!params.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. 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 ) if( y > 0 )
{ {
const CostType* hsumSub = hsumBuf + (std::max(y - SH2 - 1, 0) % hsumBufNRows)*costBufSize; 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 ) for( x = D; x < width1*D; x += D )
{ {
@ -828,8 +829,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
} }
} }
class StereoSGBMImpl : public StereoSGBM
class StereoSGBMImpl : public StereoMatcher
{ {
public: public:
StereoSGBMImpl() StereoSGBMImpl()
@ -840,12 +840,12 @@ public:
StereoSGBMImpl( int _minDisparity, int _numDisparities, int _SADWindowSize, StereoSGBMImpl( int _minDisparity, int _numDisparities, int _SADWindowSize,
int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap, int _P1, int _P2, int _disp12MaxDiff, int _preFilterCap,
int _uniquenessRatio, int _speckleWindowSize, int _speckleRange, int _uniquenessRatio, int _speckleWindowSize, int _speckleRange,
bool _fullDP ) int _mode )
{ {
params = StereoSGBMParams( _minDisparity, _numDisparities, _SADWindowSize, params = StereoSGBMParams( _minDisparity, _numDisparities, _SADWindowSize,
_P1, _P2, _disp12MaxDiff, _preFilterCap, _P1, _P2, _disp12MaxDiff, _preFilterCap,
_uniquenessRatio, _speckleWindowSize, _speckleRange, _uniquenessRatio, _speckleWindowSize, _speckleRange,
_fullDP ); _mode );
} }
void compute( InputArray leftarr, InputArray rightarr, OutputArray disparr ) void compute( InputArray leftarr, InputArray rightarr, OutputArray disparr )
@ -861,47 +861,98 @@ public:
medianBlur(disp, disp, 3); medianBlur(disp, disp, 3);
if( params.speckleWindowSize > 0 ) if( params.speckleWindowSize > 0 )
filterSpeckles(disp, (params.minDisparity - 1)*STEREO_DISP_SCALE, params.speckleWindowSize, filterSpeckles(disp, (params.minDisparity - 1)*StereoMatcher::DISP_SCALE, params.speckleWindowSize,
STEREO_DISP_SCALE*params.speckleRange, buffer); StereoMatcher::DISP_SCALE*params.speckleRange, buffer);
}
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;
} }
AlgorithmInfo* info() const; 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; StereoSGBMParams params;
Mat buffer; Mat buffer;
static const char* name_;
}; };
const char* StereoSGBMImpl::name_ = "StereoMatcher.SGBM";
Ptr<StereoMatcher> createStereoSGBM(int minDisparity, int numDisparities, int SADWindowSize, Ptr<StereoSGBM> createStereoSGBM(int minDisparity, int numDisparities, int SADWindowSize,
int P1, int P2, int disp12MaxDiff, int P1, int P2, int disp12MaxDiff,
int preFilterCap, int uniquenessRatio, int preFilterCap, int uniquenessRatio,
int speckleWindowSize, int speckleRange, int speckleWindowSize, int speckleRange,
bool fullDP) int mode)
{ {
return new StereoSGBMImpl(minDisparity, numDisparities, SADWindowSize, return new StereoSGBMImpl(minDisparity, numDisparities, SADWindowSize,
P1, P2, disp12MaxDiff, P1, P2, disp12MaxDiff,
preFilterCap, uniquenessRatio, preFilterCap, uniquenessRatio,
speckleWindowSize, speckleRange, 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, Rect getValidDisparityROI( Rect roi1, Rect roi2,
int minDisparity, int minDisparity,
int numberOfDisparities, int numberOfDisparities,

@ -700,8 +700,10 @@ protected:
Mat leftImg; cvtColor( _leftImg, leftImg, CV_BGR2GRAY ); Mat leftImg; cvtColor( _leftImg, leftImg, CV_BGR2GRAY );
Mat rightImg; cvtColor( _rightImg, rightImg, CV_BGR2GRAY ); Mat rightImg; cvtColor( _rightImg, rightImg, CV_BGR2GRAY );
StereoBM bm( StereoBM::BASIC_PRESET, params.ndisp, params.winSize ); Ptr<StereoBM> bm = createStereoBM( params.ndisp, params.winSize );
bm( leftImg, rightImg, leftDisp, CV_32F ); Mat tempDisp;
bm->compute( leftImg, rightImg, tempDisp );
tempDisp.convertTo(leftDisp, CV_32F, 1./StereoMatcher::DISP_SCALE);
return params.winSize/2; return params.winSize/2;
} }
}; };
@ -751,10 +753,13 @@ protected:
{ {
RunParams params = caseRunParams[caseIdx]; RunParams params = caseRunParams[caseIdx];
assert( params.ndisp%16 == 0 ); assert( params.ndisp%16 == 0 );
StereoSGBM sgbm( 0, params.ndisp, params.winSize, 10*params.winSize*params.winSize, 40*params.winSize*params.winSize, Ptr<StereoSGBM> sgbm = createStereoSGBM( 0, params.ndisp, params.winSize,
1, 63, 10, 100, 32, params.fullDP ); 10*params.winSize*params.winSize,
sgbm( leftImg, rightImg, leftDisp ); 40*params.winSize*params.winSize,
assert( leftDisp.type() == CV_16SC1 ); 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; leftDisp/=16;
return 0; return 0;
} }

@ -37,11 +37,11 @@ PERF_TEST_P(ImagePair, Calib3D_StereoBM,
} }
else else
{ {
cv::StereoBM bm(preset, ndisp); cv::Ptr<cv::StereoBM> bm = cv::createStereoBM(ndisp);
cv::Mat dst; cv::Mat dst;
TEST_CYCLE() bm(imgLeft, imgRight, dst); TEST_CYCLE() bm->compute(imgLeft, imgRight, dst);
CPU_SANITY_CHECK(dst); CPU_SANITY_CHECK(dst);
} }

@ -67,8 +67,8 @@ int main(int argc, char** argv)
bool no_display = false; bool no_display = false;
float scale = 1.f; float scale = 1.f;
Ptr<StereoMatcher> bm = createStereoBM(16,9); Ptr<StereoBM> bm = createStereoBM(16,9);
Ptr<StereoMatcher> sgbm = createStereoSGBM(0,16,3); Ptr<StereoSGBM> sgbm = createStereoSGBM(0,16,3);
StereoVar var; StereoVar var;
for( int i = 1; i < argc; i++ ) 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; numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : ((img_size.width/8) + 15) & -16;
//bm->set("roi1", roi1); bm->setROI1(roi1);
//bm->set("roi2", roi2); bm->setROI2(roi2);
bm->set("preFilterCap", 31); bm->setPreFilterCap(31);
bm->set("SADWindowSize", SADWindowSize > 0 ? SADWindowSize : 9); bm->setBlockSize(SADWindowSize > 0 ? SADWindowSize : 9);
bm->set("minDisparity", 0); bm->setMinDisparity(0);
bm->set("numDisparities", numberOfDisparities); bm->setNumDisparities(numberOfDisparities);
bm->set("textureThreshold", 10); bm->setTextureThreshold(10);
bm->set("uniquenessRatio", 15); bm->setUniquenessRatio(15);
bm->set("speckleWindowSize", 100); bm->setSpeckleWindowSize(100);
bm->set("speckleRange", 32); bm->setSpeckleRange(32);
bm->set("disp12MaxDiff", 1); bm->setDisp12MaxDiff(1);
sgbm->set("preFilterCap", 63); sgbm->setPreFilterCap(63);
int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3; int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
sgbm->set("SADWindowSize", sgbmWinSize); sgbm->setBlockSize(sgbmWinSize);
int cn = img1.channels(); int cn = img1.channels();
sgbm->set("P1", 8*cn*sgbmWinSize*sgbmWinSize); sgbm->setP1(8*cn*sgbmWinSize*sgbmWinSize);
sgbm->set("P2", 32*cn*sgbmWinSize*sgbmWinSize); sgbm->setP2(32*cn*sgbmWinSize*sgbmWinSize);
sgbm->set("minDisparity", 0); sgbm->setMinDisparity(0);
sgbm->set("numDisparities", numberOfDisparities); sgbm->setNumDisparities(numberOfDisparities);
sgbm->set("uniquenessRatio", 10); sgbm->setUniquenessRatio(10);
sgbm->set("speckleWindowSize", 100); sgbm->setSpeckleWindowSize(100);
sgbm->set("speckleRange", 32); sgbm->setSpeckleRange(32);
sgbm->set("disp12MaxDiff", 1); sgbm->setDisp12MaxDiff(1);
sgbm->set("fullDP", alg == STEREO_HH); sgbm->setMode(alg == STEREO_HH ? StereoSGBM::MODE_HH : StereoSGBM::MODE_SGBM);
var.levels = 3; // ignored with USE_AUTO_PARAMS var.levels = 3; // ignored with USE_AUTO_PARAMS
var.pyrScale = 0.5; // ignored with USE_AUTO_PARAMS var.pyrScale = 0.5; // ignored with USE_AUTO_PARAMS

@ -39,12 +39,10 @@ int main( int argc, char** argv )
int ndisparities = 16*5; /**< Range of disparity */ int ndisparities = 16*5; /**< Range of disparity */
int SADWindowSize = 21; /**< Size of the block window. Must be odd */ int SADWindowSize = 21; /**< Size of the block window. Must be odd */
StereoBM sbm( StereoBM::BASIC_PRESET, Ptr<StereoBM> sbm = createStereoBM( ndisparities, SADWindowSize );
ndisparities,
SADWindowSize );
//-- 3. Calculate the disparity image //-- 3. Calculate the disparity image
sbm( imgLeft, imgRight, imgDisparity16S, CV_16S ); sbm->compute( imgLeft, imgRight, imgDisparity16S );
//-- Check its extreme values //-- Check its extreme values
double minVal; double maxVal; double minVal; double maxVal;

Loading…
Cancel
Save