Commit a102eeb1 authored by Muresan Mircea Paul's avatar Muresan Mircea Paul

added the SGBM and asserts in bm

removed warnings

clip tab warning fixed

fixed tab size warning

added a new sample

the new sample

fixed spacing problem

added a testing for the penalties

fixed sample warning

fixed last warnings

added tests and modified a bit the sources

added the tests

fixed warning

removed redundant samples

Rename Sample3.cpp to sample.cpp

renamed from Sample3 to sample

refactored sample

repaired descriptor test

added test data

usless info erased from test block matching

added last tests

did some modifications to the files

whitespace removal

did some modifications to the testing files

fixed test descriptor issue

Revert "whitespace removal"

This reverts commit 76d4aa530fee8f7444de6c80ecb4fc9c80ec0677.

corrected part of the comments

made modifications so the sources build successfully

fixed some issue for sub pixel

refactored sample

fixed small issue at testing

added some performance files

performance tests and other corrections

corrected the paths and added some images

fixed a bug

Delete imgKitty.bmp

Delete imgKittyl.bmp

performance tests again....

added larger images

fixed issues

did some last changes

added the copyright notice

fixed some linux errors
parent 707beb3f
......@@ -52,4 +52,4 @@ $ cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules -D BUILD_opencv_re
22. **opencv_xphoto**: Additional photo processing algorithms: Color balance / Denoising / Inpainting.
23. **opencv_stereo**: Stereo Correspondence done with different descriptors: Census / CS-Census / MCT / BRIEF / MV / RT.
23. **opencv_stereo**: Stereo Correspondence done with different descriptors: Census / CS-Census / MCT / BRIEF / MV.
......@@ -59,14 +59,10 @@ namespace cv
{
namespace stereo
{
//! @addtogroup stereo
//! @{
// void correctMatches( InputArray F, InputArray points1, InputArray points2,
// OutputArray newPoints1, OutputArray newPoints2 );
enum {
CV_SPECKLE_REMOVAL_ALGORITHM, CV_SPECKLE_REMOVAL_AVG_ALGORITHM
};
/** @brief Filters off small noise blobs (speckles) in the disparity map
@param img The input 16-bit signed disparity image
@param newVal The disparity value used to paint-off the speckles
......@@ -117,8 +113,14 @@ namespace cv
virtual void setDisp12MaxDiff(int disp12MaxDiff) = 0;
};
//!speckle removal algorithms. These algorithms have the purpose of removing small regions
enum {
CV_SPECKLE_REMOVAL_ALGORITHM, CV_SPECKLE_REMOVAL_AVG_ALGORITHM
};
//!subpixel interpolationm methods for disparities.
enum{
CV_QUADRATIC_INTERPOLATION, CV_SIMETRICV_INTERPOLATION
};
/** @brief Class for computing stereo correspondence using the block matching algorithm, introduced and
contributed to OpenCV by K. Konolige.
*/
......@@ -174,7 +176,7 @@ namespace cv
The function create StereoBM object. You can then call StereoBM::compute() to compute disparity for
a specific stereo pair.
*/
CV_EXPORTS static Ptr< cv::stereo::StereoBinaryBM > create(int numDisparities = 0, int blockSize = 21);
CV_EXPORTS static Ptr< cv::stereo::StereoBinaryBM > create(int numDisparities = 0, int blockSize = 9);
};
/** @brief The class implements the modified H. Hirschmuller algorithm @cite HH08 that differs from the original
......@@ -219,6 +221,15 @@ namespace cv
virtual int getMode() const = 0;
virtual void setMode(int mode) = 0;
virtual int getSpekleRemovalTechnique() const = 0 ;
virtual void setSpekleRemovalTechnique(int factor) = 0;
virtual int getBinaryKernelType() const = 0;
virtual void setBinaryKernelType(int value) = 0;
virtual int getSubPixelInterpolationMethod() const = 0;
virtual void setSubPixelInterpolationMethod(int value) = 0;
/** @brief Creates StereoSGBM object
@param minDisparity Minimum possible disparity value. Normally, it is zero but sometimes
......@@ -257,9 +268,9 @@ namespace cv
to a custom value.
*/
CV_EXPORTS static Ptr<cv::stereo::StereoBinarySGBM> create(int minDisparity, int numDisparities, int blockSize,
int P1 = 100, int P2 = 1000, int disp12MaxDiff = 0,
int preFilterCap = 0, int uniquenessRatio = 0,
int speckleWindowSize = 0, int speckleRange = 0,
int P1 = 100, int P2 = 1000, int disp12MaxDiff = 1,
int preFilterCap = 0, int uniquenessRatio = 5,
int speckleWindowSize = 400, int speckleRange = 200,
int mode = StereoBinarySGBM::MODE_SGBM);
};
//! @}
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "perf_precomp.hpp"
using namespace std;
using namespace cv;
using namespace cv::stereo;
using namespace perf;
typedef std::tr1::tuple<Size, MatType, MatDepth> s_bm_test_t;
typedef perf::TestBaseWithParam<s_bm_test_t> s_bm;
PERF_TEST_P( s_bm, sgm_perf,
testing::Combine(
testing::Values( cv::Size(512, 283), cv::Size(320, 240)),
testing::Values( CV_8UC1,CV_8U ),
testing::Values( CV_8UC1,CV_8U,CV_16S )
)
)
{
Size sz = std::tr1::get<0>(GetParam());
int matType = std::tr1::get<1>(GetParam());
int sdepth = std::tr1::get<2>(GetParam());
Mat left(sz, matType);
Mat right(sz, matType);
Mat out1(sz, sdepth);
Ptr<StereoBinarySGBM> sgbm = StereoBinarySGBM::create(0, 16, 5);
sgbm->setBinaryKernelType(CV_DENSE_CENSUS);
declare.in(left, WARMUP_RNG)
.out(out1)
.time(0.1)
.iterations(20);
TEST_CYCLE()
{
sgbm->compute(left, right, out1);
}
SANITY_CHECK(out1);
}
PERF_TEST_P( s_bm, bm_perf,
testing::Combine(
testing::Values( cv::Size(512, 383), cv::Size(320, 240) ),
testing::Values( CV_8UC1,CV_8U ),
testing::Values( CV_8UC1,CV_8U )
)
)
{
Size sz = std::tr1::get<0>(GetParam());
int matType = std::tr1::get<1>(GetParam());
int sdepth = std::tr1::get<2>(GetParam());
Mat left(sz, matType);
Mat right(sz, matType);
Mat out1(sz, sdepth);
Ptr<StereoBinaryBM> sbm = StereoBinaryBM::create(16, 9);
// we set the corresponding parameters
sbm->setPreFilterCap(31);
sbm->setMinDisparity(0);
sbm->setTextureThreshold(10);
sbm->setUniquenessRatio(0);
sbm->setSpeckleWindowSize(400);
sbm->setDisp12MaxDiff(0);
sbm->setAgregationWindowSize(11);
// the user can choose between the average speckle removal algorithm or
// the classical version that was implemented in OpenCV
sbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM);
sbm->setUsePrefilter(false);
declare.in(left, WARMUP_RNG)
.out(out1)
.time(0.1)
.iterations(20);
TEST_CYCLE()
{
sbm->compute(left, right, out1);
}
SANITY_CHECK(out1);
}
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "perf_precomp.hpp"
using namespace std;
using namespace cv;
using namespace cv::stereo;
using namespace perf;
typedef std::tr1::tuple<Size, MatType, MatDepth> descript_params_t;
typedef perf::TestBaseWithParam<descript_params_t> descript_params;
PERF_TEST_P( descript_params, census_sparse_descriptor,
testing::Combine(
testing::Values( TYPICAL_MAT_SIZES ),
testing::Values( CV_8UC1,CV_8U ),
testing::Values( CV_32SC4,CV_32S )
)
)
{
Size sz = std::tr1::get<0>(GetParam());
int matType = std::tr1::get<1>(GetParam());
int sdepth = std::tr1::get<2>(GetParam());
Mat left(sz, matType);
Mat out1(sz, sdepth);
declare.in(left, WARMUP_RNG)
.out(out1)
.time(0.01);
TEST_CYCLE()
{
censusTransform(left,9,out1,CV_SPARSE_CENSUS);
}
SANITY_CHECK(out1);
}
PERF_TEST_P( descript_params, star_census_transform,
testing::Combine(
testing::Values( TYPICAL_MAT_SIZES ),
testing::Values( CV_8UC1,CV_8U ),
testing::Values( CV_32SC4,CV_32S )
)
)
{
Size sz = std::tr1::get<0>(GetParam());
int matType = std::tr1::get<1>(GetParam());
int sdepth = std::tr1::get<2>(GetParam());
Mat left(sz, matType);
Mat out1(sz, sdepth);
declare.in(left, WARMUP_RNG)
.out(out1)
.time(0.01);
TEST_CYCLE()
{
starCensusTransform(left,9,out1);
}
SANITY_CHECK(out1);
}
PERF_TEST_P( descript_params, modified_census_transform,
testing::Combine(
testing::Values( TYPICAL_MAT_SIZES ),
testing::Values( CV_8UC1,CV_8U ),
testing::Values( CV_32SC4,CV_32S )
)
)
{
Size sz = std::tr1::get<0>(GetParam());
int matType = std::tr1::get<1>(GetParam());
int sdepth = std::tr1::get<2>(GetParam());
Mat left(sz, matType);
Mat out1(sz, sdepth);
declare.in(left, WARMUP_RNG)
.out(out1)
.time(0.01);
TEST_CYCLE()
{
modifiedCensusTransform(left,9,out1,CV_MODIFIED_CENSUS_TRANSFORM);
}
SANITY_CHECK(out1);
}
PERF_TEST_P( descript_params, center_symetric_census,
testing::Combine(
testing::Values( TYPICAL_MAT_SIZES ),
testing::Values( CV_8UC1,CV_8U ),
testing::Values( CV_32SC4,CV_32S )
)
)
{
Size sz = std::tr1::get<0>(GetParam());
int matType = std::tr1::get<1>(GetParam());
int sdepth = std::tr1::get<2>(GetParam());
Mat left(sz, matType);
Mat out1(sz, sdepth);
declare.in(left, WARMUP_RNG)
.out(out1)
.time(0.01);
TEST_CYCLE()
{
symetricCensusTransform(left,7,out1,CV_CS_CENSUS);
}
SANITY_CHECK(out1);
}
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "perf_precomp.hpp"
CV_PERF_TEST_MAIN(stereo)
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__
#include <iostream>
#include "opencv2/ts.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/stereo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include "opencv2/core/cvdef.h"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/calib3d.hpp"
#include <algorithm>
#include <cmath>
#ifdef GTEST_CREATE_SHARED_LIBRARY
#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined
#endif
#endif
#include <iostream>
#include "opencv2/stereo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace stereo;
using namespace std;
//in this example we will load a sequence of images from a file process them and display the result on the screen
//the descriptor used is the modified_census transform
int main(int, char**)
{
//begin the program
cout << " Running Main function \n";
//declare 2 images
Mat image1, image2;
// -- 1. Call the constructor for StereoBinaryBM
int ndisparities = 32; /**< Range of disparity */
int kernelSize = 9; /**< Size of the block window. Must be odd */
Ptr<StereoBinaryBM> sbm = StereoBinaryBM::create(ndisparities, kernelSize);
// -- 2. Set parameters
sbm->setPreFilterCap(31);
sbm->setMinDisparity(0);
sbm->setTextureThreshold(10);
sbm->setUniquenessRatio(0);
sbm->setSpeckleWindowSize(400);//speckle size
sbm->setSpeckleRange(200);
sbm->setDisp12MaxDiff(0);
sbm->setScalleFactor(4);//the scalling factor
sbm->setBinaryKernelType(CV_MODIFIED_CENSUS_TRANSFORM);//binary descriptor kernel
sbm->setAgregationWindowSize(9);
sbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM);//speckle removal algorithm
sbm->setUsePrefilter(false);//prefilter or not the images prior to making the transformations
for(int i = 0 ; i < 200; i++)
{
string path = "D:\\WorkingSec";
string left = "l.bmp";
string right = ".bmp";
std::string s;
std::stringstream out;
out << i;
s = out.str();
string finLeft = path + "\\rezult" + s + left;
string finRigth = path + "\\rezult" + s + right;
image1 = imread(finLeft, CV_8UC1);
image2 = imread(finRigth, CV_8UC1);
//set a certain region of interest
Rect region_of_interest = Rect(0, 20, image1.cols, (image1.rows - 20 - 110));
Mat imgLeft = image1(region_of_interest);
Mat imgRight = image2(region_of_interest);
Mat imgDisparity8U = Mat(imgLeft.rows, imgLeft.cols, CV_8UC1);
if (imgLeft.empty() || imgRight.empty())
{
std::cout << " --(!) Error reading images \n" ; return -1;
}
////-- 3. Calculate the disparity image
sbm->compute(imgLeft, imgRight, imgDisparity8U);
imshow("RealImage", image1);
imshow("Disparity", imgDisparity8U);
waitKey(1);
}
waitKey(0);
return 0;
}
#include <iostream>
#include "opencv2/stereo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace stereo;
using namespace std;
int main(int, char**)
{
//begin the program
cout << " Running Main function \n";
//declare 2 images
Mat image1, image2;
// -- 1. Call the constructor for StereoBinaryBM
int ndisparities = 32; /**< Range of disparity */
int kernelSize = 9; /**< Size of the block window. Must be odd */
Ptr<StereoBinaryBM> sbm = StereoBinaryBM::create(ndisparities, kernelSize);
// -- 2. Set parameters
sbm->setPreFilterCap(31);
sbm->setMinDisparity(0);
sbm->setTextureThreshold(10);
sbm->setUniquenessRatio(0);
sbm->setSpeckleWindowSize(400);//speckle size
sbm->setSpeckleRange(200);
sbm->setDisp12MaxDiff(0);
sbm->setScalleFactor(4);//the scalling factor
sbm->setBinaryKernelType(CV_MEAN_VARIATION);//binary descriptor kernel
sbm->setAgregationWindowSize(9);
sbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM);//speckle removal algorithm
sbm->setUsePrefilter(false);//prefilter or not the images prior to making the transformations
//load 2 images from disc
image1 = imread("D:\\rezult0l.bmp", CV_8UC1);
image2 = imread("D:\\rezult0.bmp", CV_8UC1);
//set a certain region of interest
Rect region_of_interest = Rect(0, 20, image1.cols, (image1.rows - 20 - 110));
Mat imgLeft = image1(region_of_interest);
Mat imgRight = image2(region_of_interest);
Mat imgDisparity8U = Mat(imgLeft.rows, imgLeft.cols, CV_8UC1);
if (imgLeft.empty() || imgRight.empty())
{
std::cout << " --(!) Error reading images \n" ; return -1;
}
////-- 3. Calculate the disparity image
sbm->compute(imgLeft, imgRight, imgDisparity8U);
imshow("RealImage", image1);
imshow("Disparity", imgDisparity8U);
waitKey(0);
return 0;
}
#include "opencv2/stereo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::stereo;
enum { STEREO_BINARY_BM, STEREO_BINARY_SGM };
static cv::CommandLineParser parse_argument_values(int argc, char **argv, string &left, string &right, int &kernel_size, int &number_of_disparities,
int &aggregation_window, int &P1, int &P2, float &scale, int &algo, int &binary_descriptor_type);
int main(int argc, char** argv)
{
string left, right;
int kernel_size = 0, number_of_disparities = 0, aggregation_window = 0, P1 = 0, P2 = 0;
float scale = 4;
int algo = STEREO_BINARY_BM;
int binary_descriptor_type = 0;
// here we extract the values that were added as arguments
// we also test to see if they are provided correcly
cv::CommandLineParser parser =
parse_argument_values(argc, argv, left, right,
kernel_size,
number_of_disparities,
aggregation_window,
P1, P2,
scale,
algo, binary_descriptor_type);
if (!parser.check())
{
parser.printMessage();
return 1;
}
int fail = 0;
//TEST if the provided parameters are correct
if(binary_descriptor_type == CV_DENSE_CENSUS && kernel_size > 5)
{
cout << "For the dense census transform the maximum kernel size should be 5\n";
fail = 1;
}
if((binary_descriptor_type == CV_MEAN_VARIATION || binary_descriptor_type == CV_MODIFIED_CENSUS_TRANSFORM || binary_descriptor_type == CV_STAR_KERNEL) && kernel_size != 9)
{
cout <<" For Mean variation and the modified census transform the kernel size should be equal to 9\n";
fail = 1;
}
if((binary_descriptor_type == CV_CS_CENSUS || binary_descriptor_type == CV_MODIFIED_CS_CENSUS) && kernel_size > 7)
{
cout << " The kernel size should be smaller or equal to 7 for the CS census and modified center symetric census\n";
fail = 1;
}
if(binary_descriptor_type == CV_SPARSE_CENSUS && kernel_size > 11)
{
cout << "The kernel size for the sparse census must be smaller or equal to 11\n";
fail = 1;
}
if(number_of_disparities < 10)
{
cout << "Number of disparities should be greater than 10\n";
fail = 1;
}
if(P2 / P1 < 2)
{
cout << "You should probabilly choose a greater P2 penalty\n";
fail = 1;
}
if(fail == 1)
{
return 1;
}
// verify if the user inputs the correct number of parameters
Mat image1, image2;
// we read a pair of images from the disk
image1 = imread(left, CV_8UC1);
image2 = imread(right, CV_8UC1);
// verify if they are loaded correctly
if (image1.empty() || image2.empty())
{
cout << " --(!) Error reading images \n";
parser.printMessage();
return 1;
}
// we display the parsed parameters
const char *b[7] = { "CV_DENSE_CENSUS", "CV_SPARSE_CENSUS", "CV_CS_CENSUS", "CV_MODIFIED_CS_CENSUS",
"CV_MODIFIED_CENSUS_TRANSFORM", "CV_MEAN_VARIATION", "CV_STAR_KERNEL" };
cout << "Program Name: " << argv[0];
cout << "\nPath to left image " << left << " \n" << "Path to right image " << right << "\n";
cout << "\nkernel size " << kernel_size << "\n"
<< "numberOfDisparities " << number_of_disparities << "\n"
<< "aggregationWindow " << aggregation_window << "\n"
<< "scallingFactor " << scale << "\n" << "Descriptor name : " << b[binary_descriptor_type] << "\n";
Mat imgDisparity16S2 = Mat(image1.rows, image1.cols, CV_16S);
Mat imgDisparity8U2 = Mat(image1.rows, image1.cols, CV_8UC1);
imshow("Original Left image", image1);
if (algo == STEREO_BINARY_BM)
{
Ptr<StereoBinaryBM> sbm = StereoBinaryBM::create(number_of_disparities, kernel_size);
// we set the corresponding parameters
sbm->setPreFilterCap(31);
sbm->setMinDisparity(0);
sbm->setTextureThreshold(10);
sbm->setUniquenessRatio(0);
sbm->setSpeckleWindowSize(400); // speckle size
sbm->setSpeckleRange(200);
sbm->setDisp12MaxDiff(0);
sbm->setScalleFactor((int)scale); // the scaling factor
sbm->setBinaryKernelType(binary_descriptor_type); // binary descriptor kernel
sbm->setAgregationWindowSize(aggregation_window);
// the user can choose between the average speckle removal algorithm or
// the classical version that was implemented in OpenCV
sbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM);
sbm->setUsePrefilter(false);
//-- calculate the disparity image
sbm->compute(image1, image2, imgDisparity8U2);
imshow("Disparity", imgDisparity8U2);
}
else if (algo == STEREO_BINARY_SGM)
{
// we set the corresponding parameters
Ptr<StereoBinarySGBM> sgbm = StereoBinarySGBM::create(0, number_of_disparities, kernel_size);
// setting the penalties for sgbm
sgbm->setP1(P1);
sgbm->setP2(P2);
sgbm->setMinDisparity(0);
sgbm->setUniquenessRatio(5);
sgbm->setSpeckleWindowSize(400);
sgbm->setSpeckleRange(0);
sgbm->setDisp12MaxDiff(1);
sgbm->setBinaryKernelType(binary_descriptor_type);
sgbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM);
sgbm->setSubPixelInterpolationMethod(CV_SIMETRICV_INTERPOLATION);
sgbm->compute(image1, image2, imgDisparity16S2);
/*Alternative for scalling
imgDisparity16S2.convertTo(imgDisparity8U2, CV_8UC1, scale);
*/
double minVal; double maxVal;
minMaxLoc(imgDisparity16S2, &minVal, &maxVal);
imgDisparity16S2.convertTo(imgDisparity8U2, CV_8UC1, 255 / (maxVal - minVal));
//show the disparity image
imshow("Windowsgm", imgDisparity8U2);
}
waitKey(0);
return 0;
}
static cv::CommandLineParser parse_argument_values(int argc, char **argv, string &left, string &right, int &kernel_size, int &number_of_disparities,
int &aggregation_window, int &P1, int &P2, float &scale, int &algo, int &binary_descriptor_type)
{
static const char* keys =
"{ @left | | }"
"{ @right | | }"
"{ k kernel_size | 9 | }"
"{ d disparity | 128 | }"
"{ w aggregation_window | 9 | }"
"{ P1 | 100 | }"
"{ P2 | 1000 | }"
"{ b binary_descriptor | 4 | Index of the descriptor type:\n 0 - CV_DENSE_CENSUS,\n 1 - CV_SPARSE_CENSUS,\n 2 - CV_CS_CENSUS,\n 3 - CV_MODIFIED_CS_CENSUS,\n 4 - CV_MODIFIED_CENSUS_TRANSFORM,\n 5 - CV_MEAN_VARIATION,\n 6 - CV_STAR_KERNEL}"
"{ s scale | 1.01593 | }"
"{ a algorithm | sgm | }"
;
cv::CommandLineParser parser( argc, argv, keys );
left = parser.get<string>(0);
right = parser.get<string>(1);
kernel_size = parser.get<int>("kernel_size");
number_of_disparities = parser.get<int>("disparity");
aggregation_window = parser.get<int>("aggregation_window");
P1 = parser.get<int>("P1");
P2 = parser.get<int>("P2");
binary_descriptor_type = parser.get<int>("binary_descriptor");
scale = parser.get<float>("scale");
algo = parser.get<string>("algorithm") == "sgm" ? STEREO_BINARY_SGM : STEREO_BINARY_BM;
parser.about("\nDemo stereo matching converting L and R images into disparity images using BM and SGBM\n");
return parser;
}
......@@ -52,7 +52,7 @@ namespace cv
{
//function that performs the census transform on two images.
//Two variants of census are offered a sparse version whcih takes every second pixel as well as dense version
void censusTransform(const Mat &image1, const Mat &image2, int kernelSize, Mat &dist1, Mat &dist2, const int type)
CV_EXPORTS void censusTransform(const Mat &image1, const Mat &image2, int kernelSize, Mat &dist1, Mat &dist2, const int type)
{
CV_Assert(image1.size() == image2.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -75,7 +75,7 @@ namespace cv
}
}
//function that performs census on one image
void censusTransform(const Mat &image1, int kernelSize, Mat &dist1, const int type)
CV_EXPORTS void censusTransform(const Mat &image1, int kernelSize, Mat &dist1, const int type)
{
CV_Assert(image1.size() == dist1.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -98,7 +98,7 @@ namespace cv
}
}
//in a 9x9 kernel only certain positions are choosen for comparison
void starCensusTransform(const Mat &img1, const Mat &img2, int kernelSize, Mat &dist1, Mat &dist2)
CV_EXPORTS void starCensusTransform(const Mat &img1, const Mat &img2, int kernelSize, Mat &dist1, Mat &dist2)
{
CV_Assert(img1.size() == img2.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -110,7 +110,7 @@ namespace cv
parallel_for_(Range(n2, img1.rows - n2), StarKernelCensus<2>(images, n2,date));
}
//single version of star census
void starCensusTransform(const Mat &img1, int kernelSize, Mat &dist)
CV_EXPORTS void starCensusTransform(const Mat &img1, int kernelSize, Mat &dist)
{
CV_Assert(img1.size() == dist.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -126,7 +126,7 @@ namespace cv
//the sencond modified census transform is invariant to noise; i.e.
//if the current pixel with whom we are dooing the comparison is a noise, this descriptor will provide a better result by comparing with the mean of the window
//otherwise if the pixel is not noise the information is strengthend
void modifiedCensusTransform(const Mat &img1, const Mat &img2, int kernelSize, Mat &dist1,Mat &dist2, const int type, int t, const Mat &IntegralImage1, const Mat &IntegralImage2 )
CV_EXPORTS void modifiedCensusTransform(const Mat &img1, const Mat &img2, int kernelSize, Mat &dist1,Mat &dist2, const int type, int t, const Mat &IntegralImage1, const Mat &IntegralImage2 )
{
CV_Assert(img1.size() == img2.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -153,7 +153,7 @@ namespace cv
CombinedDescriptor<2,3,2,2, MVKernel<2> >(img1.cols, img1.rows,stride,n2,date,MVKernel<2>(images,integral),n2));
}
}
void modifiedCensusTransform(const Mat &img1, int kernelSize, Mat &dist, const int type, int t , Mat const &IntegralImage)
CV_EXPORTS void modifiedCensusTransform(const Mat &img1, int kernelSize, Mat &dist, const int type, int t , Mat const &IntegralImage)
{
CV_Assert(img1.size() == dist.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -168,7 +168,7 @@ namespace cv
{
//MCT
parallel_for_(Range(n2, img1.rows - n2),
CombinedDescriptor<2,3,2, 1,MCTKernel<1> >(img1.cols, img1.rows,stride,n2,date,MCTKernel<1>(images,t),n2));
CombinedDescriptor<2,4,2, 1,MCTKernel<1> >(img1.cols, img1.rows,stride,n2,date,MCTKernel<1>(images,t),n2));
}
else if(type == CV_MEAN_VARIATION)
{
......@@ -180,7 +180,7 @@ namespace cv
}
//different versions of simetric census
//These variants since they do not compare with the center they are invariant to noise
void symetricCensusTransform(const Mat &img1, const Mat &img2, int kernelSize, Mat &dist1, Mat &dist2, const int type)
CV_EXPORTS void symetricCensusTransform(const Mat &img1, const Mat &img2, int kernelSize, Mat &dist1, Mat &dist2, const int type)
{
CV_Assert(img1.size() == img2.size());
CV_Assert(kernelSize % 2 != 0);
......@@ -202,7 +202,7 @@ namespace cv
CombinedDescriptor<1,1,1,2,ModifiedCsCensus<2> >(img1.cols, img1.rows,stride,n2,date,ModifiedCsCensus<2>(images,n2),1));
}
}
void symetricCensusTransform(const Mat &img1, int kernelSize, Mat &dist1, const int type)
CV_EXPORTS void symetricCensusTransform(const Mat &img1, int kernelSize, Mat &dist1, const int type)
{
CV_Assert(img1.size() == dist1.size());
CV_Assert(kernelSize % 2 != 0);
......
......@@ -424,26 +424,26 @@ namespace cv
Implementation of a census transform which is taking into account just the some pixels from the census kernel thus allowing for larger block sizes
**/
//void applyCensusOnImages(const cv::Mat &im1,const cv::Mat &im2, int kernelSize, cv::Mat &dist, cv::Mat &dist2, const int type);
void censusTransform(const cv::Mat &image1, const cv::Mat &image2, int kernelSize, cv::Mat &dist1, cv::Mat &dist2, const int type);
CV_EXPORTS void censusTransform(const cv::Mat &image1, const cv::Mat &image2, int kernelSize, cv::Mat &dist1, cv::Mat &dist2, const int type);
//single image census transform
void censusTransform(const cv::Mat &image1, int kernelSize, cv::Mat &dist1, const int type);
CV_EXPORTS void censusTransform(const cv::Mat &image1, int kernelSize, cv::Mat &dist1, const int type);
/**
STANDARD_MCT - Modified census which is memorizing for each pixel 2 bits and includes a tolerance to the pixel comparison
MCT_MEAN_VARIATION - Implementation of a modified census transform which is also taking into account the variation to the mean of the window not just the center pixel
**/
void modifiedCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1,cv::Mat &dist2, const int type, int t = 0 , const cv::Mat &IntegralImage1 = cv::Mat::zeros(100,100,CV_8UC1), const cv::Mat &IntegralImage2 = cv::Mat::zeros(100,100,CV_8UC1));
CV_EXPORTS void modifiedCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1,cv::Mat &dist2, const int type, int t = 0 , const cv::Mat &IntegralImage1 = cv::Mat::zeros(100,100,CV_8UC1), const cv::Mat &IntegralImage2 = cv::Mat::zeros(100,100,CV_8UC1));
//single version of modified census transform descriptor
void modifiedCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist, const int type, int t = 0 ,const cv::Mat &IntegralImage = cv::Mat::zeros(100,100,CV_8UC1));
CV_EXPORTS void modifiedCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist, const int type, int t = 0 ,const cv::Mat &IntegralImage = cv::Mat::zeros(100,100,CV_8UC1));
/**The classical center symetric census
A modified version of cs census which is comparing a pixel with its correspondent after the center
**/
void symetricCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1, cv::Mat &dist2, const int type);
CV_EXPORTS void symetricCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1, cv::Mat &dist2, const int type);
//single version of census transform
void symetricCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist1, const int type);
CV_EXPORTS void symetricCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist1, const int type);
//in a 9x9 kernel only certain positions are choosen
void starCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1,cv::Mat &dist2);
CV_EXPORTS void starCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1,cv::Mat &dist2);
//single image version of star kernel
void starCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist);
CV_EXPORTS void starCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist);
//integral image computation used in the Mean Variation Census Transform
void imageMeanKernelSize(const cv::Mat &img, int windowSize, cv::Mat &c);
}
......
......@@ -67,7 +67,7 @@ namespace cv
//!the LUT used in case SSE is not available
int hamLut[65537];
//!function used for getting the minimum disparity from the cost volume"
static int minim(int *c, int iwpj, int widthDisp,const double confidence, const int search_region)
static int minim(short *c, int iwpj, int widthDisp,const double confidence, const int search_region)
{
double mini, mini2, mini3;
mini = mini2 = mini3 = DBL_MAX;
......@@ -101,7 +101,7 @@ namespace cv
}
//!Interpolate in order to obtain better results
//!function for refining the disparity at sub pixel using simetric v
static double symetricVInterpolation(int *c, int iwjp, int widthDisp, int winDisp,const int search_region)
static double symetricVInterpolation(short *c, int iwjp, int widthDisp, int winDisp,const int search_region)
{
if (winDisp == 0 || winDisp == widthDisp - 1)
return winDisp;
......@@ -146,12 +146,13 @@ namespace cv
class hammingDistance : public ParallelLoopBody
{
private:
int *left, *right, *c;
int *left, *right;
short *c;
int v,kernelSize, width, height;
int MASK;
int *hammLut;
public :
hammingDistance(const Mat &leftImage, const Mat &rightImage, int *cost, int maxDisp, int kerSize, int *hammingLUT):
hammingDistance(const Mat &leftImage, const Mat &rightImage, short *cost, int maxDisp, int kerSize, int *hammingLUT):
left((int *)leftImage.data), right((int *)rightImage.data), c(cost), v(maxDisp),kernelSize(kerSize),width(leftImage.cols), height(leftImage.rows), MASK(65535), hammLut(hammingLUT){}
void operator()(const cv::Range &r) const {
for (int i = r.start; i <= r.end ; i++)
......@@ -168,63 +169,31 @@ namespace cv
j2 = (0 > j - d) ? (0) : (j - d);
xorul = left[(iwj)] ^ right[(iw + j2)];
#if CV_SSE4_1
c[(iwj)* (v + 1) + d] = _mm_popcnt_u32(xorul);
c[(iwj)* (v + 1) + d] = (short)_mm_popcnt_u32(xorul);
#else
c[(iwj)* (v + 1) + d] = hammLut[xorul & MASK] + hammLut[xorul >> 16];
c[(iwj)* (v + 1) + d] = (short)(hammLut[xorul & MASK] + hammLut[xorul >> 16]);
#endif
}
}
}
}
};
//!preprocessing used for agregation
class costGatheringHorizontal:public ParallelLoopBody
{
private:
int *c, *ham;
int width, maxDisp;
public:
costGatheringHorizontal(const Mat &hamimg,const int maxDispa, Mat &output)
{
ham = (int *)hamimg.data;
c = (int *)output.data;
maxDisp = maxDispa;
width = output.cols / ( maxDisp + 1) - 1;
}
void operator()(const cv::Range &r) const {
for (int i = r.start; i <= r.end; i++)
{
int iw = i * width;
int iwi = (i - 1) * width;
for (int j = 1; j <= width; j++)
{
int iwj = (iw + j) * (maxDisp + 1);
int iwjmu = (iw + j - 1) * (maxDisp + 1);
int iwijmu = (iwi + j - 1) * (maxDisp + 1);
for (int d = 0; d <= maxDisp; d++)
{
c[iwj + d] = ham[iwijmu + d] + c[iwjmu + d];
}
}
}
}
};
//!cost aggregation
class agregateCost:public ParallelLoopBody
{
private:
int win;
int *c, *parSum;
short *c, *parSum;
int maxDisp,width, height;
public:
agregateCost(const Mat &partialSums, int windowSize, int maxDispa, Mat &cost)
{
win = windowSize / 2;
c = (int *)cost.data;
c = (short *)cost.data;
maxDisp = maxDispa;
width = cost.cols / ( maxDisp + 1) - 1;
height = cost.rows - 1;
parSum = (int *)partialSums.data;
parSum = (short *)partialSums.data;
}
void operator()(const cv::Range &r) const {
for (int i = r.start; i <= r.end; i++)
......@@ -255,11 +224,11 @@ namespace cv
int width,disparity,scallingFact,th;
double confCheck;
uint8_t *map;
int *c;
short *c;
public:
makeMap(const Mat &costVolume, int threshold, int maxDisp, double confidence,int scale, Mat &mapFinal)
{
c = (int *)costVolume.data;
c = (short *)costVolume.data;
map = mapFinal.data;
disparity = maxDisp;
width = costVolume.cols / ( disparity + 1) - 1;
......@@ -393,6 +362,7 @@ namespace cv
int *specklePointX;
int *specklePointY;
long long *pus;
int previous_size;
//!method for setting the maximum disparity
void setMaxDisparity(int val)
{
......@@ -436,22 +406,37 @@ namespace cv
CV_Assert(kernelSize % 2 != 0);
CV_Assert(cost.rows == leftImage.rows);
CV_Assert(cost.cols / (maxDisparity + 1) == leftImage.cols);
int *c = (int *)cost.data;
short *c = (short *)cost.data;
memset(c, 0, sizeof(c[0]) * leftImage.cols * leftImage.rows * (maxDisparity + 1));
parallel_for_(cv::Range(kernelSize / 2,leftImage.rows - kernelSize / 2), hammingDistance(leftImage,rightImage,(int *)cost.data,maxDisparity,kernelSize / 2,hamLut));
parallel_for_(cv::Range(kernelSize / 2,leftImage.rows - kernelSize / 2), hammingDistance(leftImage,rightImage,(short *)cost.data,maxDisparity,kernelSize / 2,hamLut));
}
//preprocessing the cost volume in order to get it ready for aggregation
void costGathering(const Mat &hammingDistanceCost, Mat &cost)
{
CV_Assert(hammingDistanceCost.rows == hammingDistanceCost.rows);
CV_Assert(hammingDistanceCost.type() == CV_32SC4);
CV_Assert(cost.type() == CV_32SC4);
CV_Assert(hammingDistanceCost.type() == CV_16S);
CV_Assert(cost.type() == CV_16S);
int maxDisp = maxDisparity;
int width = cost.cols / ( maxDisp + 1) - 1;
int height = cost.rows - 1;
int *c = (int *)cost.data;
short *c = (short *)cost.data;
short *ham = (short *)hammingDistanceCost.data;
memset(c, 0, sizeof(c[0]) * (width + 1) * (height + 1) * (maxDisp + 1));
parallel_for_(cv::Range(1,height), costGatheringHorizontal(hammingDistanceCost,maxDisparity,cost));
for (int i = 1; i <= height; i++)
{
int iw = i * width;
int iwi = (i - 1) * width;
for (int j = 1; j <= width; j++)
{
int iwj = (iw + j) * (maxDisp + 1);
int iwjmu = (iw + j - 1) * (maxDisp + 1);
int iwijmu = (iwi + j - 1) * (maxDisp + 1);
for (int d = 0; d <= maxDisp; d++)
{
c[iwj + d] = ham[iwijmu + d] + c[iwjmu + d];
}
}
}
for (int i = 1; i <= height; i++)
{
for (int j = 1; j <= width; j++)
......@@ -472,7 +457,7 @@ namespace cv
CV_Assert(partialSums.rows == cost.rows);
CV_Assert(partialSums.cols == cost.cols);
int win = windowSize / 2;
int *c = (int *)cost.data;
short *c = (short *)cost.data;
int maxDisp = maxDisparity;
int width = cost.cols / ( maxDisp + 1) - 1;
int height = cost.rows - 1;
......@@ -484,8 +469,8 @@ namespace cv
{
CV_Assert(currentMap.cols == out.cols);
CV_Assert(currentMap.rows == out.rows);
CV_Assert(t > 0);
memset(pus, 0, sizeof(pus));
CV_Assert(t >= 0);
memset(pus, 0, previous_size * sizeof(pus[0]));
uint8_t *map = currentMap.data;
uint8_t *outputMap = out.data;
int height = currentMap.rows;
......
......@@ -269,7 +269,7 @@ namespace cv
class StereoBinaryBMImpl : public StereoBinaryBM, public Matching
{
public:
StereoBinaryBMImpl()
StereoBinaryBMImpl(): Matching(64)
{
params = StereoBinaryBMParams();
}
......@@ -322,20 +322,6 @@ namespace cv
Mat left0 = leftarr.getMat(), right0 = rightarr.getMat();
Mat disp0 = disparr.getMat();
censusImage[0].create(left0.rows,left0.cols,CV_32SC4);
censusImage[1].create(left0.rows,left0.cols,CV_32SC4);
partialSumsLR.create(left0.rows + 1,(left0.cols + 1) * (params.numDisparities + 1),CV_32SC4);
agregatedHammingLRCost.create(left0.rows + 1,(left0.cols + 1) * (params.numDisparities + 1),CV_32SC4);
hammingDistance.create(left0.rows, left0.cols * (params.numDisparities + 1),CV_32SC4);
preFilteredImg0.create(left0.size(), CV_8U);
preFilteredImg1.create(left0.size(), CV_8U);
Mat left = preFilteredImg0, right = preFilteredImg1;
int ndisp = params.numDisparities;
int width = left0.cols;
int height = left0.rows;
......@@ -345,8 +331,22 @@ namespace cv
specklePointX = new int[width * height];
specklePointY = new int[width * height];
pus = new long long[width * height];
censusImage[0].create(left0.rows,left0.cols,CV_32SC4);
censusImage[1].create(left0.rows,left0.cols,CV_32SC4);
partialSumsLR.create(left0.rows + 1,(left0.cols + 1) * (params.numDisparities + 1),CV_16S);
agregatedHammingLRCost.create(left0.rows + 1,(left0.cols + 1) * (params.numDisparities + 1),CV_16S);
hammingDistance.create(left0.rows, left0.cols * (params.numDisparities + 1),CV_16S);
preFilteredImg0.create(left0.size(), CV_8U);
preFilteredImg1.create(left0.size(), CV_8U);
}
Mat left = preFilteredImg0, right = preFilteredImg1;
int ndisp = params.numDisparities;
int wsz = params.kernelSize;
int bufSize0 = (int)((ndisp + 2)*sizeof(int));
bufSize0 += (int)((height + wsz + 2)*ndisp*sizeof(int));
......@@ -419,52 +419,52 @@ namespace cv
}
}
int getAgregationWindowSize() const { return params.agregationWindowSize;}
void setAgregationWindowSize(int value = 9) { params.agregationWindowSize = value;}
void setAgregationWindowSize(int value = 9) { CV_Assert(value % 2 != 0); params.agregationWindowSize = value;}
int getBinaryKernelType() const { return params.kernelType;}
void setBinaryKernelType(int value = CV_MODIFIED_CENSUS_TRANSFORM) { params.kernelType = value; }
void setBinaryKernelType(int value = CV_MODIFIED_CENSUS_TRANSFORM) { CV_Assert(value < 7); params.kernelType = value; }
int getSpekleRemovalTechnique() const { return params.regionRemoval;}
void setSpekleRemovalTechnique(int factor = CV_SPECKLE_REMOVAL_AVG_ALGORITHM) { params.regionRemoval = factor; }
void setSpekleRemovalTechnique(int factor = CV_SPECKLE_REMOVAL_AVG_ALGORITHM) {CV_Assert(factor < 2); params.regionRemoval = factor; }
bool getUsePrefilter() const { return params.usePrefilter;}
void setUsePrefilter(bool value = false) { params.usePrefilter = value;}
int getScalleFactor() const { return params.scalling;}
void setScalleFactor(int factor) {params.scalling = factor; setScallingFactor(factor);}
void setScalleFactor(int factor = 4) {CV_Assert(factor > 0); params.scalling = factor; setScallingFactor(factor);}
int getMinDisparity() const { return params.minDisparity; }
void setMinDisparity(int minDisparity) { params.minDisparity = minDisparity; }
void setMinDisparity(int minDisparity) {CV_Assert(minDisparity >= 0); params.minDisparity = minDisparity; }
int getNumDisparities() const { return params.numDisparities; }
void setNumDisparities(int numDisparities) { params.numDisparities = numDisparities; }
void setNumDisparities(int numDisparities) {CV_Assert(numDisparities > 0); params.numDisparities = numDisparities; }
int getBlockSize() const { return params.kernelSize; }
void setBlockSize(int blockSize) { params.kernelSize = blockSize; }
void setBlockSize(int blockSize) {CV_Assert(blockSize % 2 != 0); params.kernelSize = blockSize; }
int getSpeckleWindowSize() const { return params.speckleWindowSize; }
void setSpeckleWindowSize(int speckleWindowSize) { params.speckleWindowSize = speckleWindowSize; }
void setSpeckleWindowSize(int speckleWindowSize) {CV_Assert(speckleWindowSize >= 0); params.speckleWindowSize = speckleWindowSize; }
int getSpeckleRange() const { return params.speckleRange; }
void setSpeckleRange(int speckleRange) { params.speckleRange = speckleRange; }
void setSpeckleRange(int speckleRange) {CV_Assert(speckleRange >= 0); params.speckleRange = speckleRange; }
int getDisp12MaxDiff() const { return params.disp12MaxDiff; }
void setDisp12MaxDiff(int disp12MaxDiff) { params.disp12MaxDiff = disp12MaxDiff; }
void setDisp12MaxDiff(int disp12MaxDiff) {CV_Assert(disp12MaxDiff >= 0); params.disp12MaxDiff = disp12MaxDiff; }
int getPreFilterType() const { return params.preFilterType; }
void setPreFilterType(int preFilterType) { params.preFilterType = preFilterType; }
void setPreFilterType(int preFilterType) { CV_Assert(preFilterType >= 0); params.preFilterType = preFilterType; }
int getPreFilterSize() const { return params.preFilterSize; }
void setPreFilterSize(int preFilterSize) { params.preFilterSize = preFilterSize; }
void setPreFilterSize(int preFilterSize) { CV_Assert(preFilterSize >= 0); params.preFilterSize = preFilterSize; }
int getPreFilterCap() const { return params.preFilterCap; }
void setPreFilterCap(int preFilterCap) { params.preFilterCap = preFilterCap; }
void setPreFilterCap(int preFilterCap) {CV_Assert(preFilterCap >= 0); params.preFilterCap = preFilterCap; }
int getTextureThreshold() const { return params.textureThreshold; }
void setTextureThreshold(int textureThreshold) { params.textureThreshold = textureThreshold; }
void setTextureThreshold(int textureThreshold) {CV_Assert(textureThreshold >= 0); params.textureThreshold = textureThreshold; }
int getUniquenessRatio() const { return params.uniquenessRatio; }
void setUniquenessRatio(int uniquenessRatio) { params.uniquenessRatio = uniquenessRatio; }
void setUniquenessRatio(int uniquenessRatio) {CV_Assert(uniquenessRatio >= 0); params.uniquenessRatio = uniquenessRatio; }
int getSmallerBlockSize() const { return 0; }
void setSmallerBlockSize(int) {}
......@@ -506,12 +506,11 @@ namespace cv
Mat preFilteredImg0, preFilteredImg1, cost, dispbuf;
Mat slidingSumBuf;
Mat parSumsIntensityImage[2];
Mat Integral[2];
Mat censusImage[2];
Mat hammingDistance;
Mat partialSumsLR;
Mat agregatedHammingLRCost;
Mat Integral[2];
int previous_size;
static const char* name_;
};
......
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of Intel Corporation may not 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 the Intel Corporation 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.
//
//M*/
#include "test_precomp.hpp"
#include <limits.h>
using namespace cv;
using namespace cv::stereo;
using namespace std;
class CV_BlockMatchingTest : public cvtest::BaseTest
{
public:
CV_BlockMatchingTest();
~CV_BlockMatchingTest();
protected:
void run(int /* idx */);
};
CV_BlockMatchingTest::CV_BlockMatchingTest(){}
CV_BlockMatchingTest::~CV_BlockMatchingTest(){}
static double errorLevel(const Mat &ideal, Mat &actual)
{
uint8_t *date, *harta;
harta = actual.data;
date = ideal.data;
int stride, h;
stride = (int)ideal.step;
h = ideal.rows;
int error = 0;
for (int i = 0; i < ideal.rows; i++)
{
for (int j = 0; j < ideal.cols; j++)
{
if (date[i * stride + j] != 0)
if (abs(date[i * stride + j] - harta[i * stride + j]) > 2 * 16)
{
error += 1;
}
}
}
return ((double)((error * 100) * 1.0) / (stride * h));
}
void CV_BlockMatchingTest::run(int )
{
Mat image1, image2, gt;
//some test images can be found in the test data folder
image1 = imread(ts->get_data_path() + "testdata/imL2l.bmp", CV_8UC1);
image2 = imread(ts->get_data_path() + "testdata/imL2.bmp", CV_8UC1);
gt = imread(ts->get_data_path() + "testdata/groundtruth.bmp", CV_8UC1);
if(image1.empty() || image2.empty() || gt.empty())
{
ts->printf(cvtest::TS::LOG, "Wrong input data \n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
return;
}
if(image1.rows != image2.rows || image1.cols != image2.cols || gt.cols != gt.cols || gt.rows != gt.rows)
{
ts->printf(cvtest::TS::LOG, "Wrong input / output dimension \n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
return;
}
RNG range;
//set the parameters
int binary_descriptor_type = range.uniform(0,8);
int kernel_size, aggregation_window;
if(binary_descriptor_type == 0)
kernel_size = 5;
else if(binary_descriptor_type == 2 || binary_descriptor_type == 3)
kernel_size = 7;
else if(binary_descriptor_type == 1)
kernel_size = 11;
else
kernel_size = 9;
if(binary_descriptor_type == 3)
aggregation_window = 13;
else
aggregation_window = 11;
Mat test = Mat(image1.rows, image1.cols, CV_8UC1);
Ptr<StereoBinaryBM> sbm = StereoBinaryBM::create(16, kernel_size);
//we set the corresponding parameters
sbm->setPreFilterCap(31);
sbm->setMinDisparity(0);
sbm->setTextureThreshold(10);
sbm->setUniquenessRatio(0);
sbm->setSpeckleWindowSize(400);//speckle size
sbm->setSpeckleRange(200);
sbm->setDisp12MaxDiff(0);
sbm->setScalleFactor(16);//the scaling factor
sbm->setBinaryKernelType(binary_descriptor_type);//binary descriptor kernel
sbm->setAgregationWindowSize(aggregation_window);
//speckle removal algorithm the user can choose between the average speckle removal algorithm
//or the classical version that was implemented in open cv
sbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM);
sbm->setUsePrefilter(false);//pre-filter or not the images prior to making the transformations
//-- calculate the disparity image
sbm->compute(image1, image2, test);
if(test.empty())
{
ts->printf(cvtest::TS::LOG, "Wrong input / output dimension \n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
if(errorLevel(gt,test) > 20)
{
ts->printf( cvtest::TS::LOG,
"Too big error\n");
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
return;
}
}
class CV_SGBlockMatchingTest : public cvtest::BaseTest
{
public:
CV_SGBlockMatchingTest();
~CV_SGBlockMatchingTest();
protected:
void run(int /* idx */);
};
CV_SGBlockMatchingTest::CV_SGBlockMatchingTest(){}
CV_SGBlockMatchingTest::~CV_SGBlockMatchingTest(){}
void CV_SGBlockMatchingTest::run(int )
{
Mat image1, image2, gt;
//some test images can be found in the test data folder
image1 = imread(ts->get_data_path() + "testdata/imL2l.bmp", CV_8UC1);
image2 = imread(ts->get_data_path() + "testdata/imL2.bmp", CV_8UC1);
gt = imread(ts->get_data_path() + "testdata/groundtruth.bmp", CV_8UC1);
if(image1.empty() || image2.empty() || gt.empty())
{
ts->printf(cvtest::TS::LOG, "Wrong input data \n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
return;
}
if(image1.rows != image2.rows || image1.cols != image2.cols || gt.cols != gt.cols || gt.rows != gt.rows)
{
ts->printf(cvtest::TS::LOG, "Wrong input / output dimension \n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
return;
}
RNG range;
//set the parameters
int binary_descriptor_type = range.uniform(0,8);
int kernel_size;
if(binary_descriptor_type == 0)
kernel_size = 5;
else if(binary_descriptor_type == 2 || binary_descriptor_type == 3)
kernel_size = 7;
else if(binary_descriptor_type == 1)
kernel_size = 11;
else
kernel_size = 9;
Mat test = Mat(image1.rows, image1.cols, CV_8UC1);
Mat imgDisparity16S2 = Mat(image1.rows, image1.cols, CV_16S);
Ptr<StereoBinarySGBM> sgbm = StereoBinarySGBM::create(0, 16, kernel_size);
//setting the penalties for sgbm
sgbm->setP1(10);
sgbm->setP2(100);
sgbm->setMinDisparity(0);
sgbm->setNumDisparities(16);//set disparity number
sgbm->setUniquenessRatio(1);
sgbm->setSpeckleWindowSize(400);
sgbm->setSpeckleRange(200);
sgbm->setDisp12MaxDiff(1);
sgbm->setBinaryKernelType(binary_descriptor_type);//set the binary descriptor
sgbm->setSpekleRemovalTechnique(CV_SPECKLE_REMOVAL_AVG_ALGORITHM); //the avg speckle removal algorithm
sgbm->setSubPixelInterpolationMethod(CV_SIMETRICV_INTERPOLATION);// the SIMETRIC V interpolation method
sgbm->compute(image1, image2, imgDisparity16S2);
double minVal; double maxVal;
minMaxLoc(imgDisparity16S2, &minVal, &maxVal);
imgDisparity16S2.convertTo(test, CV_8UC1, 255 / (maxVal - minVal));
if(test.empty())
{
ts->printf(cvtest::TS::LOG, "Wrong input / output dimension \n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
double error = errorLevel(gt,test);
if(error > 10)
{
ts->printf( cvtest::TS::LOG,
"Too big error\n");
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
return;
}
}
TEST(block_matching_simple_test, accuracy) { CV_BlockMatchingTest test; test.safe_run(); }
TEST(SG_block_matching_simple_test, accuracy) { CV_SGBlockMatchingTest test; test.safe_run(); }
This diff is collapsed.
......@@ -12,8 +12,6 @@
#include <iostream>
#include "opencv2/ts.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/stereo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features2d.hpp"
......@@ -22,10 +20,9 @@
#include "opencv2/core/cvdef.h"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/calib3d.hpp"
#include <algorithm>
#include <cmath>
#endif
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