diff --git a/SDK/CPP/private/frame_impl.cpp b/SDK/CPP/private/frame_impl.cpp index a91ad3e6a762cf18f9915299df616412e420e2b7..059b508fff3e7e7e3b40877685411ad890f0887f 100644 --- a/SDK/CPP/private/frame_impl.cpp +++ b/SDK/CPP/private/frame_impl.cpp @@ -15,9 +15,9 @@ FrameImpl::~FrameImpl() } -std::list<voltu::ImagePtr> FrameImpl::getImageSet(voltu::Channel c) +std::vector<voltu::ImagePtr> FrameImpl::getImageSet(voltu::Channel c) { - std::list<voltu::ImagePtr> result; + std::vector<voltu::ImagePtr> result; ftl::codecs::Channel channel = ftl::codecs::Channel::Colour; switch (c) diff --git a/SDK/CPP/private/frame_impl.hpp b/SDK/CPP/private/frame_impl.hpp index eb5caa5a65b873cc8f80718a1193051abb8fa26a..38750ce4269b9bdaf67df41ba76f4f07a3d15233 100644 --- a/SDK/CPP/private/frame_impl.hpp +++ b/SDK/CPP/private/frame_impl.hpp @@ -16,7 +16,7 @@ public: FrameImpl(); ~FrameImpl() override; - std::list<voltu::ImagePtr> getImageSet(voltu::Channel) override; + std::vector<voltu::ImagePtr> getImageSet(voltu::Channel) override; voltu::PointCloudPtr getPointCloud(voltu::PointCloudFormat cloudfmt, voltu::PointFormat pointfmt) override; diff --git a/SDK/CPP/public/CMakeLists.txt b/SDK/CPP/public/CMakeLists.txt index f1ea62a4e8a428581f6a4a7f73915d7413ac5c66..e3d1c339a1e7852536c9a88a039a007f93e5cf77 100644 --- a/SDK/CPP/public/CMakeLists.txt +++ b/SDK/CPP/public/CMakeLists.txt @@ -43,6 +43,10 @@ endif() add_library(voltu_sdk STATIC ${VOLTU_SRCS}) +if (WITH_OPENCV) + target_compile_definitions(voltu_sdk PUBLIC WITH_OPENCV) +endif() + target_include_directories(voltu_sdk PUBLIC include) target_link_libraries(voltu_sdk ${OS_LIBS} Threads::Threads ${OPTIONAL_DEPENDENCIES} Eigen3::Eigen) diff --git a/SDK/CPP/public/include/voltu/cuda.hpp b/SDK/CPP/public/include/voltu/cuda.hpp new file mode 100644 index 0000000000000000000000000000000000000000..972f4964b839db3db3793d117e5fb80c0c7702ae --- /dev/null +++ b/SDK/CPP/public/include/voltu/cuda.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include <voltu/types/image.hpp> +#include +#include <memory> + +namespace voltu +{ + +/** + * @brief CUDA Processing Stream. + * + * An instance of this class is mapped to a single CUDA stream, so any of the + * available operations will occur within that stream. It is therefore + * necessary to call `waitCompletion` after all steps have been finished. + */ +class CUDAProc +{ +public: + virtual bool waitCompletion(int timeout, bool except=false) = 0; + + virtual void* getInternalStream() = 0; + + virtual void visualiseDepthEnhancement(const voltu::ImagePtr >, const voltu::ImagePtr &depth_old, const voltu::ImagePtr &depth_new, const voltu::ImagePtr &colour) = 0; +}; + +} diff --git a/SDK/CPP/public/include/voltu/opencv.hpp b/SDK/CPP/public/include/voltu/opencv.hpp index 7119cbc87097ce1609a7e93696059db38b7097e3..1e8e858ab0eef22dfccc892f0a1b2124056f482e 100644 --- a/SDK/CPP/public/include/voltu/opencv.hpp +++ b/SDK/CPP/public/include/voltu/opencv.hpp @@ -7,19 +7,29 @@ #pragma once #include <opencv2/core/mat.hpp> -#include <opencv2/core/cuda_types.hpp> +#include <opencv2/core/cuda.hpp> #include <voltu/types/image.hpp> namespace voltu { -namespace cv +namespace opencv { void convert(voltu::ImagePtr img, ::cv::Mat &mat); void convert(voltu::ImagePtr img, ::cv::cuda::GpuMat &mat); +::cv::cuda::GpuMat toGpuMat(voltu::ImagePtr img); + void visualise(voltu::ImagePtr img, ::cv::Mat &mat); } + +struct GpuUtilities +{ + void (*visualiseDepthEnhancement)(const voltu::ImagePtr >, const voltu::ImagePtr &depth_old, const voltu::ImagePtr &depth_new, const voltu::ImagePtr &colour) = nullptr; +}; + +extern GpuUtilities gpu; + } \ No newline at end of file diff --git a/SDK/CPP/public/include/voltu/system.hpp b/SDK/CPP/public/include/voltu/system.hpp index 8fb9c744cdf3c7646531803f349aeb7455962c12..df7b4938ebd8103903b852f962fa6c23c1f5d255 100644 --- a/SDK/CPP/public/include/voltu/system.hpp +++ b/SDK/CPP/public/include/voltu/system.hpp @@ -78,7 +78,7 @@ public: * Identifiers (URIs), with some non-standard additions. A few examples * are: * * `file:///home/user/file.ftl` - * * `tcp://localhost:9001/*` + * * `tcp://localhost:9001/` * * `ftl://my.stream.name/room1` * * `ws://ftlab.utu.fi/lab/` * * `./file.ftl` diff --git a/SDK/CPP/public/include/voltu/types/frame.hpp b/SDK/CPP/public/include/voltu/types/frame.hpp index 30b7c4ddcf26c22256700311457abaf6755b8ef6..7f03fc6045ec8a378fb9feb174e956c59cc4adff 100644 --- a/SDK/CPP/public/include/voltu/types/frame.hpp +++ b/SDK/CPP/public/include/voltu/types/frame.hpp @@ -22,7 +22,7 @@ class Frame public: virtual ~Frame() = default; - PY_API PY_RV_LIFETIME_PARENT virtual std::list<voltu::ImagePtr> getImageSet(voltu::Channel channel) = 0; + PY_API PY_RV_LIFETIME_PARENT virtual std::vector<voltu::ImagePtr> getImageSet(voltu::Channel channel) = 0; PY_API PY_RV_LIFETIME_PARENT virtual voltu::PointCloudPtr getPointCloud(voltu::PointCloudFormat cloudfmt, voltu::PointFormat pointfmt) = 0; diff --git a/SDK/CPP/public/samples/basic_file/main.cpp b/SDK/CPP/public/samples/basic_file/main.cpp index c983864275a217fc1d2cc6628012dc698f8ad19e..9af26c1c0859e609aaabf687dfeb119e9f625f80 100644 --- a/SDK/CPP/public/samples/basic_file/main.cpp +++ b/SDK/CPP/public/samples/basic_file/main.cpp @@ -45,7 +45,7 @@ int main(int argc, char **argv) for (auto img : imgset) { cv::Mat m; - voltu::cv::visualise(img, m); + voltu::opencv::visualise(img, m); cv::imshow(string("Image-") + img->getName(), m); } diff --git a/SDK/CPP/public/samples/basic_virtual_cam/main.cpp b/SDK/CPP/public/samples/basic_virtual_cam/main.cpp index f1b2634b7135bfb3c303fdd6fd54e81da6a69a38..47dea0583709dbf339e32ca7e96f2eee8e7e78db 100644 --- a/SDK/CPP/public/samples/basic_virtual_cam/main.cpp +++ b/SDK/CPP/public/samples/basic_virtual_cam/main.cpp @@ -69,7 +69,7 @@ int main(int argc, char **argv) for (auto img : imgset) { cv::Mat m; - voltu::cv::convert(img, m); + voltu::opencv::convert(img, m); cv::imshow(string("Camera-") + img->getName(), m); } diff --git a/SDK/CPP/public/samples/fusion_evaluator/main.cpp b/SDK/CPP/public/samples/fusion_evaluator/main.cpp index c4073baf4044d72a1346876047f8cfad317a7a06..f9b96468c292883118559a1542ca0b833d4a0e20 100644 --- a/SDK/CPP/public/samples/fusion_evaluator/main.cpp +++ b/SDK/CPP/public/samples/fusion_evaluator/main.cpp @@ -107,6 +107,10 @@ int main(int argc, char **argv) op1->property("visibility_carving")->setBool(do_carving); op1->property("mls_iterations")->setInt(iters); + cv::Mat old_depth; + auto oldimgset = frame->getImageSet(voltu::Channel::kDepth); + voltu::opencv::toGpuMat(oldimgset[sourceno]).download(old_depth); + pipe->submit(frame); pipe->waitCompletion(3000, true); @@ -123,7 +127,8 @@ int main(int argc, char **argv) { if (srccount++ < sourceno) continue; cv::Mat m; - voltu::cv::visualise(img, m); + voltu::opencv::toGpuMat(img).download(m); + voltu::opencv::visualise(img, m); cv::imshow(string("Image-") + img->getName(), m); break; } diff --git a/SDK/CPP/public/voltu.cpp b/SDK/CPP/public/voltu.cpp index 2c4d19712428be34af7d8fd04c93a7c615fdec7b..d558ff7b0897ab96cb58b55e115a21ebe42980d3 100644 --- a/SDK/CPP/public/voltu.cpp +++ b/SDK/CPP/public/voltu.cpp @@ -8,6 +8,10 @@ #include <voltu/types/errors.hpp> #include <voltu/voltu.hpp> +#ifdef WITH_OPENCV +#include <voltu/opencv.hpp> +#endif + #if defined(WIN32) #include <windows.h> #pragma comment(lib, "User32.lib") @@ -23,6 +27,10 @@ static bool g_init = false; +#ifdef WITH_OPENCV +voltu::GpuUtilities voltu::gpu; +#endif + typedef void* Library; static Library loadLibrary(const char *file) @@ -132,6 +140,18 @@ std::shared_ptr<voltu::System> voltu::instance() throw voltu::exceptions::RuntimeVersionMismatch(); } +#ifdef WITH_OPENCV + auto gpuinit = (voltu::GpuUtilities* (*)())getFunction(handle, "voltu_utilities_gpu"); + if (gpuinit) + { + gpu = *gpuinit(); + } + else + { + //throw voltu::exceptions::LibraryLoadFailed(); + } +#endif + return instance; } else diff --git a/SDK/CPP/public/voltu_cv.cpp b/SDK/CPP/public/voltu_cv.cpp index e9951dc37959b0ea89b22c1d2f6432690619f4ef..5e55e79086a96dc599d209944f5c3ccff9170776 100644 --- a/SDK/CPP/public/voltu_cv.cpp +++ b/SDK/CPP/public/voltu_cv.cpp @@ -9,7 +9,7 @@ #include <opencv2/imgproc.hpp> -void voltu::cv::convert(voltu::ImagePtr img, ::cv::Mat &mat) +void voltu::opencv::convert(voltu::ImagePtr img, ::cv::Mat &mat) { voltu::ImageData data = img->getHost(); @@ -31,23 +31,44 @@ void voltu::cv::convert(voltu::ImagePtr img, ::cv::Mat &mat) } } -void voltu::cv::convert(voltu::ImagePtr img, ::cv::cuda::GpuMat &mat) +void voltu::opencv::convert(voltu::ImagePtr img, ::cv::cuda::GpuMat &mat) { + mat = voltu::opencv::toGpuMat(img); +} + +cv::cuda::GpuMat voltu::opencv::toGpuMat(voltu::ImagePtr img) +{ + voltu::ImageData data = img->getDevice(); + + if (data.format == voltu::ImageFormat::kBGRA8) + { + + } + else if (data.format == voltu::ImageFormat::kFloat32) + { + return ::cv::cuda::GpuMat( + data.height, + data.width, + CV_32F, + data.data + ); + } + throw voltu::exceptions::NotImplemented(); } -void voltu::cv::visualise(voltu::ImagePtr img, ::cv::Mat &mat) +void voltu::opencv::visualise(voltu::ImagePtr img, ::cv::Mat &mat) { voltu::ImageData data = img->getHost(); if (data.format == voltu::ImageFormat::kBGRA8) { - voltu::cv::convert(img, mat); + voltu::opencv::convert(img, mat); } else if (data.format == voltu::ImageFormat::kFloat32) { ::cv::Mat tmp; - voltu::cv::convert(img, tmp); + voltu::opencv::convert(img, tmp); float maxdepth = 8.0f; // TODO: Get from intrinsics @@ -65,7 +86,7 @@ void voltu::cv::visualise(voltu::ImagePtr img, ::cv::Mat &mat) else if (data.format == voltu::ImageFormat::kFloat16_4) { ::cv::Mat tmp; - voltu::cv::convert(img, tmp); + voltu::opencv::convert(img, tmp); tmp.convertTo(tmp, CV_32FC4); tmp += 1.0f; tmp *= 127.0f;