From 47d7b3fa188f2de709827c86031b649c39d6a1a6 Mon Sep 17 00:00:00 2001 From: Sebastian Hahta <joseha@utu.fi> Date: Thu, 5 Sep 2019 13:18:54 +0300 Subject: [PATCH] more changes; optflow with config option --- .../rgbd-sources/include/ftl/rgbd/frame.hpp | 17 +++-- .../src/algorithms/fixstars_sgm.cpp | 69 +++++++++++-------- .../src/algorithms/fixstars_sgm.hpp | 4 -- components/rgbd-sources/src/disparity.cpp | 28 +++++++- components/rgbd-sources/src/disparity.hpp | 26 +++++-- components/rgbd-sources/src/stereovideo.cpp | 10 ++- components/rgbd-sources/src/stereovideo.hpp | 2 - 7 files changed, 103 insertions(+), 53 deletions(-) diff --git a/components/rgbd-sources/include/ftl/rgbd/frame.hpp b/components/rgbd-sources/include/ftl/rgbd/frame.hpp index 17205d4c6..227913e5d 100644 --- a/components/rgbd-sources/include/ftl/rgbd/frame.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/frame.hpp @@ -19,20 +19,25 @@ static const channel_t kChanDisparity = 0x0008; // CV_32FC1 static const channel_t kChanDeviation = 0x0010; static const channel_t kChanNormals = 0x0020; static const channel_t kChanConfidence = 0x0040; -static const channel_t kChanFlow = 0x0080; // CV_32FC2 or CV_16FC2 (fix) +static const channel_t kChanFlow = 0x0080; // CV_16SC2 (format 10.5) from NVOF static const channel_t kChanEnergy = 0x0100; -//static const channel_t kChanLeftGray = 0x0200; // not used // CV_8UC1 -//static const channel_t kChanRightGray = 0x0400; // not used // CV_8UC1 + +// should l/r gray be removed (not that expensive to re-calculate if needed)? +static const channel_t kChanLeftGray = 0x0200; // CV_8UC1 +static const channel_t kChanRightGray = 0x0400; // CV_8UC1 static const channel_t kChanOverlay1 = 0x1000; // maximum number of available channels -static const unsigned int n_channels = 11; +static const unsigned int n_channels = 13; inline bool isFloatChannel(ftl::rgbd::channel_t chan) { return (chan == ftl::rgbd::kChanDepth || chan == ftl::rgbd::kChanEnergy); } +// TODO: interpolation for scaling depends on channel type; +// NN for depth/disparity/optflow, linear/cubic/etc. for RGB + class Frame; class Frame { @@ -100,8 +105,8 @@ private: case kChanConfidence: return 7; case kChanFlow: return 8; case kChanEnergy: return 9; -// case kChanLeftGray: return 11; -// case kChanRightGray: return 12; + case kChanLeftGray: return 11; + case kChanRightGray: return 12; // should not happen (error); returned index is kChanNone default: return 0; } diff --git a/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp b/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp index 0d8cfa877..782338fc2 100644 --- a/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp +++ b/components/rgbd-sources/src/algorithms/fixstars_sgm.cpp @@ -12,11 +12,9 @@ using cv::cuda::GpuMat; FixstarsSGM::FixstarsSGM(nlohmann::json &config) : Disparity(config) { ssgm_ = nullptr; + const int width = size_.width; + const int height = size_.height; - int width = value("width", 1280); - int height = value("height", 720); - - size_ = cv::Size(width, height); CHECK((width >= 480) && (height >= 360)); uniqueness_ = value("uniqueness", 0.95f); @@ -66,8 +64,22 @@ void FixstarsSGM::init(const cv::Size size) { void FixstarsSGM::compute(ftl::rgbd::Frame &frame, cv::cuda::Stream &stream) { - const auto &l = frame.getChannel<GpuMat>(ftl::rgbd::kChanLeft); - const auto &r = frame.getChannel<GpuMat>(ftl::rgbd::kChanRight); + /*if (!frame.hasChannel(ftl::rgbd::kChanLeftGray)) + { + auto &rgb = frame.getChannel<GpuMat>(ftl::rgbd::kChanLeft, stream); + auto &gray = frame.setChannel<GpuMat>(ftl::rgbd::kChanLeftGray); + cv::cuda::cvtColor(rgb, gray, cv::COLOR_BGR2GRAY, 0, stream); + } + + if (!frame.hasChannel(ftl::rgbd::kChanRightGray)) + { + auto &rgb = frame.getChannel<GpuMat>(ftl::rgbd::kChanRight, stream); + auto &gray = frame.setChannel<GpuMat>(ftl::rgbd::kChanRightGray); + cv::cuda::cvtColor(rgb, gray, cv::COLOR_BGR2GRAY, 0, stream); + }*/ + + const auto &l = frame.getChannel<GpuMat>(ftl::rgbd::kChanLeft, stream); + const auto &r = frame.getChannel<GpuMat>(ftl::rgbd::kChanRight, stream); auto &disp = frame.setChannel<GpuMat>(ftl::rgbd::kChanDisparity); if (disp.size() != l.size()) @@ -75,45 +87,48 @@ void FixstarsSGM::compute(ftl::rgbd::Frame &frame, cv::cuda::Stream &stream) disp = GpuMat(l.size(), CV_32FC1); } - if (l.size() != size_) { - // re-use same buffer for l/r - cv::cuda::resize(r, l_downscaled_, size_, 0.0, 0.0, cv::INTER_CUBIC, stream); - cv::cuda::cvtColor(l_downscaled_, rbw_, cv::COLOR_BGR2GRAY, 0, stream); - cv::cuda::resize(l, l_downscaled_, size_, 0.0, 0.0, cv::INTER_CUBIC, stream); - cv::cuda::cvtColor(l_downscaled_, lbw_, cv::COLOR_BGR2GRAY, 0, stream); + GpuMat l_scaled; + if (l.size() != size_) + { + GpuMat _r; + scaleInput(l, r, l_scaled, _r, stream); + cv::cuda::cvtColor(l_scaled, lbw_, cv::COLOR_BGR2GRAY, 0, stream); + cv::cuda::cvtColor(_r, rbw_, cv::COLOR_BGR2GRAY, 0, stream); } - else { + else + { cv::cuda::cvtColor(l, lbw_, cv::COLOR_BGR2GRAY, 0, stream); cv::cuda::cvtColor(r, rbw_, cv::COLOR_BGR2GRAY, 0, stream); } stream.waitForCompletion(); - ssgm_->execute(lbw_.data, rbw_.data, dispt_.data); - GpuMat left_pixels(dispt_, cv::Rect(0, 0, max_disp_, dispt_.rows)); left_pixels.setTo(0); cv::cuda::threshold(dispt_, dispt_, 4096.0f, 0.0f, cv::THRESH_TOZERO_INV, stream); // TODO: filter could be applied after upscaling (to the upscaled disparity image) - if (use_filter_) { - filter_->apply(dispt_, - l.size() != dispt_.size() ? l_downscaled_ : l, + if (use_filter_) + { + filter_->apply( + dispt_, + (l.size() == size_) ? l : l_scaled, dispt_, stream ); } - if (l.size() != size_) { - cv::cuda::multiply(dispt_, (double)l.cols / (double)size_.width, dispt_); - // invalid areas (bad values) have to be taken into account in interpolation - cv::cuda::resize(dispt_, dispt_full_res_, l.size(), 0.0, 0.0, cv::INTER_NEAREST, stream); + GpuMat dispt_scaled; + if (l.size() != size_) + { + scaleDisparity(l.size(), dispt_, dispt_scaled, stream); } - else { - dispt_full_res_ = dispt_; + else + { + dispt_scaled = dispt_; } - dispt_full_res_.convertTo(disp, CV_32F, 1.0f / 16.0f, stream); + dispt_scaled.convertTo(disp, CV_32F, 1.0f / 16.0f, stream); #ifdef HAVE_OPTFLOW if (use_off_) @@ -127,9 +142,7 @@ void FixstarsSGM::compute(ftl::rgbd::Frame &frame, cv::cuda::Stream &stream) void FixstarsSGM::setMask(Mat &mask) { return; // TODO(Nick) Not needed, but also code below does not work with new GPU pipeline CHECK(mask.type() == CV_8UC1) << "mask type must be CV_8U"; - if (!ssgm_) { init(size_); } - - mask_l_ = mask; + mask_l_ = GpuMat(mask); ssgm_->setMask((uint8_t*)mask.data, mask.cols); } \ No newline at end of file diff --git a/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp b/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp index 14f80bf89..039db0c87 100644 --- a/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp +++ b/components/rgbd-sources/src/algorithms/fixstars_sgm.hpp @@ -44,7 +44,6 @@ namespace ftl { float uniqueness_; int P1_; int P2_; - cv::Size size_; bool use_filter_; bool use_off_; cv::Ptr<cv::cuda::DisparityBilateralFilter> filter_; @@ -53,9 +52,6 @@ namespace ftl { cv::cuda::GpuMat rbw_; cv::cuda::GpuMat dispt_; - cv::cuda::GpuMat l_downscaled_; - cv::cuda::GpuMat dispt_full_res_; - #ifdef HAVE_OPTFLOW ftl::rgbd::OFDisparityFilter off_; #endif diff --git a/components/rgbd-sources/src/disparity.cpp b/components/rgbd-sources/src/disparity.cpp index e92c72de7..7d9089c1a 100644 --- a/components/rgbd-sources/src/disparity.cpp +++ b/components/rgbd-sources/src/disparity.cpp @@ -15,7 +15,11 @@ std::map<std::string, std::function<Disparity*(ftl::Configurable *, const std::s Disparity::Disparity(nlohmann::json &config) : ftl::Configurable(config), min_disp_(value("minimum",0)), - max_disp_(value("maximum", 256)) {} + max_disp_(value("maximum", 256)), + size_(value("width", 1280), value("height", 720)) + { + + } Disparity *Disparity::create(ftl::Configurable *parent, const std::string &name) { nlohmann::json &config = ftl::config::resolve((!parent->getConfig()[name].is_null()) ? parent->getConfig()[name] : ftl::config::resolve(parent->getConfig())[name]); // ftl::config::resolve(parent->getConfig()[name]); @@ -37,6 +41,28 @@ void Disparity::_register(const std::string &n, (*algorithms__)[n] = f; } +void Disparity::scaleInput( const cv::cuda::GpuMat& left_in, + const cv::cuda::GpuMat& right_in, + cv::cuda::GpuMat& left_out, + cv::cuda::GpuMat& right_out, + cv::cuda::Stream &stream) +{ + cv::cuda::resize(left_in, left_scaled_, size_, 0.0, 0.0, cv::INTER_CUBIC, stream); + left_out = left_scaled_; + cv::cuda::resize(right_in, right_scaled_, size_, 0.0, 0.0, cv::INTER_CUBIC, stream); + right_out = right_scaled_; +} + +void Disparity::scaleDisparity( const cv::Size& new_size, + cv::cuda::GpuMat& in, + cv::cuda::GpuMat& out, + cv::cuda::Stream& stream) +{ + cv::cuda::multiply(in, (double) new_size.width / (double) in.cols, in); + cv::cuda::resize(in, dispt_scaled_, new_size, 0.0, 0.0, cv::INTER_NEAREST, stream); + out = dispt_scaled_; +} + // TODO:(Nick) Add remaining algorithms /* #include "algorithms/rtcensus.hpp" diff --git a/components/rgbd-sources/src/disparity.hpp b/components/rgbd-sources/src/disparity.hpp index a5e7efea7..2ab8223ca 100644 --- a/components/rgbd-sources/src/disparity.hpp +++ b/components/rgbd-sources/src/disparity.hpp @@ -27,8 +27,20 @@ class Disparity : public ftl::Configurable { virtual void setMinDisparity(size_t min) { min_disp_ = min; } virtual void setMaxDisparity(size_t max) { max_disp_ = max; } - virtual void setMask(cv::Mat &mask) { mask_l_ = mask; } + virtual void setMask(cv::Mat &mask) { mask_l_ = cv::cuda::GpuMat(mask); } + virtual void setMask(cv::cuda::GpuMat &mask) { mask_l_ = mask; } + void scaleInput(const cv::cuda::GpuMat& left_in, + const cv::cuda::GpuMat& right_in, + cv::cuda::GpuMat& left_out, + cv::cuda::GpuMat& right_out, + cv::cuda::Stream &stream); + + void scaleDisparity(const cv::Size &new_size, + cv::cuda::GpuMat& in, + cv::cuda::GpuMat& out, + cv::cuda::Stream &stream); + /** * Pure virtual function representing the actual computation of * disparity from left and right images to be implemented. @@ -42,7 +54,6 @@ class Disparity : public ftl::Configurable { frame.setChannel<cv::cuda::GpuMat>(kChanDisparity) = disp; } - /** * Factory registration class. */ @@ -63,11 +74,15 @@ class Disparity : public ftl::Configurable { protected: static void _register(const std::string &n, std::function<Disparity*(ftl::Configurable *, const std::string &)> f); - protected: - //nlohmann::json &config_; +protected: int min_disp_; int max_disp_; - cv::Mat mask_l_; + cv::Size size_; + + cv::cuda::GpuMat left_scaled_; + cv::cuda::GpuMat right_scaled_; + cv::cuda::GpuMat dispt_scaled_; + cv::cuda::GpuMat mask_l_; private: static std::map<std::string,std::function<Disparity*(ftl::Configurable *, const std::string &)>> *algorithms__; @@ -78,4 +93,3 @@ class Disparity : public ftl::Configurable { } #endif // _FTL_DISPARITY_HPP_ - diff --git a/components/rgbd-sources/src/stereovideo.cpp b/components/rgbd-sources/src/stereovideo.cpp index 05f0f6765..ebc72d854 100644 --- a/components/rgbd-sources/src/stereovideo.cpp +++ b/components/rgbd-sources/src/stereovideo.cpp @@ -61,14 +61,13 @@ void StereoVideoSource::init(const string &file) frames_ = std::vector<Frame>(2); #ifdef HAVE_OPTFLOW -/* - use_optflow_ = host_->value("use_optflow", false); + use_optflow_ = host_->value("use_optflow", false); LOG(INFO) << "Using optical flow: " << (use_optflow_ ? "true" : "false"); nvof_ = cv::cuda::NvidiaOpticalFlow_1_0::create(size.width, size.height, cv::cuda::NvidiaOpticalFlow_1_0::NV_OF_PERF_LEVEL_SLOW, true, false, false, 0); -*/ + #endif calib_ = ftl::create<Calibrate>(host_, "calibration", size, stream_); @@ -181,7 +180,6 @@ bool StereoVideoSource::retrieve() { lsrc_->get(left, right, calib_, stream2_); #ifdef HAVE_OPTFLOW -/* // see comments in https://gitlab.utu.fi/nicolas.pope/ftl/issues/155 if (use_optflow_) @@ -198,10 +196,10 @@ bool StereoVideoSource::retrieve() { auto &optflow = frame.setChannel<cv::cuda::GpuMat>(kChanFlow); nvof_->calc(left_gray, left_gray_prev, optflow_, stream2_); // nvof_->upSampler() isn't implemented with CUDA - cv::cuda::resize(optflow_, optflow, left.size(), 0.0, 0.0, cv::INTER_NEAREST, stream2_); + // cv::cuda::resize() does not work wiht 2-channel input + // cv::cuda::resize(optflow_, optflow, left.size(), 0.0, 0.0, cv::INTER_NEAREST, stream2_); } } -*/ #endif stream2_.waitForCompletion(); diff --git a/components/rgbd-sources/src/stereovideo.hpp b/components/rgbd-sources/src/stereovideo.hpp index 226f1c548..9fe3ca529 100644 --- a/components/rgbd-sources/src/stereovideo.hpp +++ b/components/rgbd-sources/src/stereovideo.hpp @@ -51,11 +51,9 @@ class StereoVideoSource : public detail::Source { cv::Mat mask_l_; #ifdef HAVE_OPTFLOW -/* // see comments in https://gitlab.utu.fi/nicolas.pope/ftl/issues/155 cv::Ptr<cv::cuda::NvidiaOpticalFlow_1_0> nvof_; cv::cuda::GpuMat optflow_; -*/ #endif void init(const std::string &); -- GitLab