Skip to content

Commit a1d8730

Browse files
savuoralalek
authored andcommitted
Merge pull request #2133 from savuor:kinfu_truncate
KinectFusion: several updates (#2133) * truncateThreshold added * demo updated for RealSense * first Kinect2, then RealSense * more distance-based parameters
1 parent b6e2867 commit a1d8730

File tree

6 files changed

+117
-35
lines changed

6 files changed

+117
-35
lines changed

modules/rgbd/include/opencv2/rgbd/kinfu.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,11 @@ struct CV_EXPORTS_W Params
102102
/** number of ICP iterations for each pyramid level */
103103
CV_PROP std::vector<int> icpIterations;
104104

105-
// depth truncation is not used by default
106-
// float icp_truncate_depth_dist; //meters
105+
/** @brief Threshold for depth truncation in meters
106+
107+
All depth values beyond this threshold will be set to zero
108+
*/
109+
CV_PROP_RW float truncateThreshold;
107110
};
108111

109112
/** @brief KinectFusion implementation

modules/rgbd/samples/kinfu_demo.cpp

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ namespace Kinect2Params
9595
struct DepthSource
9696
{
9797
public:
98+
enum Type
99+
{
100+
DEPTH_LIST,
101+
DEPTH_KINECT2_LIST,
102+
DEPTH_KINECT2,
103+
DEPTH_REALSENSE
104+
};
105+
98106
DepthSource(int cam) :
99107
DepthSource("", cam)
100108
{ }
@@ -106,11 +114,31 @@ struct DepthSource
106114
DepthSource(String fileListName, int cam) :
107115
depthFileList(fileListName.empty() ? vector<string>() : readDepth(fileListName)),
108116
frameIdx(0),
109-
vc( cam >= 0 ? VideoCapture(VideoCaptureAPIs::CAP_OPENNI2 + cam) : VideoCapture()),
110117
undistortMap1(),
111-
undistortMap2(),
112-
useKinect2Workarounds(true)
113-
{ }
118+
undistortMap2()
119+
{
120+
if(cam >= 0)
121+
{
122+
vc = VideoCapture(VideoCaptureAPIs::CAP_OPENNI2 + cam);
123+
if(vc.isOpened())
124+
{
125+
sourceType = Type::DEPTH_KINECT2;
126+
}
127+
else
128+
{
129+
vc = VideoCapture(VideoCaptureAPIs::CAP_REALSENSE + cam);
130+
if(vc.isOpened())
131+
{
132+
sourceType = Type::DEPTH_REALSENSE;
133+
}
134+
}
135+
}
136+
else
137+
{
138+
vc = VideoCapture();
139+
sourceType = Type::DEPTH_KINECT2_LIST;
140+
}
141+
}
114142

115143
UMat getDepth()
116144
{
@@ -130,10 +158,21 @@ struct DepthSource
130158
else
131159
{
132160
vc.grab();
133-
vc.retrieve(out, CAP_OPENNI_DEPTH_MAP);
161+
switch (sourceType)
162+
{
163+
case Type::DEPTH_KINECT2:
164+
vc.retrieve(out, CAP_OPENNI_DEPTH_MAP);
165+
break;
166+
case Type::DEPTH_REALSENSE:
167+
vc.retrieve(out, CAP_INTELPERC_DEPTH_MAP);
168+
break;
169+
default:
170+
// unknown depth source
171+
vc.retrieve(out);
172+
}
134173

135174
// workaround for Kinect 2
136-
if(useKinect2Workarounds)
175+
if(sourceType == Type::DEPTH_KINECT2)
137176
{
138177
out = out(Rect(Point(), Kinect2Params::frameSize));
139178

@@ -163,12 +202,11 @@ struct DepthSource
163202
int w = (int)vc.get(VideoCaptureProperties::CAP_PROP_FRAME_WIDTH);
164203
int h = (int)vc.get(VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT);
165204

166-
float focal = (float)vc.get(CAP_OPENNI_DEPTH_GENERATOR | CAP_PROP_OPENNI_FOCAL_LENGTH);
167-
168205
// it's recommended to calibrate sensor to obtain its intrinsics
169206
float fx, fy, cx, cy;
207+
float depthFactor = 1000.f;
170208
Size frameSize;
171-
if(useKinect2Workarounds)
209+
if(sourceType == Type::DEPTH_KINECT2)
172210
{
173211
fx = fy = Kinect2Params::focal;
174212
cx = Kinect2Params::cx;
@@ -178,7 +216,17 @@ struct DepthSource
178216
}
179217
else
180218
{
181-
fx = fy = focal;
219+
if(sourceType == Type::DEPTH_REALSENSE)
220+
{
221+
fx = (float)vc.get(CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ);
222+
fy = (float)vc.get(CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT);
223+
depthFactor = 1.f/(float)vc.get(CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE);
224+
}
225+
else
226+
{
227+
fx = fy = (float)vc.get(CAP_OPENNI_DEPTH_GENERATOR | CAP_PROP_OPENNI_FOCAL_LENGTH);
228+
}
229+
182230
cx = w/2 - 0.5f;
183231
cy = h/2 - 0.5f;
184232

@@ -191,24 +239,42 @@ struct DepthSource
191239

192240
params.frameSize = frameSize;
193241
params.intr = camMatrix;
194-
params.depthFactor = 1000.f;
242+
params.depthFactor = depthFactor;
243+
244+
// RealSense has shorter depth range, some params should be tuned
245+
if(sourceType == Type::DEPTH_REALSENSE)
246+
{
247+
// all sizes in meters
248+
float cubeSize = 1.f;
249+
params.voxelSize = cubeSize/params.volumeDims[0];
250+
params.tsdf_trunc_dist = 0.01f;
251+
params.icpDistThresh = 0.01f;
252+
params.volumePose = Affine3f().translate(Vec3f(-cubeSize/2.f,
253+
-cubeSize/2.f,
254+
0.05f));
255+
params.truncateThreshold = 2.5f;
256+
params.bilateral_sigma_depth = 0.01f;
257+
}
258+
259+
if(sourceType == Type::DEPTH_KINECT2)
260+
{
261+
Matx<float, 1, 5> distCoeffs;
262+
distCoeffs(0) = Kinect2Params::k1;
263+
distCoeffs(1) = Kinect2Params::k2;
264+
distCoeffs(4) = Kinect2Params::k3;
195265

196-
Matx<float, 1, 5> distCoeffs;
197-
distCoeffs(0) = Kinect2Params::k1;
198-
distCoeffs(1) = Kinect2Params::k2;
199-
distCoeffs(4) = Kinect2Params::k3;
200-
if(useKinect2Workarounds)
201266
initUndistortRectifyMap(camMatrix, distCoeffs, cv::noArray(),
202267
camMatrix, frameSize, CV_16SC2,
203268
undistortMap1, undistortMap2);
269+
}
204270
}
205271
}
206272

207273
vector<string> depthFileList;
208274
size_t frameIdx;
209275
VideoCapture vc;
210276
UMat undistortMap1, undistortMap2;
211-
bool useKinect2Workarounds;
277+
Type sourceType;
212278
};
213279

214280
#ifdef HAVE_OPENCV_VIZ
@@ -323,7 +389,11 @@ int main(int argc, char **argv)
323389
cv::setUseOptimized(true);
324390

325391
// Scene-specific params should be tuned for each scene individually
326-
//params->volumePose = params->volumePose.translate(Vec3f(0.f, 0.f, 0.5f));
392+
//float cubeSize = 1.f;
393+
//params->voxelSize = cubeSize/params->volumeDims[0]; //meters
394+
//params->tsdf_trunc_dist = 0.01f; //meters
395+
//params->icpDistThresh = 0.01f; //meters
396+
//params->volumePose = Affine3f().translate(Vec3f(-cubeSize/2.f, -cubeSize/2.f, 0.25f)); //meters
327397
//params->tsdf_max_weight = 16;
328398

329399
if(!idle)

modules/rgbd/src/kinfu.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ Ptr<Params> Params::defaultParams()
6060
//p.lightPose = p.volume_pose.translation()/4; //meters
6161
p.lightPose = Vec3f::all(0.f); //meters
6262

63-
// depth truncation is not used by default
64-
//p.icp_truncate_depth_dist = 0.f; //meters, disabled
63+
// depth truncation is not used by default but can be useful in some scenes
64+
p.truncateThreshold = 0.f; //meters
6565

6666
return makePtr<Params>(p);
6767
}
@@ -209,7 +209,8 @@ bool KinFuImpl<T>::updateT(const T& _depth)
209209
params.depthFactor,
210210
params.bilateral_sigma_depth,
211211
params.bilateral_sigma_spatial,
212-
params.bilateral_kernel_size);
212+
params.bilateral_kernel_size,
213+
params.truncateThreshold);
213214

214215
if(frameCounter == 0)
215216
{

modules/rgbd/src/kinfu_frame.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ void computePointsNormals(const Intr intr, float depthFactor, const Depth depth,
304304
static bool ocl_renderPointsNormals(const UMat points, const UMat normals, UMat image, Affine3f lightPose);
305305
static bool ocl_makeFrameFromDepth(const UMat depth, OutputArrayOfArrays points, OutputArrayOfArrays normals,
306306
const Intr intr, int levels, float depthFactor,
307-
float sigmaDepth, float sigmaSpatial, int kernelSize);
307+
float sigmaDepth, float sigmaSpatial, int kernelSize,
308+
float truncateThreshold);
308309
static bool ocl_buildPyramidPointsNormals(const UMat points, const UMat normals,
309310
OutputArrayOfArrays pyrPoints, OutputArrayOfArrays pyrNormals,
310311
int levels);
@@ -490,20 +491,22 @@ static bool ocl_renderPointsNormals(const UMat points, const UMat normals,
490491

491492
static bool ocl_makeFrameFromDepth(const UMat depth, OutputArrayOfArrays points, OutputArrayOfArrays normals,
492493
const Intr intr, int levels, float depthFactor,
493-
float sigmaDepth, float sigmaSpatial, int kernelSize)
494+
float sigmaDepth, float sigmaSpatial, int kernelSize,
495+
float truncateThreshold)
494496
{
495497
CV_TRACE_FUNCTION();
496498

497499
// looks like OpenCV's bilateral filter works the same as KinFu's
498500
UMat smooth;
499501
//TODO: fix that
500-
// until 32f isn't implemented in OpenCV, we should use our workarounds
502+
// until 32f isn't implemented in OpenCV in OpenCL, we should use our workarounds
501503
//bilateralFilter(udepth, smooth, kernelSize, sigmaDepth*depthFactor, sigmaSpatial);
502504
if(!customBilateralFilterGpu(depth, smooth, kernelSize, sigmaDepth*depthFactor, sigmaSpatial))
503-
return false;
505+
return false;
504506

505-
// depth truncation is not used by default
506-
//if (p.icp_truncate_depth_dist > 0) kfusion::cuda::depthTruncation(curr_.depth_pyr[0], p.icp_truncate_depth_dist);
507+
// depth truncation can be used in some scenes
508+
if(truncateThreshold > 0.f)
509+
threshold(depth, depth, truncateThreshold*depthFactor, 0.0, THRESH_TOZERO_INV);
507510

508511
UMat scaled = smooth;
509512
Size sz = smooth.size();
@@ -596,7 +599,8 @@ void renderPointsNormals(InputArray _points, InputArray _normals, OutputArray im
596599
void makeFrameFromDepth(InputArray _depth,
597600
OutputArray pyrPoints, OutputArray pyrNormals,
598601
const Intr intr, int levels, float depthFactor,
599-
float sigmaDepth, float sigmaSpatial, int kernelSize)
602+
float sigmaDepth, float sigmaSpatial, int kernelSize,
603+
float truncateThreshold)
600604
{
601605
CV_TRACE_FUNCTION();
602606

@@ -605,7 +609,8 @@ void makeFrameFromDepth(InputArray _depth,
605609
CV_OCL_RUN(_depth.isUMat() && pyrPoints.isUMatVector() && pyrNormals.isUMatVector(),
606610
ocl_makeFrameFromDepth(_depth.getUMat(), pyrPoints, pyrNormals,
607611
intr, levels, depthFactor,
608-
sigmaDepth, sigmaSpatial, kernelSize));
612+
sigmaDepth, sigmaSpatial, kernelSize,
613+
truncateThreshold));
609614

610615
int kp = pyrPoints.kind(), kn = pyrNormals.kind();
611616
CV_Assert(kp == _InputArray::STD_ARRAY_MAT || kp == _InputArray::STD_VECTOR_MAT);
@@ -618,8 +623,9 @@ void makeFrameFromDepth(InputArray _depth,
618623

619624
bilateralFilter(depth, smooth, kernelSize, sigmaDepth*depthFactor, sigmaSpatial);
620625

621-
// depth truncation is not used by default
622-
//if (p.icp_truncate_depth_dist > 0) kfusion::cuda::depthTruncation(curr_.depth_pyr[0], p.icp_truncate_depth_dist);
626+
// depth truncation can be used in some scenes
627+
if(truncateThreshold > 0.f)
628+
threshold(depth, depth, truncateThreshold, 0.0, THRESH_TOZERO_INV);
623629

624630
// we don't need depth pyramid outside this method
625631
// if we do, the code is to be refactored

modules/rgbd/src/kinfu_frame.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ typedef cv::Mat_< depthType > Depth;
8383
void renderPointsNormals(InputArray _points, InputArray _normals, OutputArray image, cv::Affine3f lightPose);
8484
void makeFrameFromDepth(InputArray depth, OutputArray pyrPoints, OutputArray pyrNormals,
8585
const Intr intr, int levels, float depthFactor,
86-
float sigmaDepth, float sigmaSpatial, int kernelSize);
86+
float sigmaDepth, float sigmaSpatial, int kernelSize,
87+
float truncateThreshold);
8788
void buildPyramidPointsNormals(InputArray _points, InputArray _normals,
8889
OutputArrayOfArrays pyrPoints, OutputArrayOfArrays pyrNormals,
8990
int levels);

modules/rgbd/src/odometry.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,8 +1492,9 @@ Size FastICPOdometry::prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType
14921492
// mask isn't used by FastICP
14931493
Intr intr(cameraMatrix);
14941494
float depthFactor = 1.f; // user should rescale depth manually
1495+
float truncateThreshold = 0.f; // disabled
14951496
makeFrameFromDepth(frame->depth, frame->pyramidCloud, frame->pyramidNormals, intr, (int)iterCounts.total(),
1496-
depthFactor, sigmaDepth, sigmaSpatial, kernelSize);
1497+
depthFactor, sigmaDepth, sigmaSpatial, kernelSize, truncateThreshold);
14971498

14981499
return frame->depth.size();
14991500
}

0 commit comments

Comments
 (0)