Skip to content

Commit ff7ae0b

Browse files
Felixxlz
authored andcommitted
Add KDE depth unwrapping algorithms
This implements kernel density estimation based phase unwrapping procedure. It shows improved depth imaging, especially for large depth and outdoors scenes. The method was presented on ECCV 2016, see paper for more information. http://users.isy.liu.se/cvl/perfo/abstracts/jaremo16.html The algorithms are added as OpenCL and CUDA processors. OpenCLKde and CudaKde pipelines are also added as APIs.
1 parent e968c1f commit ff7ae0b

11 files changed

+3211
-9
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ IF(ENABLE_OPENCL)
313313

314314
LIST(APPEND SOURCES
315315
src/opencl_depth_packet_processor.cpp
316+
src/opencl_kde_depth_packet_processor.cpp
316317
)
317318

318319
LIST(APPEND LIBRARIES
@@ -321,6 +322,7 @@ IF(ENABLE_OPENCL)
321322

322323
LIST(APPEND RESOURCES
323324
src/opencl_depth_packet_processor.cl
325+
src/opencl_kde_depth_packet_processor.cl
324326
)
325327

326328
# Major Linux distro stable releases have buggy OpenCL ICD loader.
@@ -359,6 +361,7 @@ IF(ENABLE_CUDA)
359361
ENDIF()
360362
CUDA_COMPILE(CUDA_OBJECTS
361363
src/cuda_depth_packet_processor.cu
364+
src/cuda_kde_depth_packet_processor.cu
362365
OPTIONS ${CUDA_FLAGS}
363366
)
364367
SET(CMAKE_CXX_FLAGS "${OLD_CMAKE_CXX_FLAGS}")

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Note: libfreenect2 does not do anything for either Kinect for Windows v1 or Kine
2020

2121
If you are using libfreenect2 in an academic context, please cite our work using the following DOI: [![DOI](https://zenodo.org/badge/20096/OpenKinect/libfreenect2.svg)](https://zenodo.org/badge/latestdoi/20096/OpenKinect/libfreenect2)
2222

23+
If you use the KDE depth unwrapping algorithm implemented in the library, please also cite this ECCV 2016 [paper](http://users.isy.liu.se/cvl/perfo/abstracts/jaremo16.html).
24+
2325
This driver supports:
2426
* RGB image transfer
2527
* IR and depth image transfer

examples/Protonect.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ int main(int argc, char *argv[])
113113
std::string program_path(argv[0]);
114114
std::cerr << "Version: " << LIBFREENECT2_VERSION << std::endl;
115115
std::cerr << "Environment variables: LOGFILE=<protonect.log>" << std::endl;
116-
std::cerr << "Usage: " << program_path << " [-gpu=<id>] [gl | cl | cuda | cpu] [<device serial>]" << std::endl;
116+
std::cerr << "Usage: " << program_path << " [-gpu=<id>] [gl | cl | clkde | cuda | cudakde | cpu] [<device serial>]" << std::endl;
117117
std::cerr << " [-noviewer] [-norgb | -nodepth] [-help] [-version]" << std::endl;
118118
std::cerr << " [-frames <number of frames to process>]" << std::endl;
119119
std::cerr << "To pause and unpause: pkill -USR1 Protonect" << std::endl;
@@ -198,6 +198,15 @@ int main(int argc, char *argv[])
198198
pipeline = new libfreenect2::OpenCLPacketPipeline(deviceId);
199199
#else
200200
std::cout << "OpenCL pipeline is not supported!" << std::endl;
201+
#endif
202+
}
203+
else if(arg == "clkde")
204+
{
205+
#ifdef LIBFREENECT2_WITH_OPENCL_SUPPORT
206+
if(!pipeline)
207+
pipeline = new libfreenect2::OpenCLKdePacketPipeline(deviceId);
208+
#else
209+
std::cout << "OpenCL pipeline is not supported!" << std::endl;
201210
#endif
202211
}
203212
else if(arg == "cuda")
@@ -207,6 +216,15 @@ int main(int argc, char *argv[])
207216
pipeline = new libfreenect2::CudaPacketPipeline(deviceId);
208217
#else
209218
std::cout << "CUDA pipeline is not supported!" << std::endl;
219+
#endif
220+
}
221+
else if(arg == "cudakde")
222+
{
223+
#ifdef LIBFREENECT2_WITH_CUDA_SUPPORT
224+
if(!pipeline)
225+
pipeline = new libfreenect2::CudaKdePacketPipeline(deviceId);
226+
#else
227+
std::cout << "CUDA pipeline is not supported!" << std::endl;
210228
#endif
211229
}
212230
else if(arg.find_first_not_of("0123456789") == std::string::npos) //check if parameter could be a serial number

include/internal/libfreenect2/depth_packet_processor.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ class DepthPacketProcessor : public BaseDepthPacketProcessor
9090
float edge_avg_delta_threshold;
9191
float max_edge_count;
9292

93+
float kde_sigma_sqr;
94+
float unwrapping_likelihood_scale;
95+
float phase_confidence_scale;
96+
float kde_threshold;
97+
size_t kde_neigborhood_size;
98+
size_t num_hyps;
99+
93100
float min_depth;
94101
float max_depth;
95102

@@ -184,6 +191,37 @@ class OpenCLDepthPacketProcessor : public DepthPacketProcessor
184191
private:
185192
OpenCLDepthPacketProcessorImpl *impl_;
186193
};
194+
195+
/*
196+
* The class below implement a depth packet processor using the phase unwrapping
197+
* algorithm described in the paper "Efficient Phase Unwrapping using Kernel
198+
* Density Estimation", ECCV 2016, Felix Järemo Lawin, Per-Erik Forssen and
199+
* Hannes Ovren, see http://www.cvl.isy.liu.se/research/datasets/kinect2-dataset/.
200+
*/
201+
class OpenCLKdeDepthPacketProcessorImpl;
202+
203+
/** Depth packet processor using OpenCL. */
204+
class OpenCLKdeDepthPacketProcessor : public DepthPacketProcessor
205+
{
206+
public:
207+
OpenCLKdeDepthPacketProcessor(const int deviceId = -1);
208+
virtual ~OpenCLKdeDepthPacketProcessor();
209+
virtual void setConfiguration(const libfreenect2::DepthPacketProcessor::Config &config);
210+
211+
virtual void loadP0TablesFromCommandResponse(unsigned char* buffer, size_t buffer_length);
212+
213+
virtual void loadXZTables(const float *xtable, const float *ztable);
214+
virtual void loadLookupTable(const short *lut);
215+
216+
virtual bool good();
217+
virtual const char *name() { return "OpenCLKde"; }
218+
219+
virtual void process(const DepthPacket &packet);
220+
protected:
221+
virtual Allocator *getAllocator();
222+
private:
223+
OpenCLKdeDepthPacketProcessorImpl *impl_;
224+
};
187225
#endif // LIBFREENECT2_WITH_OPENCL_SUPPORT
188226

189227
#ifdef LIBFREENECT2_WITH_CUDA_SUPPORT
@@ -210,6 +248,36 @@ class CudaDepthPacketProcessor : public DepthPacketProcessor
210248
private:
211249
CudaDepthPacketProcessorImpl *impl_;
212250
};
251+
252+
/*
253+
* The class below implement a depth packet processor using the phase unwrapping
254+
* algorithm described in the paper "Efficient Phase Unwrapping using Kernel
255+
* Density Estimation", ECCV 2016, Felix Järemo Lawin, Per-Erik Forssen and
256+
* Hannes Ovren, see http://www.cvl.isy.liu.se/research/datasets/kinect2-dataset/.
257+
*/
258+
class CudaKdeDepthPacketProcessorImpl;
259+
260+
class CudaKdeDepthPacketProcessor : public DepthPacketProcessor
261+
{
262+
public:
263+
CudaKdeDepthPacketProcessor(const int deviceId = -1);
264+
virtual ~CudaKdeDepthPacketProcessor();
265+
virtual void setConfiguration(const libfreenect2::DepthPacketProcessor::Config &config);
266+
267+
virtual void loadP0TablesFromCommandResponse(unsigned char* buffer, size_t buffer_length);
268+
269+
virtual void loadXZTables(const float *xtable, const float *ztable);
270+
virtual void loadLookupTable(const short *lut);
271+
272+
virtual bool good();
273+
virtual const char *name() { return "CUDAKde"; }
274+
275+
virtual void process(const DepthPacket &packet);
276+
protected:
277+
virtual Allocator *getAllocator();
278+
private:
279+
CudaKdeDepthPacketProcessorImpl *impl_;
280+
};
213281
#endif // LIBFREENECT2_WITH_CUDA_SUPPORT
214282

215283
class DumpDepthPacketProcessor : public DepthPacketProcessor

include/libfreenect2/packet_pipeline.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,21 @@ class LIBFREENECT2_API OpenCLPacketPipeline : public PacketPipeline
113113
OpenCLPacketPipeline(const int deviceId = -1);
114114
virtual ~OpenCLPacketPipeline();
115115
};
116+
117+
/*
118+
* The class below implement a depth packet processor using the phase unwrapping
119+
* algorithm described in the paper "Efficient Phase Unwrapping using Kernel
120+
* Density Estimation", ECCV 2016, Felix Järemo Lawin, Per-Erik Forssen and
121+
* Hannes Ovren, see http://www.cvl.isy.liu.se/research/datasets/kinect2-dataset/.
122+
*/
123+
class LIBFREENECT2_API OpenCLKdePacketPipeline : public PacketPipeline
124+
{
125+
protected:
126+
const int deviceId;
127+
public:
128+
OpenCLKdePacketPipeline(const int deviceId = -1);
129+
virtual ~OpenCLKdePacketPipeline();
130+
};
116131
#endif // LIBFREENECT2_WITH_OPENCL_SUPPORT
117132

118133
#ifdef LIBFREENECT2_WITH_CUDA_SUPPORT
@@ -124,6 +139,21 @@ class LIBFREENECT2_API CudaPacketPipeline : public PacketPipeline
124139
CudaPacketPipeline(const int deviceId = -1);
125140
virtual ~CudaPacketPipeline();
126141
};
142+
143+
/*
144+
* The class below implement a depth packet processor using the phase unwrapping
145+
* algorithm described in the paper "Efficient Phase Unwrapping using Kernel
146+
* Density Estimation", ECCV 2016, Felix Järemo Lawin, Per-Erik Forssen and
147+
* Hannes Ovren, see http://www.cvl.isy.liu.se/research/datasets/kinect2-dataset/.
148+
*/
149+
class LIBFREENECT2_API CudaKdePacketPipeline : public PacketPipeline
150+
{
151+
protected:
152+
const int deviceId;
153+
public:
154+
CudaKdePacketPipeline(const int deviceId = -1);
155+
virtual ~CudaKdePacketPipeline();
156+
};
127157
#endif // LIBFREENECT2_WITH_CUDA_SUPPORT
128158

129159
///@}

0 commit comments

Comments
 (0)