From 7aa42052c1644dea7f486a8a151cc91d3be5c2a1 Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Sun, 21 Jul 2019 09:46:08 +0300 Subject: [PATCH] Tidy params, add normal alloc --- .../reconstruct/include/ftl/depth_camera.hpp | 21 ++++++- .../include/ftl/voxel_hash_params.hpp | 19 +------ applications/reconstruct/src/integrators.cu | 57 ++++++------------- .../reconstruct/src/scene_rep_hash_sdf.cu | 35 ------------ applications/reconstruct/src/voxel_scene.cpp | 36 ++++-------- 5 files changed, 52 insertions(+), 116 deletions(-) diff --git a/applications/reconstruct/include/ftl/depth_camera.hpp b/applications/reconstruct/include/ftl/depth_camera.hpp index f40581b65..7553f8aa8 100644 --- a/applications/reconstruct/include/ftl/depth_camera.hpp +++ b/applications/reconstruct/include/ftl/depth_camera.hpp @@ -24,6 +24,7 @@ namespace voxhash { struct __align__(16) DepthCameraCUDA { cudaTextureObject_t depth; cudaTextureObject_t colour; + cudaTextureObject_t normal; DepthCameraParams params; float4x4 pose; float4x4 poseInverse; @@ -44,12 +45,15 @@ struct DepthCamera { depth_mat_ = nullptr; colour_mat_ = nullptr; + point_mat_ = nullptr; + normal_mat_ = nullptr; depth_tex_ = nullptr; colour_tex_ = nullptr; + normal_tex_ = nullptr; } __host__ - void alloc(const DepthCameraParams& params) { //! todo resizing??? + void alloc(const DepthCameraParams& params, bool withNormals=false) { //! todo resizing??? depth_mat_ = new cv::cuda::GpuMat(params.m_imageHeight, params.m_imageWidth, CV_32FC1); colour_mat_ = new cv::cuda::GpuMat(params.m_imageHeight, params.m_imageWidth, CV_8UC4); depth_tex_ = new ftl::cuda::TextureObject<float>((cv::cuda::PtrStepSz<float>)*depth_mat_); @@ -57,6 +61,15 @@ struct DepthCamera { data.depth = depth_tex_->cudaTexture(); data.colour = colour_tex_->cudaTexture(); data.params = params; + + if (withNormals) { + point_mat_ = new cv::cuda::GpuMat(params.m_imageHeight, params.m_imageWidth, CV_32FC3); + normal_mat_ = new cv::cuda::GpuMat(params.m_imageHeight, params.m_imageWidth, CV_32FC4); + normal_tex_ = new ftl::cuda::TextureObject<float4>((cv::cuda::PtrStepSz<float4>)*normal_mat_); + data.normal = normal_tex_->cudaTexture(); + } else { + data.normal = 0; + } } //__host__ @@ -74,16 +87,22 @@ struct DepthCamera { void free() { if (depth_mat_) delete depth_mat_; if (colour_mat_) delete colour_mat_; + if (point_mat_) delete point_mat_; + if (normal_mat_) delete normal_mat_; delete depth_tex_; delete colour_tex_; + if (normal_tex_) delete normal_tex_; } // TODO(Nick) Should not need to pass all these pointers to device cv::cuda::GpuMat *depth_mat_; cv::cuda::GpuMat *colour_mat_; + cv::cuda::GpuMat *point_mat_; + cv::cuda::GpuMat *normal_mat_; ftl::cuda::TextureObject<float> *depth_tex_; ftl::cuda::TextureObject<uchar4> *colour_tex_; + ftl::cuda::TextureObject<float4> *normal_tex_; //cudaTextureObject_t depth_obj_; //cudaTextureObject_t colour_obj_; diff --git a/applications/reconstruct/include/ftl/voxel_hash_params.hpp b/applications/reconstruct/include/ftl/voxel_hash_params.hpp index cb94404c3..aa19368ea 100644 --- a/applications/reconstruct/include/ftl/voxel_hash_params.hpp +++ b/applications/reconstruct/include/ftl/voxel_hash_params.hpp @@ -17,30 +17,17 @@ struct __align__(16) HashParams { HashParams() { } - float4x4 m_rigidTransform; - float4x4 m_rigidTransformInverse; - unsigned int m_hashNumBuckets; - unsigned int m_deprecated1; - unsigned int m_deprecated2; //m_hashMaxCollisionLinkedListSize; - unsigned int m_numSDFBlocks; - - int m_SDFBlockSize; float m_virtualVoxelSize; - unsigned int m_numOccupiedBlocks; //occupied blocks in the viewing frustum - float m_maxIntegrationDistance; float m_truncScale; float m_truncation; unsigned int m_integrationWeightSample; unsigned int m_integrationWeightMax; - float3 m_streamingVoxelExtents; - int3 m_streamingGridDimensions; - int3 m_streamingMinGridPos; - unsigned int m_streamingInitialChunkListSize; - uint2 m_dummy; - + float3 m_minBounds; + float3 m_maxBounds; + float m_spatialSmoothing; }; } // namespace voxhash diff --git a/applications/reconstruct/src/integrators.cu b/applications/reconstruct/src/integrators.cu index 1259210b4..ce51c185d 100644 --- a/applications/reconstruct/src/integrators.cu +++ b/applications/reconstruct/src/integrators.cu @@ -7,6 +7,8 @@ #include <ftl/cuda_common.hpp> #define T_PER_BLOCK 8 +#define NUM_CUDA_BLOCKS 10000 +#define WARP_SIZE 32 using ftl::voxhash::HashData; using ftl::voxhash::HashParams; @@ -15,45 +17,13 @@ using ftl::voxhash::HashEntry; using ftl::voxhash::HashEntryHead; using ftl::voxhash::FREE_ENTRY; +extern __constant__ ftl::voxhash::DepthCameraCUDA c_cameras[MAX_CAMERAS]; +extern __constant__ HashParams c_hashParams; + __device__ float4 make_float4(uchar4 c) { return make_float4(static_cast<float>(c.x), static_cast<float>(c.y), static_cast<float>(c.z), static_cast<float>(c.w)); } -inline __device__ uchar4 bilinearFilterColor(const DepthCameraParams& cameraParams, const float2& screenPos, cudaTextureObject_t colorTextureRef) { - //const DepthCameraParams& cameraParams = c_depthCameraParams; - const int imageWidth = cameraParams.m_imageWidth; - const int imageHeight = cameraParams.m_imageHeight; - const int2 p00 = make_int2(screenPos.x+0.5f, screenPos.y+0.5f); - const int2 dir = sign(make_float2(screenPos.x - p00.x, screenPos.y - p00.y)); - - const int2 p01 = p00 + make_int2(0.0f, dir.y); - const int2 p10 = p00 + make_int2(dir.x, 0.0f); - const int2 p11 = p00 + make_int2(dir.x, dir.y); - - const float alpha = (screenPos.x - p00.x)*dir.x; - const float beta = (screenPos.y - p00.y)*dir.y; - - float4 s0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float w0 = 0.0f; - if(p00.x >= 0 && p00.x < imageWidth && p00.y >= 0 && p00.y < imageHeight) { uchar4 v00 = tex2D<uchar4>(colorTextureRef, p00.x, p00.y); if(v00.x != 0) { s0 += (1.0f-alpha)*make_float4(v00); w0 += (1.0f-alpha); } } - if(p10.x >= 0 && p10.x < imageWidth && p10.y >= 0 && p10.y < imageHeight) { uchar4 v10 = tex2D<uchar4>(colorTextureRef, p10.x, p10.y); if(v10.x != 0) { s0 += alpha *make_float4(v10); w0 += alpha ; } } - - float4 s1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float w1 = 0.0f; - if(p01.x >= 0 && p01.x < imageWidth && p01.y >= 0 && p01.y < imageHeight) { uchar4 v01 = tex2D<uchar4>(colorTextureRef, p01.x, p01.y); if(v01.x != 0) { s1 += (1.0f-alpha)*make_float4(v01); w1 += (1.0f-alpha);} } - if(p11.x >= 0 && p11.x < imageWidth && p11.y >= 0 && p11.y < imageHeight) { uchar4 v11 = tex2D<uchar4>(colorTextureRef, p11.x, p11.y); if(v11.x != 0) { s1 += alpha *make_float4(v11); w1 += alpha ;} } - - const float4 p0 = s0/w0; - const float4 p1 = s1/w1; - - float4 ss = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float ww = 0.0f; - if(w0 > 0.0f) { ss += (1.0f-beta)*p0; ww += (1.0f-beta); } - if(w1 > 0.0f) { ss += beta *p1; ww += beta ; } - - if(ww > 0.0f) { - ss /= ww; - return make_uchar4(ss.x,ss.y,ss.z,ss.w); - } else return make_uchar4(0, 0, 0, 0); -} - __device__ float colourDistance(const uchar4 &c1, const uchar3 &c2) { float x = c1.x-c2.x; float y = c1.y-c2.y; @@ -69,7 +39,17 @@ __device__ bool colordiff(const uchar4 &pa, const uchar3 &pb, float epsilon) { return sqrt(x_2 - p_2) < epsilon; } -#define NUM_CUDA_BLOCKS 10000 +/* + * Guennebaud, G.; Gross, M. Algebraic point set surfaces. ACMTransactions on Graphics Vol. 26, No. 3, Article No. 23, 2007. + * Used in: FusionMLS: Highly dynamic 3D reconstruction with consumer-grade RGB-D cameras + */ +__device__ float spatialWeighting(float r) { + const float h = c_hashParams.m_spatialSmoothing; + float rh = r / h; + rh = 1.0f - rh*rh; + rh = rh*rh*rh*rh; + return (rh < h) ? rh : 0.0f; +} @@ -141,10 +121,6 @@ __device__ bool colordiff(const uchar4 &pa, const uchar3 &pb, float epsilon) { } // Stride loop }*/ -extern __constant__ ftl::voxhash::DepthCameraCUDA c_cameras[MAX_CAMERAS]; - -#define WARP_SIZE 32 - __global__ void integrateDepthMapsKernel(HashData hashData, HashParams hashParams, int numcams) { __shared__ uint all_warp_ballot; __shared__ uint voxels[16]; @@ -254,6 +230,7 @@ __global__ void integrateDepthMapsKernel(HashData hashData, HashParams hashParam __syncthreads(); // Work out if block is occupied or not and save voxel masks + // TODO:(Nick) Is it faster to do this in a separate garbage kernel? if (i < 16) { const uint v = voxels[i]; hashData.d_hashCompactified[bi]->voxels[i] = v; diff --git a/applications/reconstruct/src/scene_rep_hash_sdf.cu b/applications/reconstruct/src/scene_rep_hash_sdf.cu index 5c5ebf6fd..927e22eed 100644 --- a/applications/reconstruct/src/scene_rep_hash_sdf.cu +++ b/applications/reconstruct/src/scene_rep_hash_sdf.cu @@ -168,41 +168,6 @@ extern "C" void resetHashBucketMutexCUDA(HashData& hashData, const HashParams& h } -__device__ -unsigned int linearizeChunkPos(const int3& chunkPos) -{ - int3 p = chunkPos-c_hashParams.m_streamingMinGridPos; - return p.z * c_hashParams.m_streamingGridDimensions.x * c_hashParams.m_streamingGridDimensions.y + - p.y * c_hashParams.m_streamingGridDimensions.x + - p.x; -} - -__device__ -int3 worldToChunks(const float3& posWorld) -{ - float3 p; - p.x = posWorld.x/c_hashParams.m_streamingVoxelExtents.x; - p.y = posWorld.y/c_hashParams.m_streamingVoxelExtents.y; - p.z = posWorld.z/c_hashParams.m_streamingVoxelExtents.z; - - float3 s; - s.x = (float)sign(p.x); - s.y = (float)sign(p.y); - s.z = (float)sign(p.z); - - return make_int3(p+s*0.5f); -} - -__device__ -bool isSDFBlockStreamedOut(const int3& sdfBlock, const HashData& hashData, const unsigned int* d_bitMask) //TODO MATTHIAS (-> move to HashData) -{ - float3 posWorld = hashData.virtualVoxelPosToWorld(hashData.SDFBlockToVirtualVoxelPos(sdfBlock)); // sdfBlock is assigned to chunk by the bottom right sample pos - - uint index = linearizeChunkPos(worldToChunks(posWorld)); - uint nBitsInT = 32; - return ((d_bitMask[index/nBitsInT] & (0x1 << (index%nBitsInT))) != 0x0); -} - // Note: bitMask used for Streaming out code... could be set to nullptr if not streaming out // Note: Allocations might need to be around fat rays since multiple voxels could correspond // to same depth map pixel at larger distances. diff --git a/applications/reconstruct/src/voxel_scene.cpp b/applications/reconstruct/src/voxel_scene.cpp index 51f9bc75b..861e480e2 100644 --- a/applications/reconstruct/src/voxel_scene.cpp +++ b/applications/reconstruct/src/voxel_scene.cpp @@ -138,7 +138,7 @@ int SceneRep::upload() { cam.params.m_imageHeight = in->parameters().height; cam.params.m_sensorDepthWorldMax = in->parameters().maxDepth; cam.params.m_sensorDepthWorldMin = in->parameters().minDepth; - cam.gpu.alloc(cam.params); + cam.gpu.alloc(cam.params, true); } } @@ -179,6 +179,8 @@ int SceneRep::upload() { //allocate all hash blocks which are corresponding to depth map entries _alloc(i, cv::cuda::StreamAccessor::getStream(cam.stream)); + + // Calculate normals } // Must have finished all allocations and rendering before next integration @@ -237,21 +239,11 @@ void SceneRep::garbage() { m_numIntegratedFrames++; }*/ -void SceneRep::setLastRigidTransform(const Eigen::Matrix4f& lastRigidTransform) { - m_hashParams.m_rigidTransform = MatrixConversion::toCUDA(lastRigidTransform); - m_hashParams.m_rigidTransformInverse = MatrixConversion::toCUDA(lastRigidTransform.inverse()); //m_hashParams.m_rigidTransform.getInverse(); -} - /*void SceneRep::setLastRigidTransformAndCompactify(const Eigen::Matrix4f& lastRigidTransform, const DepthCameraData& depthCameraData) { setLastRigidTransform(lastRigidTransform); _compactifyHashEntries(); }*/ - -const Eigen::Matrix4f SceneRep::getLastRigidTransform() const { - return MatrixConversion::toEigen(m_hashParams.m_rigidTransform); -} - /* Nick: To reduce weights between frames */ void SceneRep::nextFrame() { if (do_reset_) { @@ -269,10 +261,6 @@ void SceneRep::nextFrame() { //! resets the hash to the initial state (i.e., clears all data) void SceneRep::reset() { m_numIntegratedFrames = 0; - - //m_hashParams.m_rigidTransform.setIdentity(); - //m_hashParams.m_rigidTransformInverse.setIdentity(); - m_hashParams.m_numOccupiedBlocks = 0; m_hashData.updateParams(m_hashParams); resetCUDA(m_hashData, m_hashParams); } @@ -288,22 +276,22 @@ HashParams SceneRep::_parametersFromConfig() { HashParams params; // First camera view is set to identity pose to be at the centre of // the virtual coordinate space. - params.m_rigidTransform.setIdentity(); - params.m_rigidTransformInverse.setIdentity(); params.m_hashNumBuckets = value("hashNumBuckets", 100000); - params.m_SDFBlockSize = SDF_BLOCK_SIZE; - params.m_numSDFBlocks = value("hashNumSDFBlocks",500000); params.m_virtualVoxelSize = value("SDFVoxelSize", 0.006f); params.m_maxIntegrationDistance = value("SDFMaxIntegrationDistance", 10.0f); params.m_truncation = value("SDFTruncation", 0.1f); params.m_truncScale = value("SDFTruncationScale", 0.01f); params.m_integrationWeightSample = value("SDFIntegrationWeightSample", 10); params.m_integrationWeightMax = value("SDFIntegrationWeightMax", 255); - // Note (Nick): We are not streaming voxels in/out of GPU - //params.m_streamingVoxelExtents = MatrixConversion::toCUDA(gas.s_streamingVoxelExtents); - //params.m_streamingGridDimensions = MatrixConversion::toCUDA(gas.s_streamingGridDimensions); - //params.m_streamingMinGridPos = MatrixConversion::toCUDA(gas.s_streamingMinGridPos); - //params.m_streamingInitialChunkListSize = gas.s_streamingInitialChunkListSize; + params.m_spatialSmoothing = value("spatialSmoothing", 0.04f); // 4cm + params.m_maxBounds = make_float3( + value("bbox_x_max", 2.0f), + value("bbox_y_max", 2.0f), + value("bbox_z_max", 2.0f)); + params.m_minBounds = make_float3( + value("bbox_x_min", -2.0f), + value("bbox_y_min", -2.0f), + value("bbox_z_min", -2.0f)); return params; } -- GitLab