diff --git a/components/rgbd-sources/include/ftl/rgbd/frame.hpp b/components/rgbd-sources/include/ftl/rgbd/frame.hpp new file mode 100644 index 0000000000000000000000000000000000000000..41eb7509541f40dd15d9ae121a30139edf311311 --- /dev/null +++ b/components/rgbd-sources/include/ftl/rgbd/frame.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include <ftl/rgbd/detail/source.hpp> +#include <ftl/configuration.hpp> +#include <opencv2/core.hpp> + +// https://stackoverflow.com/a/31718095/ +static uint32_t msbDeBruijn32(uint32_t v) +{ + static const int MultiplyDeBruijnBitPosition[32] = + { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + + v |= v >> 1; // first round down to one less than a power of 2 + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27]; +} + +namespace ftl { +namespace rgbd { + +class Frame { +public: + /* @todo REMOVE HARDCODED CHANNEL COUNT! + */ + Frame() : channels_(11), available_(11, false) {} + + /* @brief Reset all channels without releasing memory + */ + void reset() + { + std::fill(available_.begin(), available_.end(), false); + } + + /* @brief Is there valid data in channel + */ + bool hasChannel(const ftl::rgbd::channel_t& channel) + { + return available_[msbDeBruijn32(channel)]; + } + + /* @brief Get reference to the channel GpuMat + */ + cv::cuda::GpuMat& getChannel(const ftl::rgbd::channel_t& channel) + { + return channels_[msbDeBruijn32(channel)]; + } + +private: + std::vector<cv::cuda::GpuMat> channels_; + std::vector<bool> available_; +}; + +} +} \ No newline at end of file diff --git a/components/rgbd-sources/include/ftl/rgbd/source.hpp b/components/rgbd-sources/include/ftl/rgbd/source.hpp index 4ddf48cdb50e463619113e31edfe79d2ec7a6807..1106d76220e676a3e7e36c5db18db9596a0f91d9 100644 --- a/components/rgbd-sources/include/ftl/rgbd/source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/source.hpp @@ -12,6 +12,7 @@ #include <string> #include <ftl/cuda_common.hpp> +#include <ftl/rgbd/frame.hpp> namespace ftl { diff --git a/components/rgbd-sources/src/stereovideo.cpp b/components/rgbd-sources/src/stereovideo.cpp index b162eb90b8ec92c0082eacf471fb02091d1cce0f..58a513a08f93619b22233478c79cff3a85600c0f 100644 --- a/components/rgbd-sources/src/stereovideo.cpp +++ b/components/rgbd-sources/src/stereovideo.cpp @@ -58,7 +58,7 @@ void StereoVideoSource::init(const string &file) } cv::Size size = cv::Size(lsrc_->width(), lsrc_->height()); - frames_ = std::vector<StereoVideoSource::Frame>(2); // triple-buffering for optical flow + frames_ = std::vector<Frame>(2); #ifdef HAVE_OPTFLOW // TODO make optional, can be calculated at later step @@ -173,9 +173,12 @@ bool StereoVideoSource::capture(int64_t ts) { bool StereoVideoSource::retrieve() { auto &frame = frames_[0]; frame.reset(); - lsrc_->get(frame.left, frame.right, calib_, stream2_); + cv::cuda::GpuMat& left = frame.getChannel(ftl::rgbd::kChanLeft); + cv::cuda::GpuMat& right = frame.getChannel(ftl::rgbd::kChanRight); + lsrc_->get(left, right, calib_, stream2_); #ifdef HAVE_OPTFLOW +/* if (nvof_) { cv::cuda::cvtColor(frame.left, frame.left_gray, cv::COLOR_BGR2GRAY, 0, stream2_); @@ -190,6 +193,7 @@ bool StereoVideoSource::retrieve() { frame.optflow_ready = true; } } +*/ #endif stream2_.waitForCompletion(); @@ -204,24 +208,31 @@ void StereoVideoSource::swap() { bool StereoVideoSource::compute(int n, int b) { auto &frame = frames_[1]; + cv::cuda::GpuMat& left = frame.getChannel(ftl::rgbd::kChanLeft); + cv::cuda::GpuMat& right = frame.getChannel(ftl::rgbd::kChanRight); + cv::cuda::GpuMat& depth = frame.getChannel(ftl::rgbd::kChanDepth); + cv::cuda::GpuMat& disp = frame.getChannel(ftl::rgbd::kChanDisparity); + const ftl::rgbd::channel_t chan = host_->getChannel(); - if (frame.left.empty() || frame.right.empty()) return false; + if (left.empty() || right.empty()) return false; + + if (chan == ftl::rgbd::kChanDepth) { - if (frame.depth.empty()) frame.depth = cv::cuda::GpuMat(frame.left.size(), CV_32FC1); - if (frame.disp.empty()) frame.disp = cv::cuda::GpuMat(frame.left.size(), CV_32FC1); - disp_->compute(frame.left, frame.right, frame.disp, stream_); - ftl::cuda::disparity_to_depth(frame.disp, frame.depth, params_, stream_); - frame.left.download(rgb_, stream_); - frame.depth.download(depth_, stream_); + if (depth.empty()) depth = cv::cuda::GpuMat(left.size(), CV_32FC1); + if (disp.empty()) disp = cv::cuda::GpuMat(left.size(), CV_32FC1); + disp_->compute(left, right, disp, stream_); + ftl::cuda::disparity_to_depth(disp, depth, params_, stream_); + left.download(rgb_, stream_); + depth.download(depth_, stream_); stream_.waitForCompletion(); // TODO:(Nick) Move to getFrames } else if (chan == ftl::rgbd::kChanRight) { - frame.left.download(rgb_, stream_); - frame.right.download(depth_, stream_); + left.download(rgb_, stream_); + right.download(depth_, stream_); stream_.waitForCompletion(); // TODO:(Nick) Move to getFrames } else { - frame.left.download(rgb_, stream_); + left.download(rgb_, stream_); stream_.waitForCompletion(); // TODO:(Nick) Move to getFrames } diff --git a/components/rgbd-sources/src/stereovideo.hpp b/components/rgbd-sources/src/stereovideo.hpp index 18790991cf67b483d28b06e8e4288fc36785b7d1..cd5a0c4884ca533ad9b185fafce47b2dd4722dd9 100644 --- a/components/rgbd-sources/src/stereovideo.hpp +++ b/components/rgbd-sources/src/stereovideo.hpp @@ -45,33 +45,6 @@ class StereoVideoSource : public detail::Source { cv::cuda::Stream stream_; cv::cuda::Stream stream2_; - // possibly should be made available for other users as well - // (should be called StereoVideoFrame) - class Frame { - public: - bool left_gray_ready; - bool right_gray_ready; - bool optflow_ready; - - cv::cuda::GpuMat left; - cv::cuda::GpuMat right; - cv::cuda::GpuMat left_gray; - cv::cuda::GpuMat right_gray; - cv::cuda::GpuMat disp; - cv::cuda::GpuMat depth; - cv::cuda::GpuMat optflow; - cv::cuda::GpuMat optflow_; // original lower res optical flow - - Frame() { reset(); } - - void reset() - { - left_gray_ready = false; - right_gray_ready = false; - optflow_ready = false; - } - }; - std::vector<Frame> frames_; cv::Mat mask_l_;