Commit ecd36611 authored by Maksim Shabunin's avatar Maksim Shabunin

Merge pull request #4179 from sbokov:improvingStereoSGBM

parents be70df11 f40b580b
...@@ -1555,7 +1555,8 @@ public: ...@@ -1555,7 +1555,8 @@ public:
enum enum
{ {
MODE_SGBM = 0, MODE_SGBM = 0,
MODE_HH = 1 MODE_HH = 1,
MODE_SGBM_3WAY = 2
}; };
CV_WRAP virtual int getPreFilterCap() const = 0; CV_WRAP virtual int getPreFilterCap() const = 0;
......
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* *Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include "perf_precomp.hpp"
namespace cvtest
{
using std::tr1::tuple;
using std::tr1::get;
using namespace perf;
using namespace testing;
using namespace cv;
void MakeArtificialExample(RNG rng, Mat& dst_left_view, Mat& dst_view);
CV_ENUM(SGBMModes, StereoSGBM::MODE_SGBM, StereoSGBM::MODE_SGBM_3WAY);
typedef tuple<Size, int, SGBMModes> SGBMParams;
typedef TestBaseWithParam<SGBMParams> TestStereoCorresp;
PERF_TEST_P( TestStereoCorresp, SGBM, Combine(Values(Size(1280,720),Size(640,480)), Values(256,128), SGBMModes::all()) )
{
RNG rng(0);
SGBMParams params = GetParam();
Size sz = get<0>(params);
int num_disparities = get<1>(params);
int mode = get<2>(params);
Mat src_left(sz, CV_8UC3);
Mat src_right(sz, CV_8UC3);
Mat dst(sz, CV_16S);
MakeArtificialExample(rng,src_left,src_right);
cv::setNumThreads(cv::getNumberOfCPUs());
int wsize = 3;
int P1 = 8*src_left.channels()*wsize*wsize;
TEST_CYCLE()
{
Ptr<StereoSGBM> sgbm = StereoSGBM::create(0,num_disparities,wsize,P1,4*P1,1,63,25,0,0,mode);
sgbm->compute(src_left,src_right,dst);
}
SANITY_CHECK(dst, .01, ERROR_RELATIVE);
}
void MakeArtificialExample(RNG rng, Mat& dst_left_view, Mat& dst_right_view)
{
int w = dst_left_view.cols;
int h = dst_left_view.rows;
//params:
unsigned char bg_level = (unsigned char)rng.uniform(0.0,255.0);
unsigned char fg_level = (unsigned char)rng.uniform(0.0,255.0);
int rect_width = (int)rng.uniform(w/16,w/2);
int rect_height = (int)rng.uniform(h/16,h/2);
int rect_disparity = (int)(0.15*w);
double sigma = 3.0;
int rect_x_offset = (w-rect_width) /2;
int rect_y_offset = (h-rect_height)/2;
if(dst_left_view.channels()==3)
{
dst_left_view = Scalar(Vec3b(bg_level,bg_level,bg_level));
dst_right_view = Scalar(Vec3b(bg_level,bg_level,bg_level));
}
else
{
dst_left_view = Scalar(bg_level);
dst_right_view = Scalar(bg_level);
}
Mat dst_left_view_rect = Mat(dst_left_view, Rect(rect_x_offset,rect_y_offset,rect_width,rect_height));
if(dst_left_view.channels()==3)
dst_left_view_rect = Scalar(Vec3b(fg_level,fg_level,fg_level));
else
dst_left_view_rect = Scalar(fg_level);
rect_x_offset-=rect_disparity;
Mat dst_right_view_rect = Mat(dst_right_view, Rect(rect_x_offset,rect_y_offset,rect_width,rect_height));
if(dst_right_view.channels()==3)
dst_right_view_rect = Scalar(Vec3b(fg_level,fg_level,fg_level));
else
dst_right_view_rect = Scalar(fg_level);
//add some gaussian noise:
unsigned char *l, *r;
for(int i=0;i<h;i++)
{
l = dst_left_view.ptr(i);
r = dst_right_view.ptr(i);
if(dst_left_view.channels()==3)
{
for(int j=0;j<w;j++)
{
l[0] = saturate_cast<unsigned char>(l[0] + rng.gaussian(sigma));
l[1] = saturate_cast<unsigned char>(l[1] + rng.gaussian(sigma));
l[2] = saturate_cast<unsigned char>(l[2] + rng.gaussian(sigma));
l+=3;
r[0] = saturate_cast<unsigned char>(r[0] + rng.gaussian(sigma));
r[1] = saturate_cast<unsigned char>(r[1] + rng.gaussian(sigma));
r[2] = saturate_cast<unsigned char>(r[2] + rng.gaussian(sigma));
r+=3;
}
}
else
{
for(int j=0;j<w;j++)
{
l[0] = saturate_cast<unsigned char>(l[0] + rng.gaussian(sigma));
l++;
r[0] = saturate_cast<unsigned char>(r[0] + rng.gaussian(sigma));
r++;
}
}
}
}
}
This diff is collapsed.
...@@ -742,7 +742,7 @@ protected: ...@@ -742,7 +742,7 @@ protected:
{ {
int ndisp; int ndisp;
int winSize; int winSize;
bool fullDP; int mode;
}; };
vector<RunParams> caseRunParams; vector<RunParams> caseRunParams;
...@@ -757,7 +757,7 @@ protected: ...@@ -757,7 +757,7 @@ protected:
RunParams params; RunParams params;
String ndisp = fn[i+2]; params.ndisp = atoi(ndisp.c_str()); String ndisp = fn[i+2]; params.ndisp = atoi(ndisp.c_str());
String winSize = fn[i+3]; params.winSize = atoi(winSize.c_str()); String winSize = fn[i+3]; params.winSize = atoi(winSize.c_str());
String fullDP = fn[i+4]; params.fullDP = atoi(fullDP.c_str()) == 0 ? false : true; String mode = fn[i+4]; params.mode = atoi(mode.c_str());
caseNames.push_back( caseName ); caseNames.push_back( caseName );
caseDatasets.push_back( datasetName ); caseDatasets.push_back( datasetName );
caseRunParams.push_back( params ); caseRunParams.push_back( params );
...@@ -773,8 +773,7 @@ protected: ...@@ -773,8 +773,7 @@ protected:
Ptr<StereoSGBM> sgbm = StereoSGBM::create( 0, params.ndisp, params.winSize, Ptr<StereoSGBM> sgbm = StereoSGBM::create( 0, params.ndisp, params.winSize,
10*params.winSize*params.winSize, 10*params.winSize*params.winSize,
40*params.winSize*params.winSize, 40*params.winSize*params.winSize,
1, 63, 10, 100, 32, params.fullDP ? 1, 63, 10, 100, 32, params.mode );
StereoSGBM::MODE_HH : StereoSGBM::MODE_SGBM );
sgbm->compute( leftImg, rightImg, leftDisp ); sgbm->compute( leftImg, rightImg, leftDisp );
CV_Assert( leftDisp.type() == CV_16SC1 ); CV_Assert( leftDisp.type() == CV_16SC1 );
leftDisp/=16; leftDisp/=16;
......
...@@ -20,7 +20,7 @@ using namespace cv; ...@@ -20,7 +20,7 @@ using namespace cv;
static void print_help() static void print_help()
{ {
printf("\nDemo stereo matching converting L and R images into disparity and point clouds\n"); printf("\nDemo stereo matching converting L and R images into disparity and point clouds\n");
printf("\nUsage: stereo_match <left_image> <right_image> [--algorithm=bm|sgbm|hh] [--blocksize=<block_size>]\n" printf("\nUsage: stereo_match <left_image> <right_image> [--algorithm=bm|sgbm|hh|sgbm3way] [--blocksize=<block_size>]\n"
"[--max-disparity=<max_disparity>] [--scale=scale_factor>] [-i <intrinsic_filename>] [-e <extrinsic_filename>]\n" "[--max-disparity=<max_disparity>] [--scale=scale_factor>] [-i <intrinsic_filename>] [-e <extrinsic_filename>]\n"
"[--no-display] [-o <disparity_image>] [-p <point_cloud_file>]\n"); "[--no-display] [-o <disparity_image>] [-p <point_cloud_file>]\n");
} }
...@@ -61,7 +61,7 @@ int main(int argc, char** argv) ...@@ -61,7 +61,7 @@ int main(int argc, char** argv)
const char* disparity_filename = 0; const char* disparity_filename = 0;
const char* point_cloud_filename = 0; const char* point_cloud_filename = 0;
enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2, STEREO_VAR=3 }; enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2, STEREO_VAR=3, STEREO_3WAY=4 };
int alg = STEREO_SGBM; int alg = STEREO_SGBM;
int SADWindowSize = 0, numberOfDisparities = 0; int SADWindowSize = 0, numberOfDisparities = 0;
bool no_display = false; bool no_display = false;
...@@ -85,7 +85,8 @@ int main(int argc, char** argv) ...@@ -85,7 +85,8 @@ int main(int argc, char** argv)
alg = strcmp(_alg, "bm") == 0 ? STEREO_BM : alg = strcmp(_alg, "bm") == 0 ? STEREO_BM :
strcmp(_alg, "sgbm") == 0 ? STEREO_SGBM : strcmp(_alg, "sgbm") == 0 ? STEREO_SGBM :
strcmp(_alg, "hh") == 0 ? STEREO_HH : strcmp(_alg, "hh") == 0 ? STEREO_HH :
strcmp(_alg, "var") == 0 ? STEREO_VAR : -1; strcmp(_alg, "var") == 0 ? STEREO_VAR :
strcmp(_alg, "sgbm3way") == 0 ? STEREO_3WAY : -1;
if( alg < 0 ) if( alg < 0 )
{ {
printf("Command-line parameter error: Unknown stereo algorithm\n\n"); printf("Command-line parameter error: Unknown stereo algorithm\n\n");
...@@ -257,7 +258,12 @@ int main(int argc, char** argv) ...@@ -257,7 +258,12 @@ int main(int argc, char** argv)
sgbm->setSpeckleWindowSize(100); sgbm->setSpeckleWindowSize(100);
sgbm->setSpeckleRange(32); sgbm->setSpeckleRange(32);
sgbm->setDisp12MaxDiff(1); sgbm->setDisp12MaxDiff(1);
sgbm->setMode(alg == STEREO_HH ? StereoSGBM::MODE_HH : StereoSGBM::MODE_SGBM); if(alg==STEREO_HH)
sgbm->setMode(StereoSGBM::MODE_HH);
else if(alg==STEREO_SGBM)
sgbm->setMode(StereoSGBM::MODE_SGBM);
else if(alg==STEREO_3WAY)
sgbm->setMode(StereoSGBM::MODE_SGBM_3WAY);
Mat disp, disp8; Mat disp, disp8;
//Mat img1p, img2p, dispp; //Mat img1p, img2p, dispp;
...@@ -267,7 +273,7 @@ int main(int argc, char** argv) ...@@ -267,7 +273,7 @@ int main(int argc, char** argv)
int64 t = getTickCount(); int64 t = getTickCount();
if( alg == STEREO_BM ) if( alg == STEREO_BM )
bm->compute(img1, img2, disp); bm->compute(img1, img2, disp);
else if( alg == STEREO_SGBM || alg == STEREO_HH ) else if( alg == STEREO_SGBM || alg == STEREO_HH || alg == STEREO_3WAY )
sgbm->compute(img1, img2, disp); sgbm->compute(img1, img2, disp);
t = getTickCount() - t; t = getTickCount() - t;
printf("Time elapsed: %fms\n", t*1000/getTickFrequency()); printf("Time elapsed: %fms\n", t*1000/getTickFrequency());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment