From 744267cfe00b907b63a31124a6a096ded49087e1 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Sat, 7 Nov 2020 10:42:01 +0200
Subject: [PATCH] Add normals channel

---
 SDK/C++/private/frame_impl.cpp                   |  1 +
 SDK/C++/private/image_impl.cpp                   |  9 +++++++++
 SDK/C++/public/include/voltu/types/image.hpp     |  5 +++--
 SDK/C++/public/samples/fusion_evaluator/main.cpp |  2 +-
 SDK/C++/public/voltu_cv.cpp                      | 13 +++++++++++++
 5 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/SDK/C++/private/frame_impl.cpp b/SDK/C++/private/frame_impl.cpp
index ae295fe03..0b0779b6a 100644
--- a/SDK/C++/private/frame_impl.cpp
+++ b/SDK/C++/private/frame_impl.cpp
@@ -24,6 +24,7 @@ std::list<voltu::ImagePtr> FrameImpl::getImageSet(voltu::Channel c)
 	{
 	case voltu::Channel::kColour	: channel = ftl::codecs::Channel::Colour; break;
 	case voltu::Channel::kDepth		: channel = ftl::codecs::Channel::Depth; break;
+	case voltu::Channel::kNormals	: channel = ftl::codecs::Channel::Normals; break;
 	default: throw voltu::exceptions::BadImageChannel();
 	}
 
diff --git a/SDK/C++/private/image_impl.cpp b/SDK/C++/private/image_impl.cpp
index f8bf63a27..76dea9a22 100644
--- a/SDK/C++/private/image_impl.cpp
+++ b/SDK/C++/private/image_impl.cpp
@@ -30,6 +30,10 @@ voltu::ImageData ImageImpl::getHost()
 	{
 		r.format = voltu::ImageFormat::kFloat32;
 	}
+	else if (m.type() == CV_16FC4)
+	{
+		r.format = voltu::ImageFormat::kFloat16_4;
+	}
 
 	return r;
 }
@@ -51,6 +55,10 @@ voltu::ImageData ImageImpl::getDevice()
 	{
 		r.format = voltu::ImageFormat::kFloat32;
 	}
+	else if (m.type() == CV_16FC4)
+	{
+		r.format = voltu::ImageFormat::kFloat16_4;
+	}
 
 	return r;
 }
@@ -66,6 +74,7 @@ voltu::Channel ImageImpl::getChannel()
 	{
 	case ftl::codecs::Channel::Colour		: return voltu::Channel::kColour;
 	case ftl::codecs::Channel::Depth		: return voltu::Channel::kDepth;
+	case ftl::codecs::Channel::Normals		: return voltu::Channel::kNormals;
 	default: return voltu::Channel::kInvalid;
 	}
 }
diff --git a/SDK/C++/public/include/voltu/types/image.hpp b/SDK/C++/public/include/voltu/types/image.hpp
index 6064f894d..406c81df8 100644
--- a/SDK/C++/public/include/voltu/types/image.hpp
+++ b/SDK/C++/public/include/voltu/types/image.hpp
@@ -15,7 +15,8 @@ enum class ImageFormat
 {
 	kInvalid = 0,
 	kFloat32 = 1,
-	kBGRA8 = 2
+	kBGRA8 = 2,
+	kFloat16_4 = 3
 };
 
 PY_NO_SHARED_PTR struct ImageData
@@ -31,7 +32,7 @@ class Image
 {
 public:
 	virtual ~Image() = default;
-	
+
 	PY_API PY_RV_LIFETIME_PARENT virtual ImageData getHost() = 0;
 
 	virtual ImageData getDevice() = 0;
diff --git a/SDK/C++/public/samples/fusion_evaluator/main.cpp b/SDK/C++/public/samples/fusion_evaluator/main.cpp
index 7745484df..d388851e9 100644
--- a/SDK/C++/public/samples/fusion_evaluator/main.cpp
+++ b/SDK/C++/public/samples/fusion_evaluator/main.cpp
@@ -42,7 +42,7 @@ int main(int argc, char **argv)
 	pipe->submit(frame);
 	pipe->waitCompletion(1000);
 
-	auto imgset = frame->getImageSet(voltu::Channel::kColour);
+	auto imgset = frame->getImageSet(voltu::Channel::kNormals);
 
 	for (auto img : imgset)
 	{
diff --git a/SDK/C++/public/voltu_cv.cpp b/SDK/C++/public/voltu_cv.cpp
index 3b77155b6..d74ad9313 100644
--- a/SDK/C++/public/voltu_cv.cpp
+++ b/SDK/C++/public/voltu_cv.cpp
@@ -14,6 +14,10 @@ void voltu::cv::convert(voltu::ImagePtr img, ::cv::Mat &mat)
 	{
 		mat = ::cv::Mat(data.height, data.width, CV_32FC1, data.data);
 	}
+	else if (data.format == voltu::ImageFormat::kFloat16_4)
+	{
+		mat = ::cv::Mat(data.height, data.width, CV_16FC4, data.data);
+	}
 	else
 	{
 		mat = ::cv::Mat();
@@ -47,4 +51,13 @@ void voltu::cv::visualise(voltu::ImagePtr img, ::cv::Mat &mat)
 		::cv::applyColorMap(tmp, mat, ::cv::COLORMAP_INFERNO);
 		//#endif
 	}
+	else if (data.format == voltu::ImageFormat::kFloat16_4)
+	{
+		::cv::Mat tmp;
+		voltu::cv::convert(img, tmp);
+		tmp.convertTo(tmp, CV_32FC4);
+		tmp += 1.0f;
+		tmp *= 127.0f;
+		tmp.convertTo(mat, CV_8UC4);
+	}
 }
-- 
GitLab