Skip to content

Commit dda1f3d

Browse files
committed
Merge pull request #2772 from fixstars:add_cudastereo_semi_global_matching_implementation
2 parents bc1ea8f + 7883ec8 commit dda1f3d

File tree

9 files changed

+3586
-1
lines changed

9 files changed

+3586
-1
lines changed

modules/cudastereo/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ set(the_description "CUDA-accelerated Stereo Correspondence")
66

77
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wmissing-declarations -Wshadow)
88

9-
ocv_define_module(cudastereo opencv_calib3d WRAP python)
9+
ocv_define_module(cudastereo opencv_calib3d OPTIONAL opencv_cudev WRAP python)

modules/cudastereo/doc/cudastereo.bib

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@InProceedings{Spangenberg2013,
2+
author = {Spangenberg, Robert and Langner, Tobias and Rojas, Ra{\'u}l},
3+
title = {Weighted Semi-Global Matching and Center-Symmetric Census Transform for Robust Driver Assistance},
4+
booktitle = {Computer Analysis of Images and Patterns},
5+
year = {2013},
6+
pages = {34--41},
7+
publisher = {Springer Berlin Heidelberg},
8+
abstract = {Automotive applications based on stereo vision require robust and fast matching algorithms, which makes semi-global matching (SGM) a popular method in this field. Typically the Census transform is used as a cost function, since it is advantageous for outdoor scenes. We propose an extension based on center-symmetric local binary patterns, which allows better efficiency and higher matching quality. Our second contribution exploits knowledge about the three-dimensional structure of the scene to selectively enforce the smoothness constraints of SGM. It is shown that information about surface normals can be easily integrated by weighing the paths according to the gradient of the disparity. The different approaches are evaluated on the KITTI benchmark, which provides real imagery with LIDAR ground truth. The results indicate improved performance compared to state-of-the-art SGM based algorithms.},
9+
url = {https://www.mi.fu-berlin.de/inf/groups/ag-ki/publications/Semi-Global_Matching/caip2013rsp_fu.pdf}
10+
}

modules/cudastereo/include/opencv2/cudastereo.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,53 @@ class CV_EXPORTS_W StereoConstantSpaceBP : public cuda::StereoBeliefPropagation
241241
CV_EXPORTS_W Ptr<cuda::StereoConstantSpaceBP>
242242
createStereoConstantSpaceBP(int ndisp = 128, int iters = 8, int levels = 4, int nr_plane = 4, int msg_type = CV_32F);
243243

244+
/////////////////////////////////////////
245+
// StereoSGM
246+
247+
/** @brief The class implements the modified H. Hirschmuller algorithm @cite HH08.
248+
Limitation and difference are as follows:
249+
250+
- By default, the algorithm uses only 4 directions which are horizontal and vertical path instead of 8.
251+
Set mode=StereoSGM::MODE_HH in createStereoSGM to run the full variant of the algorithm.
252+
- Mutual Information cost function is not implemented.
253+
Instead, Center-Symmetric Census Transform with \f$9 \times 7\f$ window size from @cite Spangenberg2013
254+
is used for robustness.
255+
256+
@sa cv::StereoSGBM
257+
*/
258+
class CV_EXPORTS_W StereoSGM : public cv::StereoSGBM
259+
{
260+
public:
261+
/** @brief Computes disparity map for the specified stereo pair
262+
263+
@param left Left 8-bit or 16-bit unsigned single-channel image.
264+
@param right Right image of the same size and the same type as the left one.
265+
@param disparity Output disparity map. It has the same size as the input images.
266+
StereoSGM computes 16-bit fixed-point disparity map (where each disparity value has 4 fractional bits).
267+
*/
268+
CV_WRAP virtual void compute(InputArray left, InputArray right, OutputArray disparity) CV_OVERRIDE = 0;
269+
270+
/** @brief Computes disparity map with specified CUDA Stream
271+
272+
@sa compute
273+
*/
274+
CV_WRAP_AS(compute_with_stream) virtual void compute(InputArray left, InputArray right, OutputArray disparity, Stream& stream) = 0;
275+
};
276+
277+
/** @brief Creates StereoSGM object.
278+
279+
@param minDisparity Minimum possible disparity value. Normally, it is zero but sometimes rectification algorithms can shift images, so this parameter needs to be adjusted accordingly.
280+
@param numDisparities Maximum disparity minus minimum disparity. The value must be 64, 128 or 256.
281+
@param P1 The first parameter controlling the disparity smoothness.This parameter is used for the case of slanted surfaces (not fronto parallel).
282+
@param P2 The second parameter controlling the disparity smoothness.This parameter is used for "solving" the depth discontinuities problem.
283+
@param uniquenessRatio Margin in percentage by which the best (minimum) computed cost function
284+
value should "win" the second best value to consider the found match correct. Normally, a value
285+
within the 5-15 range is good enough.
286+
@param mode Set it to StereoSGM::MODE_HH to run the full-scale two-pass dynamic programming algorithm.
287+
It will consume O(W\*H\*numDisparities) bytes. By default, it is set to StereoSGM::MODE_HH4.
288+
*/
289+
CV_EXPORTS_W Ptr<cuda::StereoSGM> createStereoSGM(int minDisparity = 0, int numDisparities = 128, int P1 = 10, int P2 = 120, int uniquenessRatio = 5, int mode = cv::cuda::StereoSGM::MODE_HH4);
290+
244291
/////////////////////////////////////////
245292
// DisparityBilateralFilter
246293

modules/cudastereo/perf/perf_stereo.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,4 +252,38 @@ PERF_TEST_P(Sz_Depth, DrawColorDisp,
252252
}
253253
}
254254

255+
//////////////////////////////////////////////////////////////////////
256+
// StereoSGM
257+
258+
PERF_TEST_P(ImagePair, StereoSGM,
259+
Values(pair_string("gpu/perf/aloe.png", "gpu/perf/aloeR.png")))
260+
{
261+
declare.time(300.0);
262+
263+
const cv::Mat imgLeft = readImage(GET_PARAM(0), cv::IMREAD_GRAYSCALE);
264+
ASSERT_FALSE(imgLeft.empty());
265+
266+
const cv::Mat imgRight = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
267+
ASSERT_FALSE(imgRight.empty());
268+
269+
const int ndisp = 128;
270+
271+
if (PERF_RUN_CUDA())
272+
{
273+
cv::Ptr<cv::cuda::StereoSGM> d_sgm = cv::cuda::createStereoSGM(0, ndisp);
274+
275+
const cv::cuda::GpuMat d_imgLeft(imgLeft);
276+
const cv::cuda::GpuMat d_imgRight(imgRight);
277+
cv::cuda::GpuMat dst;
278+
279+
TEST_CYCLE() d_sgm->compute(d_imgLeft, d_imgRight, dst);
280+
281+
CUDA_SANITY_CHECK(dst);
282+
}
283+
else
284+
{
285+
FAIL_NO_CPU();
286+
}
287+
}
288+
255289
}} // namespace

0 commit comments

Comments
 (0)