From c8e76fde9abb4f63ca30f30a18c50df59182cb2b Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Tue, 5 May 2020 11:14:26 +0300 Subject: [PATCH] Add mean reference pixel --- lib/libstereo/CMakeLists.txt | 2 + lib/libstereo/include/stereo.hpp | 38 ++++++++++++++- lib/libstereo/middlebury/main.cpp | 14 ++++++ lib/libstereo/src/algorithms/meancensussgm.cu | 48 +++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 lib/libstereo/src/algorithms/meancensussgm.cu diff --git a/lib/libstereo/CMakeLists.txt b/lib/libstereo/CMakeLists.txt index a5fe73958..fba64234b 100644 --- a/lib/libstereo/CMakeLists.txt +++ b/lib/libstereo/CMakeLists.txt @@ -43,6 +43,7 @@ if (LIBSTEREO_SHARED) src/algorithms/tcensussgm.cu src/algorithms/hcensussgm.cu src/algorithms/brefcensussgm.cu + src/algorithms/meancensussgm.cu #src/stereo_hier_census.cu src/stereo_wcensussgm.cu src/stereo_census_adaptive.cu @@ -75,6 +76,7 @@ else() src/algorithms/tcensussgm.cu src/algorithms/hcensussgm.cu src/algorithms/brefcensussgm.cu + src/algorithms/meancensussgm.cu #src/stereo_hier_census.cu src/stereo_wcensussgm.cu src/stereo_census_adaptive.cu diff --git a/lib/libstereo/include/stereo.hpp b/lib/libstereo/include/stereo.hpp index ea40a6386..4c802da27 100644 --- a/lib/libstereo/include/stereo.hpp +++ b/lib/libstereo/include/stereo.hpp @@ -86,7 +86,43 @@ private: }; /** - * Bilateral filtering for reference pixel. Doesn't make things better + * Mean reference pixel. Doesn't work since detail is lost form reference + * + * @see "A robust local census-based stereo matching insensitive to illumination changes" (2012) + * @see "A stereo matching algorithm based on four-moded census and relative confidence plane fitting" (2015) + * @see "Stereo matching based on improved census transform" (2018) + */ +class StereoMeanCensusSgm { +public: + StereoMeanCensusSgm(); + ~StereoMeanCensusSgm(); + + void compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disparity); + void setPrior(cv::InputArray disp) {}; + + struct Parameters { + int d_min = 0; + int d_max = 0; + unsigned short P1 = 5; + unsigned short P2 = 25; + float uniqueness = std::numeric_limits<unsigned short>::max(); + int subpixel = 1; // subpixel interpolation method + bool lr_consistency = true; + int paths = AggregationDirections::HORIZONTAL | + AggregationDirections::VERTICAL | + AggregationDirections::DIAGONAL; + bool debug = false; + }; + Parameters params; + +private: + struct Impl; + Impl *impl_; +}; + +/** + * Bilateral filtering for reference pixel. Doesn't make things better, but + * still better than mean value for reference. */ class StereoBRefCensusSgm { public: diff --git a/lib/libstereo/middlebury/main.cpp b/lib/libstereo/middlebury/main.cpp index 0c627989d..ec40c620e 100644 --- a/lib/libstereo/middlebury/main.cpp +++ b/lib/libstereo/middlebury/main.cpp @@ -27,6 +27,19 @@ static void run_censussgm(MiddleburyData &data, cv::Mat &disparity) { stereo.compute(data.imL, data.imR, disparity); } +static void run_meancensussgm(MiddleburyData &data, cv::Mat &disparity) { + auto stereo = StereoMeanCensusSgm(); + stereo.params.P1 = 12; + stereo.params.P2 = 32; + + stereo.params.d_min = data.calib.vmin; + stereo.params.d_max = data.calib.vmax; + stereo.params.subpixel = 1; + stereo.params.lr_consistency = true; + stereo.params.debug = false; + stereo.compute(data.imL, data.imR, disparity); +} + static void run_brefcensussgm(MiddleburyData &data, cv::Mat &disparity) { auto stereo = StereoBRefCensusSgm(); stereo.params.P1 = 12; @@ -193,6 +206,7 @@ static const std::map<std::string, std::function<void(MiddleburyData&, cv::Mat&) { "hcensussgm", run_hcensussgm }, { "wcensussgm", run_wcensussgm }, { "brefcensus", run_brefcensussgm }, + { "mcensussgm", run_meancensussgm }, //{ "misgm", run_misgm }, { "varcensus", run_varcensus }, { "stablesgm", run_stablesgm }, diff --git a/lib/libstereo/src/algorithms/meancensussgm.cu b/lib/libstereo/src/algorithms/meancensussgm.cu new file mode 100644 index 000000000..e0c1d49d7 --- /dev/null +++ b/lib/libstereo/src/algorithms/meancensussgm.cu @@ -0,0 +1,48 @@ +#include "stereo.hpp" +#include "stereosgm.hpp" +#include "../costs/census.hpp" +#include <opencv2/cudafilters.hpp> + +struct StereoMeanCensusSgm::Impl : public StereoSgm<CensusMatchingCost, StereoMeanCensusSgm::Parameters> { + Array2D<uchar> l; + Array2D<uchar> r; + Array2D<uchar> ml; + Array2D<uchar> mr; + + Impl(StereoMeanCensusSgm::Parameters ¶ms, int width, int height, int dmin, int dmax) : + StereoSgm(params, width, height, dmin, dmax), l(width, height), r(width, height), + ml(width, height), mr(width, height) {} +}; + +StereoMeanCensusSgm::StereoMeanCensusSgm() : impl_(nullptr) { + impl_ = new Impl(params, 0, 0, 0, 0); +} + +void StereoMeanCensusSgm::compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disparity) { + + cudaSetDevice(0); + + if (l.rows() != impl_->cost.height() || r.cols() != impl_->cost.width()) { + delete impl_; impl_ = nullptr; + impl_ = new Impl(params, l.cols(), l.rows(), params.d_min, params.d_max); + } + + mat2gray(l, impl_->l); + mat2gray(r, impl_->r); + + auto filter = cv::cuda::createBoxFilter(CV_8UC1, CV_8UC1, cv::Size(5,5)); + filter->apply(impl_->l.toGpuMat(), impl_->ml.toGpuMat()); // E[X] + filter->apply(impl_->r.toGpuMat(), impl_->mr.toGpuMat()); // E[X] + + impl_->cost.set(impl_->ml, impl_->mr); + + cudaSafeCall(cudaDeviceSynchronize()); + impl_->compute(disparity); +} + +StereoMeanCensusSgm::~StereoMeanCensusSgm() { + if (impl_) { + delete impl_; + impl_ = nullptr; + } +} -- GitLab