From 481406f45c00dae3619fc5640000e2fe7d075b6c Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Sun, 3 Nov 2019 13:14:22 +0200
Subject: [PATCH] Multires smooth channel

---
 .../include/ftl/operators/smoothing.hpp       |  2 ++
 components/operators/src/smoothing.cpp        | 24 ++++++++++++++++++-
 .../rgbd-sources/include/ftl/rgbd/camera.hpp  |  2 ++
 components/rgbd-sources/src/source.cpp        |  5 ++--
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/components/operators/include/ftl/operators/smoothing.hpp b/components/operators/include/ftl/operators/smoothing.hpp
index a35053d2a..1f6961d81 100644
--- a/components/operators/include/ftl/operators/smoothing.hpp
+++ b/components/operators/include/ftl/operators/smoothing.hpp
@@ -42,6 +42,8 @@ class SmoothChannel : public ftl::operators::Operator {
 
     bool apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgbd::Source *src, cudaStream_t stream) override;
 
+	private:
+	ftl::rgbd::Frame temp_[2];
 };
 
 /**
diff --git a/components/operators/src/smoothing.cpp b/components/operators/src/smoothing.cpp
index 01f7f7de6..79f372077 100644
--- a/components/operators/src/smoothing.cpp
+++ b/components/operators/src/smoothing.cpp
@@ -74,8 +74,11 @@ bool SmoothChannel::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgbd
 	int radius = config()->value("radius", 1);
 	float threshold = config()->value("threshold", 30.0f);
 
+	int width = s->parameters().width;
+	int height = s->parameters().height;
+
 	// Clear to max smoothing
-	out.create<GpuMat>(Channel::Smoothing, Format<float>(s->parameters().width, s->parameters().height)).setTo(cv::Scalar(1.0f));
+	out.create<GpuMat>(Channel::Smoothing, Format<float>(width, height)).setTo(cv::Scalar(1.0f));
 
 	// Reduce to nearest
 	ftl::cuda::smooth_channel(
@@ -88,6 +91,25 @@ bool SmoothChannel::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgbd
 		stream
 	);
 
+	width /= 2;
+	height /= 2;
+
+	ftl::rgbd::Camera scaledCam = s->parameters().scaled(width, height);
+
+	// Downscale images for next pass
+	cv::cuda::resize(in.get<GpuMat>(Channel::Colour), temp_[0].create<GpuMat>(Channel::Colour), cv::Size(width, height), 0.0, 0.0, cv::INTER_LINEAR);
+	cv::cuda::resize(in.get<GpuMat>(Channel::Depth), temp_[0].create<GpuMat>(Channel::Depth), cv::Size(width, height), 0.0, 0.0, cv::INTER_NEAREST);
+
+	ftl::cuda::smooth_channel(
+		temp_[0].createTexture<uchar4>(Channel::Colour),
+		temp_[0].createTexture<float>(Channel::Depth),
+		out.getTexture<float>(Channel::Smoothing),
+		scaledCam,
+		threshold,
+		radius,
+		stream
+	);
+
 	return true;
 }
 
diff --git a/components/rgbd-sources/include/ftl/rgbd/camera.hpp b/components/rgbd-sources/include/ftl/rgbd/camera.hpp
index 9fd6b98a0..2d36b2f75 100644
--- a/components/rgbd-sources/include/ftl/rgbd/camera.hpp
+++ b/components/rgbd-sources/include/ftl/rgbd/camera.hpp
@@ -29,6 +29,8 @@ struct __align__(16) Camera {
 	double baseline;		// For stereo pair
 	double doffs;			// Disparity offset
 
+	Camera scaled(int width, int height) const;
+
 	/**
 	 * Convert camera coordinates into screen coordinates.
 	 */
diff --git a/components/rgbd-sources/src/source.cpp b/components/rgbd-sources/src/source.cpp
index a7b6b2cb0..24629e139 100644
--- a/components/rgbd-sources/src/source.cpp
+++ b/components/rgbd-sources/src/source.cpp
@@ -280,7 +280,8 @@ void Source::notifyRaw(const ftl::codecs::StreamPacket &spkt, const ftl::codecs:
 /*
  * Scale camera parameters to match resolution.
  */
-static Camera scaled(Camera &cam, int width, int height) {
+Camera Camera::scaled(int width, int height) const {
+	const auto &cam = *this;
 	float scaleX = (float)width / (float)cam.width;
 	float scaleY = (float)height / (float)cam.height;
 
@@ -304,7 +305,7 @@ void Source::notify(int64_t ts, cv::cuda::GpuMat &c1, cv::cuda::GpuMat &c2) {
 
 	// Do we need to scale camera parameters
 	if (impl_->params_.width < max_width || impl_->params_.height < max_height) {
-		impl_->params_ = scaled(impl_->params_, max_width, max_height);
+		impl_->params_ = impl_->params_.scaled(max_width, max_height);
 	}
 
 	// Should channel 1 be scaled?
-- 
GitLab