diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp index 71f790dba0a7f5b8d158019e2a5ac08066bc839f..d8dd66b59323d5ddf5aa0f136f4c25f83213441a 100644 --- a/applications/reconstruct/src/main.cpp +++ b/applications/reconstruct/src/main.cpp @@ -254,8 +254,8 @@ static void run(ftl::Configurable *root) { pipeline1->append<ftl::operators::ColourChannels>("colour"); // Convert BGR to BGRA pipeline1->append<ftl::operators::HFSmoother>("hfnoise"); // Remove high-frequency noise pipeline1->append<ftl::operators::Normals>("normals"); // Estimate surface normals - //pipeline1->append<ftl::operators::SmoothChannel>("smoothing"); // Generate a smoothing channel - pipeline1->append<ftl::operators::ColourMLS>("mls"); // Perform MLS (using smoothing channel) + pipeline1->append<ftl::operators::SmoothChannel>("smoothing"); // Generate a smoothing channel + pipeline1->append<ftl::operators::SimpleMLS>("mls"); // Perform MLS (using smoothing channel) // Alignment diff --git a/components/operators/CMakeLists.txt b/components/operators/CMakeLists.txt index 58e21f43eb785a24d4e7aa77681192b5c5d77d44..c93a87f6693334c30e28039387db45554ebdb0d2 100644 --- a/components/operators/CMakeLists.txt +++ b/components/operators/CMakeLists.txt @@ -1,6 +1,8 @@ add_library(ftloperators src/smoothing.cpp src/smoothing.cu + src/mls.cu + src/smoothchan.cu src/operator.cpp src/colours.cpp src/normals.cpp diff --git a/components/operators/include/ftl/operators/smoothing.hpp b/components/operators/include/ftl/operators/smoothing.hpp index 46bf082bede957b4a32984fe33c467e0fe0be690..a35053d2a97be851ca9afe75938a57b357465a29 100644 --- a/components/operators/include/ftl/operators/smoothing.hpp +++ b/components/operators/include/ftl/operators/smoothing.hpp @@ -63,7 +63,7 @@ class SimpleMLS : public ftl::operators::Operator { /** * Perform Moving Least Squares smoothing with a smoothing amount determined - * by a simple colour similarity weighting. + * by a simple colour similarity weighting. In practice this is too naive. */ class ColourMLS : public ftl::operators::Operator { public: @@ -84,10 +84,10 @@ class ColourMLS : public ftl::operators::Operator { * encompass hundreds of pixels with a smoothing factor approaching a meter, or * it can be only a few or even no pixels with a zero smoothing factor. */ -class DynamicColourMLS : public ftl::operators::Operator { +class AdaptiveMLS : public ftl::operators::Operator { public: - explicit DynamicColourMLS(ftl::Configurable*); - ~DynamicColourMLS(); + explicit AdaptiveMLS(ftl::Configurable*); + ~AdaptiveMLS(); inline Operator::Type type() const override { return Operator::Type::OneToOne; } diff --git a/components/operators/src/mls.cu b/components/operators/src/mls.cu new file mode 100644 index 0000000000000000000000000000000000000000..7e408b829fa39b15ad687ab8246886be3da3ee38 --- /dev/null +++ b/components/operators/src/mls.cu @@ -0,0 +1,208 @@ +#include "smoothing_cuda.hpp" + +#include <ftl/cuda/weighting.hpp> + +using ftl::cuda::TextureObject; + +#define T_PER_BLOCK 8 + +// ===== MLS Smooth ============================================================ + +/* + * Smooth depth map using Moving Least Squares + */ + template <int SEARCH_RADIUS> + __global__ void mls_smooth_kernel( + TextureObject<float4> normals_in, + TextureObject<float4> normals_out, + TextureObject<float> depth_in, // Virtual depth map + TextureObject<float> depth_out, // Accumulated output + float smoothing, + ftl::rgbd::Camera camera) { + + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < 0 || y < 0 || x >= depth_in.width() || y >= depth_in.height()) return; + + float3 aX = make_float3(0.0f,0.0f,0.0f); + float3 nX = make_float3(0.0f,0.0f,0.0f); + float contrib = 0.0f; + + float d0 = depth_in.tex2D(x, y); + depth_out(x,y) = d0; + if (d0 < camera.minDepth || d0 > camera.maxDepth) return; + float3 X = camera.screenToCam((int)(x),(int)(y),d0); + + // Neighbourhood + for (int v=-SEARCH_RADIUS; v<=SEARCH_RADIUS; ++v) { + for (int u=-SEARCH_RADIUS; u<=SEARCH_RADIUS; ++u) { + const float d = depth_in.tex2D(x+u, y+v); + if (d < camera.minDepth || d > camera.maxDepth) continue; + + // Point and normal of neighbour + const float3 Xi = camera.screenToCam((int)(x)+u,(int)(y)+v,d); + const float3 Ni = make_float3(normals_in.tex2D((int)(x)+u, (int)(y)+v)); + + // Gauss approx weighting function using point distance + const float w = ftl::cuda::spatialWeighting(X,Xi,smoothing); + + aX += Xi*w; + nX += Ni*w; + contrib += w; + } + } + + nX /= contrib; // Weighted average normal + aX /= contrib; // Weighted average point (centroid) + + // Signed-Distance Field function + float fX = nX.x * (X.x - aX.x) + nX.y * (X.y - aX.y) + nX.z * (X.z - aX.z); + + // Calculate new point using SDF function to adjust depth (and position) + X = X - nX * fX; + + //uint2 screen = camera.camToScreen<uint2>(X); + + //if (screen.x < depth_out.width() && screen.y < depth_out.height()) { + // depth_out(screen.x,screen.y) = X.z; + //} + depth_out(x,y) = X.z; + normals_out(x,y) = make_float4(nX / length(nX), 0.0f); +} + +void ftl::cuda::mls_smooth( + ftl::cuda::TextureObject<float4> &normals_in, + ftl::cuda::TextureObject<float4> &normals_out, + ftl::cuda::TextureObject<float> &depth_in, + ftl::cuda::TextureObject<float> &depth_out, + float smoothing, + int radius, + const ftl::rgbd::Camera &camera, + cudaStream_t stream) { + + const dim3 gridSize((depth_out.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth_out.height() + T_PER_BLOCK - 1)/T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + switch (radius) { + case 5: mls_smooth_kernel<5><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; + case 4: mls_smooth_kernel<4><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; + case 3: mls_smooth_kernel<3><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; + case 2: mls_smooth_kernel<2><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; + case 1: mls_smooth_kernel<1><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; + } + cudaSafeCall( cudaGetLastError() ); + + + #ifdef _DEBUG + cudaSafeCall(cudaDeviceSynchronize()); + #endif +} + + +// ===== Colour MLS Smooth ===================================================== + +/* + * Smooth depth map using Moving Least Squares. This version uses colour + * similarity weights to adjust the spatial smoothing factor. It is naive in + * that similar colours may exist on both sides of an edge and colours at the + * level of single pixels can be subject to noise. Colour noise should first + * be removed from the image. + */ + template <int SEARCH_RADIUS> + __global__ void colour_mls_smooth_kernel( + TextureObject<float4> normals_in, + TextureObject<float4> normals_out, + TextureObject<float> depth_in, // Virtual depth map + TextureObject<float> depth_out, // Accumulated output + TextureObject<uchar4> colour_in, + float smoothing, + float colour_smoothing, + ftl::rgbd::Camera camera) { + + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < 0 || y < 0 || x >= depth_in.width() || y >= depth_in.height()) return; + + float3 aX = make_float3(0.0f,0.0f,0.0f); + float3 nX = make_float3(0.0f,0.0f,0.0f); + float contrib = 0.0f; + + float d0 = depth_in.tex2D(x, y); + depth_out(x,y) = d0; + if (d0 < camera.minDepth || d0 > camera.maxDepth) return; + float3 X = camera.screenToCam((int)(x),(int)(y),d0); + + uchar4 c0 = colour_in.tex2D(x, y); + + // Neighbourhood + for (int v=-SEARCH_RADIUS; v<=SEARCH_RADIUS; ++v) { + for (int u=-SEARCH_RADIUS; u<=SEARCH_RADIUS; ++u) { + const float d = depth_in.tex2D(x+u, y+v); + if (d < camera.minDepth || d > camera.maxDepth) continue; + + // Point and normal of neighbour + const float3 Xi = camera.screenToCam((int)(x)+u,(int)(y)+v,d); + const float3 Ni = make_float3(normals_in.tex2D((int)(x)+u, (int)(y)+v)); + + const uchar4 c = colour_in.tex2D(x+u, y+v); + const float cw = ftl::cuda::colourWeighting(c0,c,colour_smoothing); + + // Gauss approx weighting function using point distance + const float w = ftl::cuda::spatialWeighting(X,Xi,smoothing*cw); + + aX += Xi*w; + nX += Ni*w; + contrib += w; + } + } + + nX /= contrib; // Weighted average normal + aX /= contrib; // Weighted average point (centroid) + + // Signed-Distance Field function + float fX = nX.x * (X.x - aX.x) + nX.y * (X.y - aX.y) + nX.z * (X.z - aX.z); + + // Calculate new point using SDF function to adjust depth (and position) + X = X - nX * fX; + + //uint2 screen = camera.camToScreen<uint2>(X); + + //if (screen.x < depth_out.width() && screen.y < depth_out.height()) { + // depth_out(screen.x,screen.y) = X.z; + //} + depth_out(x,y) = X.z; + normals_out(x,y) = make_float4(nX / length(nX), 0.0f); +} + +void ftl::cuda::colour_mls_smooth( + ftl::cuda::TextureObject<float4> &normals_in, + ftl::cuda::TextureObject<float4> &normals_out, + ftl::cuda::TextureObject<float> &depth_in, + ftl::cuda::TextureObject<float> &depth_out, + ftl::cuda::TextureObject<uchar4> &colour_in, + float smoothing, + float colour_smoothing, + int radius, + const ftl::rgbd::Camera &camera, + cudaStream_t stream) { + + const dim3 gridSize((depth_out.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth_out.height() + T_PER_BLOCK - 1)/T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + switch (radius) { + case 5: colour_mls_smooth_kernel<5><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; + case 4: colour_mls_smooth_kernel<4><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; + case 3: colour_mls_smooth_kernel<3><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; + case 2: colour_mls_smooth_kernel<2><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; + case 1: colour_mls_smooth_kernel<1><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; + } + cudaSafeCall( cudaGetLastError() ); + + + #ifdef _DEBUG + cudaSafeCall(cudaDeviceSynchronize()); + #endif +} + diff --git a/components/operators/src/smoothchan.cu b/components/operators/src/smoothchan.cu new file mode 100644 index 0000000000000000000000000000000000000000..963fc85ff3bac4d66263ce333882c8584ff6b748 --- /dev/null +++ b/components/operators/src/smoothchan.cu @@ -0,0 +1,68 @@ +#include "smoothing_cuda.hpp" + +#include <ftl/cuda/weighting.hpp> + +using ftl::cuda::TextureObject; + +#define T_PER_BLOCK 8 + +template <int RADIUS> +__global__ void smooth_chan_kernel( + ftl::cuda::TextureObject<uchar4> colour_in, + ftl::cuda::TextureObject<float> depth_in, + ftl::cuda::TextureObject<float> smoothing_out, + ftl::rgbd::Camera camera, + float alpha) { + + const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < smoothing_out.width() && y < smoothing_out.height()) { + const int ix = (float)x / (float)smoothing_out.width() * (float)colour_in.width(); + const int iy = (float)x / (float)smoothing_out.height() * (float)colour_in.height(); + + // A distance has already been found + if (smoothing_out(x,y) < 1.0f) return; + + float mindist = 1.0f; + + const uchar4 c0 = colour_in.tex2D(ix, iy); + const float3 pos = camera.screenToCam(ix, iy, depth_in.tex2D(ix, iy)); + + for (int v=-RADIUS; v<=RADIUS; ++v) { + #pragma unroll + for (int u=-RADIUS; u<=RADIUS; ++u) { + const uchar4 c = colour_in.tex2D(ix+u, iy+v); + const float3 posN = camera.screenToCam(ix+u, iy+v, depth_in.tex2D(ix+u, iy+v)); + + if (ftl::cuda::colourDistance(c, c0) >= alpha) mindist = min(mindist, length(pos - posN)); + } + } + + smoothing_out(x,y) = min(mindist, 1.0f); + } +} + +void ftl::cuda::smooth_channel( + ftl::cuda::TextureObject<uchar4> &colour_in, + ftl::cuda::TextureObject<float> &depth_in, + ftl::cuda::TextureObject<float> &smoothing_out, + const ftl::rgbd::Camera &camera, + float alpha, + int radius, + cudaStream_t stream) { + + const dim3 gridSize((smoothing_out.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (smoothing_out.height() + T_PER_BLOCK - 1)/T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + + smooth_chan_kernel<1><<<gridSize, blockSize, 0, stream>>>(colour_in, depth_in, smoothing_out, camera, alpha); + + + cudaSafeCall( cudaGetLastError() ); + + + #ifdef _DEBUG + cudaSafeCall(cudaDeviceSynchronize()); + #endif +} diff --git a/components/operators/src/smoothing.cpp b/components/operators/src/smoothing.cpp index 26fed4d17c65bf20faaa8240dff5bda860aea9ed..284658e8633362ebd7a17096e6cf874de47e5b9e 100644 --- a/components/operators/src/smoothing.cpp +++ b/components/operators/src/smoothing.cpp @@ -70,7 +70,23 @@ SmoothChannel::~SmoothChannel() { } bool SmoothChannel::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgbd::Source *s, cudaStream_t stream) { - + int radius = config()->value("radius", 1); + float threshold = config()->value("threshold", 30.0f); + + // Clear to max smoothing + out.get<GpuMat>(Channel::Smoothing).setTo(cv::Scalar(1.0f)); + + // Reduce to nearest + ftl::cuda::smooth_channel( + in.createTexture<uchar4>(Channel::Colour), + in.createTexture<float>(Channel::Depth), + out.createTexture<float>(Channel::Smoothing), + s->parameters(), + threshold, + radius, + stream + ); + return true; } diff --git a/components/operators/src/smoothing.cu b/components/operators/src/smoothing.cu index 288e1ed2977f591520a2296cc7857f7bd5c372a0..a2b7377fba011243c08cf5347f3dea4800b8ab51 100644 --- a/components/operators/src/smoothing.cu +++ b/components/operators/src/smoothing.cu @@ -6,202 +6,6 @@ using ftl::cuda::TextureObject; #define T_PER_BLOCK 8 -// ===== MLS Smooth ============================================================ - -/* - * Smooth depth map using Moving Least Squares - */ - template <int SEARCH_RADIUS> - __global__ void mls_smooth_kernel( - TextureObject<float4> normals_in, - TextureObject<float4> normals_out, - TextureObject<float> depth_in, // Virtual depth map - TextureObject<float> depth_out, // Accumulated output - float smoothing, - ftl::rgbd::Camera camera) { - - const int x = blockIdx.x*blockDim.x + threadIdx.x; - const int y = blockIdx.y*blockDim.y + threadIdx.y; - - if (x < 0 || y < 0 || x >= depth_in.width() || y >= depth_in.height()) return; - - float3 aX = make_float3(0.0f,0.0f,0.0f); - float3 nX = make_float3(0.0f,0.0f,0.0f); - float contrib = 0.0f; - - float d0 = depth_in.tex2D(x, y); - depth_out(x,y) = d0; - if (d0 < camera.minDepth || d0 > camera.maxDepth) return; - float3 X = camera.screenToCam((int)(x),(int)(y),d0); - - // Neighbourhood - for (int v=-SEARCH_RADIUS; v<=SEARCH_RADIUS; ++v) { - for (int u=-SEARCH_RADIUS; u<=SEARCH_RADIUS; ++u) { - const float d = depth_in.tex2D(x+u, y+v); - if (d < camera.minDepth || d > camera.maxDepth) continue; - - // Point and normal of neighbour - const float3 Xi = camera.screenToCam((int)(x)+u,(int)(y)+v,d); - const float3 Ni = make_float3(normals_in.tex2D((int)(x)+u, (int)(y)+v)); - - // Gauss approx weighting function using point distance - const float w = ftl::cuda::spatialWeighting(X,Xi,smoothing); - - aX += Xi*w; - nX += Ni*w; - contrib += w; - } - } - - nX /= contrib; // Weighted average normal - aX /= contrib; // Weighted average point (centroid) - - // Signed-Distance Field function - float fX = nX.x * (X.x - aX.x) + nX.y * (X.y - aX.y) + nX.z * (X.z - aX.z); - - // Calculate new point using SDF function to adjust depth (and position) - X = X - nX * fX; - - //uint2 screen = camera.camToScreen<uint2>(X); - - //if (screen.x < depth_out.width() && screen.y < depth_out.height()) { - // depth_out(screen.x,screen.y) = X.z; - //} - depth_out(x,y) = X.z; - normals_out(x,y) = make_float4(nX / length(nX), 0.0f); -} - -void ftl::cuda::mls_smooth( - ftl::cuda::TextureObject<float4> &normals_in, - ftl::cuda::TextureObject<float4> &normals_out, - ftl::cuda::TextureObject<float> &depth_in, - ftl::cuda::TextureObject<float> &depth_out, - float smoothing, - int radius, - const ftl::rgbd::Camera &camera, - cudaStream_t stream) { - - const dim3 gridSize((depth_out.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth_out.height() + T_PER_BLOCK - 1)/T_PER_BLOCK); - const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); - - switch (radius) { - case 5: mls_smooth_kernel<5><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; - case 4: mls_smooth_kernel<4><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; - case 3: mls_smooth_kernel<3><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; - case 2: mls_smooth_kernel<2><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; - case 1: mls_smooth_kernel<1><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, smoothing, camera); break; - } - cudaSafeCall( cudaGetLastError() ); - - - #ifdef _DEBUG - cudaSafeCall(cudaDeviceSynchronize()); - #endif -} - - -// ===== Colour MLS Smooth ===================================================== - -/* - * Smooth depth map using Moving Least Squares - */ - template <int SEARCH_RADIUS> - __global__ void colour_mls_smooth_kernel( - TextureObject<float4> normals_in, - TextureObject<float4> normals_out, - TextureObject<float> depth_in, // Virtual depth map - TextureObject<float> depth_out, // Accumulated output - TextureObject<uchar4> colour_in, - float smoothing, - float colour_smoothing, - ftl::rgbd::Camera camera) { - - const int x = blockIdx.x*blockDim.x + threadIdx.x; - const int y = blockIdx.y*blockDim.y + threadIdx.y; - - if (x < 0 || y < 0 || x >= depth_in.width() || y >= depth_in.height()) return; - - float3 aX = make_float3(0.0f,0.0f,0.0f); - float3 nX = make_float3(0.0f,0.0f,0.0f); - float contrib = 0.0f; - - float d0 = depth_in.tex2D(x, y); - depth_out(x,y) = d0; - if (d0 < camera.minDepth || d0 > camera.maxDepth) return; - float3 X = camera.screenToCam((int)(x),(int)(y),d0); - - uchar4 c0 = colour_in.tex2D(x, y); - - // Neighbourhood - for (int v=-SEARCH_RADIUS; v<=SEARCH_RADIUS; ++v) { - for (int u=-SEARCH_RADIUS; u<=SEARCH_RADIUS; ++u) { - const float d = depth_in.tex2D(x+u, y+v); - if (d < camera.minDepth || d > camera.maxDepth) continue; - - // Point and normal of neighbour - const float3 Xi = camera.screenToCam((int)(x)+u,(int)(y)+v,d); - const float3 Ni = make_float3(normals_in.tex2D((int)(x)+u, (int)(y)+v)); - - const uchar4 c = colour_in.tex2D(x+u, y+v); - const float cw = ftl::cuda::colourWeighting(c0,c,colour_smoothing); - - // Gauss approx weighting function using point distance - const float w = ftl::cuda::spatialWeighting(X,Xi,smoothing*cw); - - aX += Xi*w; - nX += Ni*w; - contrib += w; - } - } - - nX /= contrib; // Weighted average normal - aX /= contrib; // Weighted average point (centroid) - - // Signed-Distance Field function - float fX = nX.x * (X.x - aX.x) + nX.y * (X.y - aX.y) + nX.z * (X.z - aX.z); - - // Calculate new point using SDF function to adjust depth (and position) - X = X - nX * fX; - - //uint2 screen = camera.camToScreen<uint2>(X); - - //if (screen.x < depth_out.width() && screen.y < depth_out.height()) { - // depth_out(screen.x,screen.y) = X.z; - //} - depth_out(x,y) = X.z; - normals_out(x,y) = make_float4(nX / length(nX), 0.0f); -} - -void ftl::cuda::colour_mls_smooth( - ftl::cuda::TextureObject<float4> &normals_in, - ftl::cuda::TextureObject<float4> &normals_out, - ftl::cuda::TextureObject<float> &depth_in, - ftl::cuda::TextureObject<float> &depth_out, - ftl::cuda::TextureObject<uchar4> &colour_in, - float smoothing, - float colour_smoothing, - int radius, - const ftl::rgbd::Camera &camera, - cudaStream_t stream) { - - const dim3 gridSize((depth_out.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth_out.height() + T_PER_BLOCK - 1)/T_PER_BLOCK); - const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); - - switch (radius) { - case 5: colour_mls_smooth_kernel<5><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; - case 4: colour_mls_smooth_kernel<4><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; - case 3: colour_mls_smooth_kernel<3><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; - case 2: colour_mls_smooth_kernel<2><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; - case 1: colour_mls_smooth_kernel<1><<<gridSize, blockSize, 0, stream>>>(normals_in, normals_out, depth_in, depth_out, colour_in, smoothing, colour_smoothing, camera); break; - } - cudaSafeCall( cudaGetLastError() ); - - - #ifdef _DEBUG - cudaSafeCall(cudaDeviceSynchronize()); - #endif -} - // ===== Colour-based Smooth =================================================== template <int RADIUS> diff --git a/components/operators/src/smoothing_cuda.hpp b/components/operators/src/smoothing_cuda.hpp index f7f87f0508f9e5d16c58d0d089bb589d396ef9c8..dae25e221b1121bbfd02bab732b5c6ba5f465aff 100644 --- a/components/operators/src/smoothing_cuda.hpp +++ b/components/operators/src/smoothing_cuda.hpp @@ -29,6 +29,15 @@ void colour_mls_smooth( const ftl::rgbd::Camera &camera, cudaStream_t stream); +void smooth_channel( + ftl::cuda::TextureObject<uchar4> &colour_in, + ftl::cuda::TextureObject<float> &depth_in, + ftl::cuda::TextureObject<float> &smoothing_out, + const ftl::rgbd::Camera &camera, + float alpha, + int radius, + cudaStream_t stream); + void depth_smooth( ftl::cuda::TextureObject<float> &depth_in, ftl::cuda::TextureObject<uchar4> &colour_in, diff --git a/components/renderers/cpp/include/ftl/cuda/weighting.hpp b/components/renderers/cpp/include/ftl/cuda/weighting.hpp index 15d3dbcec387f97d8ffe60690bdb5c1fda2c098c..bffff673d2009ac698c3c604ec565a2aa1a89901 100644 --- a/components/renderers/cpp/include/ftl/cuda/weighting.hpp +++ b/components/renderers/cpp/include/ftl/cuda/weighting.hpp @@ -25,6 +25,11 @@ __device__ inline float spatialWeighting(const float3 &a, const float3 &b, float return rh*rh*rh*rh; } +__device__ inline float colourDistance(uchar4 a, uchar4 b) { + const float3 delta = make_float3((float)a.x - (float)b.x, (float)a.y - (float)b.y, (float)a.z - (float)b.z); + return length(delta); +} + /* * Colour weighting as suggested in: * C. Kuster et al. Spatio-Temporal Geometry Fusion for Multiple Hybrid Cameras using Moving Least Squares Surfaces. 2014.