├── CMakeLists.txt
├── CMakeModules
├── FindDEPTHSENSE.cmake
└── FindOpenNI2.cmake
├── LICENSE
├── README.md
├── doxygen.config
├── models
└── leftHand
│ ├── leftHand.xml
│ └── palm.obj
├── src
├── depth_sources
│ ├── depth_source.h
│ ├── depthsense_depth_source.cpp
│ ├── depthsense_depth_source.h
│ ├── image_depth_source.h
│ ├── openni_depth_source.cpp
│ ├── openni_depth_source.h
│ └── pango_depth_source.h
├── geometry
│ ├── SE3.h
│ ├── distance_transforms.cpp
│ ├── distance_transforms.cu
│ ├── distance_transforms.h
│ ├── geometry.cpp
│ ├── geometry.h
│ ├── grid_2d.h
│ ├── grid_3d.h
│ ├── plane_fitting.cpp
│ ├── plane_fitting.cu
│ ├── plane_fitting.h
│ ├── sdf.cpp
│ └── sdf.h
├── img_proc
│ ├── bilateral_filter.cu
│ ├── bilateral_filter.h
│ ├── img_ops.cpp
│ ├── img_ops.cu
│ ├── img_ops.h
│ ├── organized_point_cloud.cpp
│ ├── organized_point_cloud.cu
│ ├── organized_point_cloud.h
│ ├── resampling.cpp
│ ├── resampling.cu
│ └── resampling.h
├── mesh
│ ├── assimp_mesh_reader.cpp
│ ├── assimp_mesh_reader.h
│ ├── mesh.cpp
│ ├── mesh.h
│ ├── mesh_proc.cpp
│ ├── mesh_proc.h
│ ├── mesh_sample.cpp
│ ├── mesh_sample.h
│ ├── mesh_splat.cpp
│ ├── mesh_splat.h
│ ├── primitive_meshing.cpp
│ └── primitive_meshing.h
├── model
│ ├── host_only_model.cpp
│ ├── host_only_model.h
│ ├── mirrored_model.cpp
│ ├── mirrored_model.h
│ ├── model.cpp
│ └── model.h
├── optimization
│ ├── contact_prior.cpp
│ ├── kernels
│ │ ├── intersection.cu
│ │ ├── intersection.h
│ │ ├── kernel_common.h
│ │ ├── modToObs.cu
│ │ ├── modToObs.h
│ │ ├── obsToMod.cu
│ │ ├── obsToMod.h
│ │ ├── raycast.cu
│ │ └── raycast.h
│ ├── optimization.h
│ ├── optimizer.cpp
│ ├── optimizer.h
│ ├── point_2d_3d_prior.cpp
│ ├── point_3d_3d_prior.cpp
│ ├── prediction_renderer.cpp
│ ├── prediction_renderer.h
│ └── priors.h
├── point_cloud_src
│ └── point_cloud_src.h
├── pose
│ ├── pose.cpp
│ ├── pose.h
│ └── pose_reduction.h
├── tracker.cpp
├── tracker.h
├── util
│ ├── cuda_utils.h
│ ├── dart_io.cpp
│ ├── dart_io.h
│ ├── dart_types.h
│ ├── gl_dart.cpp
│ ├── gl_dart.h
│ ├── image_io.cpp
│ ├── image_io.h
│ ├── mirrored_memory.h
│ ├── model_renderer.cpp
│ ├── model_renderer.h
│ ├── ostream_operators.cpp
│ ├── ostream_operators.h
│ ├── prefix.h
│ ├── string_format.cpp
│ ├── string_format.h
│ └── vector_type_template.h
└── visualization
│ ├── color_ramps.cpp
│ ├── color_ramps.cu
│ ├── color_ramps.h
│ ├── data_association_viz.cpp
│ ├── data_association_viz.cu
│ ├── data_association_viz.h
│ ├── gradient_viz.cpp
│ ├── gradient_viz.cu
│ ├── gradient_viz.h
│ ├── matrix_viz.cu
│ ├── matrix_viz.h
│ ├── sdf_viz.cpp
│ ├── sdf_viz.cu
│ └── sdf_viz.h
└── test
├── test_main.cpp
├── test_mirrored_model.cpp
├── test_model_jacobian.cpp
├── test_model_jacobian.cu
├── test_obs_to_mod_kernels.cpp
├── test_pose_reduction.cpp
└── test_voxelize.cpp
/CMakeModules/FindDEPTHSENSE.cmake:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # Find DEPTHSENSE
3 | #
4 | # DEPTHSENSE_FOUND - True if DepthSense was found
5 | # DEPTHSENSE_INCLUDE_DIR - Directories containing the DepthSense include files
6 | # DEPTHSENSE_LIBRARIES - Librarires needed to use DepthSense
7 | #
8 | ################################################################################
9 |
10 | IF (WIN32)
11 | ELSE ()
12 | FIND_PATH(DEPTHSENSE_INCLUDE_DIR DepthSense.hxx
13 | /opt/DepthSenseSDK/include
14 | /opt/softkinetic/DepthSenseSDK/include
15 | ${PROJECT_SOURCE_DIR}/external_lib/include
16 | DOC "The directory where DepthSense.hxx resides"
17 | )
18 | FIND_LIBRARY(DEPTHSENSE_LIBRARIES
19 | NAMES DepthSense
20 | PATHS
21 | /opt/DepthSenseSDK/lib/libDepthSense.so
22 | /opt/softkinetic/DepthSenseSDK/lib/
23 | ${PROJECT_SOURCE_DIR}/external_lib/lib
24 | DOC "The DepthSense library"
25 | )
26 | ENDIF()
27 |
28 | IF(DEPTHSENSE_INCLUDE_DIR AND DEPTHSENSE_LIBRARIES)
29 | SET(DEPTHSENSE_FOUND ON)
30 | message(STATUS "DepthSense found: ${DEPTHSENSE_INCLUDE_DIR}")
31 | ELSE()
32 | SET(DEPTHSENSE_FOUND OFF)
33 | ENDIF()
34 |
35 | MARK_AS_ADVANCED(DEPTHSENSE_FOUND)
36 |
--------------------------------------------------------------------------------
/CMakeModules/FindOpenNI2.cmake:
--------------------------------------------------------------------------------
1 | find_package(PkgConfig QUIET)
2 |
3 | # Find LibUSB
4 | if(NOT WIN32)
5 | pkg_check_modules(PC_USB_10 libusb-1.0)
6 | find_path(USB_10_INCLUDE_DIR libusb-1.0/libusb.h
7 | HINTS ${PC_USB_10_INCLUDEDIR} ${PC_USB_10_INCLUDE_DIRS} "${USB_10_ROOT}" "$ENV{USB_10_ROOT}"
8 | PATH_SUFFIXES libusb-1.0)
9 |
10 | find_library(USB_10_LIBRARY
11 | NAMES usb-1.0
12 | HINTS ${PC_USB_10_LIBDIR} ${PC_USB_10_LIBRARY_DIRS} "${USB_10_ROOT}" "$ENV{USB_10_ROOT}"
13 | PATH_SUFFIXES lib)
14 |
15 | include(FindPackageHandleStandardArgs)
16 | find_package_handle_standard_args(USB_10 DEFAULT_MSG USB_10_LIBRARY USB_10_INCLUDE_DIR)
17 |
18 | if(NOT USB_10_FOUND)
19 | message(STATUS "OpenNI 2 disabled because libusb-1.0 not found.")
20 | return()
21 | else()
22 | include_directories(SYSTEM ${USB_10_INCLUDE_DIR})
23 | endif()
24 | endif(NOT WIN32)
25 |
26 | if(${CMAKE_VERSION} VERSION_LESS 2.8.2)
27 | pkg_check_modules(PC_OPENNI2 libopenni2)
28 | else()
29 | pkg_check_modules(PC_OPENNI2 QUIET libopenni2)
30 | endif()
31 |
32 | set(OPENNI2_DEFINITIONS ${PC_OPENNI_CFLAGS_OTHER})
33 |
34 | set(OPENNI2_SUFFIX)
35 | if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
36 | set(OPENNI2_SUFFIX 64)
37 | endif(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
38 |
39 | find_path(OPENNI2_INCLUDE_DIRS OpenNI.h
40 | PATHS
41 | "$ENV{OPENNI2_INCLUDE${OPENNI2_SUFFIX}}" # Win64 needs '64' suffix
42 | /usr/include/openni2 # common path for deb packages
43 | )
44 |
45 | find_library(OPENNI2_LIBRARY
46 | NAMES OpenNI2 # No suffix needed on Win64
47 | libOpenNI2 # Linux
48 | PATHS "$ENV{OPENNI2_LIB${OPENNI2_SUFFIX}}" # Windows default path, Win64 needs '64' suffix
49 | "$ENV{OPENNI2_REDIST}" # Linux install does not use a separate 'lib' directory
50 | )
51 |
52 | if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
53 | set(OPENNI2_LIBRARIES ${OPENNI2_LIBRARY} ${LIBUSB_1_LIBRARIES})
54 | else()
55 | set(OPENNI2_LIBRARIES ${OPENNI2_LIBRARY})
56 | endif()
57 |
58 | include(FindPackageHandleStandardArgs)
59 | find_package_handle_standard_args(OpenNI2 DEFAULT_MSG OPENNI2_LIBRARY OPENNI2_INCLUDE_DIRS)
60 |
61 | mark_as_advanced(OPENNI2_LIBRARY OPENNI2_INCLUDE_DIRS)
62 |
63 | if(OPENNI2_FOUND)
64 | # Add the include directories
65 | set(OPENNI2_INCLUDE_DIRS ${OPENNI2_INCLUDE_DIR})
66 | set(OPENNI2_REDIST_DIR $ENV{OPENNI2_REDIST${OPENNI2_SUFFIX}})
67 | message(STATUS "OpenNI 2 found (include: ${OPENNI2_INCLUDE_DIRS}, lib: ${OPENNI2_LIBRARY}, redist: ${OPENNI2_REDIST_DIR})")
68 | endif(OPENNI2_FOUND)
69 | #find_path(OpenNI2_INCLUDE_DIR OpenNI.h
70 | # /usr/local/OpenNI-2.2/Include
71 | # /usr/local/OpenNI-2.1/Include
72 |
73 | #)
74 | #find_path(OpenNI2_LIBRARY_PATH libOpenNI2.so
75 | # /usr/local/OpenNI-2.2/Redist
76 | # /usr/local/OpenNI-2.1/Redist
77 | #)
78 | #if(OpenNI2_INCLUDE_DIR)
79 | # set(OpenNI2_FOUND ON)
80 | # set(OpenNI2_LIBRARIES libOpenNI2.so libOniFile.so libPS1080.so)
81 | # set(OpenNI2_LIBRARY_COPY_PATH ${OpenNI2_LIBRARY_PATH}/OpenNI2)
82 | # set(OpenNI2_DRIVER_LIBRARY_PATH ${OpenNI2_LIBRARY_PATH}/OpenNI2/Drivers)
83 | #endif()
84 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2017, Tanner Schmidt
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | dart: Dense Articulated Real-time Tracking
2 | =======
3 |
4 | dart is a C++ library for tracking arbitrary articulated models with an RGB-D
5 | camera. It achieves real-time performance with the aid of a highly parallel CUDA
6 | implementation and state-of-the-art GPUs.
7 |
8 | Required Dependencies
9 | ---------------------
10 |
11 | **CUDA:** https://developer.nvidia.com/cuda-zone
12 |
13 | **Eigen 3:** sudo apt-get install libeigen3-dev
14 |
15 | **GNU libmatheval:** sudo apt-get install libmatheval-dev
16 |
17 | **libjpeg:** sudo apt-get install libjpeg-dev
18 |
19 | **libpng:** sudo apt-get install libpng-dev
20 |
21 | **tinyxml:** sudo apt-get install libtinyxml-dev
22 |
23 | Optional Dependencies
24 | ---------------------
25 |
26 | **Pangolin [GUI for the examples]:** https://github.com/stevenlovegrove/Pangolin
27 |
28 | **OpenNI [for PrimeSense sensors]:** https://github.com/OpenNI/OpenNI2 or http://structure.io/openni
29 |
30 | **DepthSense SDK [for Intel sensor]:** sudo apt-get install depthsensesdk
31 |
32 | **Open Asset Import Library:** sudo apt-get install libassimp-dev [for mesh models]
33 |
34 | **gtest [for testing]:** sudo apt-get install libgtest-dev; cd /usr/src/gtest; sudo mkdir build; cd build; sudo cmake ..; sudo make; sudo mv libgtest* /usr/lib/;
35 |
36 | Installation
37 | ------------
38 |
39 | cd [dart directory]
40 | mkdir build
41 | cd build
42 | cmake ..
43 | make
44 |
45 | Example usage
46 | ------------
47 |
48 | An example demonstrating the use of DART to track robot hands manipulating objects, including the depth and color video, can be downloaded from [here](https://drive.google.com/file/d/1HXvOsUcgS6THn17hME-SKQU3FQVUJr_z/view?usp=sharing).
49 |
50 | Notes on using the library
51 | ------------
52 |
53 | - OpenGL context: dart is a very visual library and therefore assumes that it
54 | will be used in collaboration with a GUI tool. If an instance of dart::Tracker
55 | is instantiated with no active OpenGL context, it will not work. If you are not
56 | using the library with a GUI, you will have to create an OpenGL context (e.g. by
57 | using glutCreateWindow to create a 1x1 window).
58 |
59 | - Frames vs. Joints vs. SDFs: These are three separate but related ways in which
60 | parts of a DART model can be referenced. A frame is a frame of reference in the
61 | kinematic chain, a joint is a connection between two frames with a single degree
62 | of freedom, and a signed distance function (SDF) implicitly stores all geometry
63 | attached to a single frame. Every model has at least one frame (the root) but
64 | need not have any joints or signed distance functions. Because loops are not
65 | allowed, a model with N joints will have N+1 frames (and N+6 degrees of
66 | freedom). The number of SDFs is at most equal to the number of frames, but may
67 | be less if there are frames with no geometry attached to them. Functions in the
68 | Model class and subclasses that require indexing part of the model will indicate
69 | in the parameter name whether the index is by joint, by frame, or by SDF.
70 |
71 | Model file format
72 | ------------
73 |
74 | DART models are stored as XML files which define the kinematic and geometric
75 | structure, optionally reference other mesh files to further describe the
76 | geometry. All models open with the "model" tag which has a single attribute,
77 | "version" describing the version of the DART XML format (current 1), like so:
78 |
79 |
80 | [model here]
81 |
82 |
83 | The model can then optionally specify a number of parameters using the "param"
84 | tag, with attributes "name" (string) and "value" (floating point), like so:
85 |
86 |
87 |
88 | These parameters can then be referenced when defining sizes, positions, or
89 | orientations, as described below. Parameters are useful if the same value
90 | appears multiple times in your specification (as is often the case) or if you
91 | would like to set the parameter values programatically.
92 |
93 | After defining parameters, the model may contain a number of hierachically
94 | nested "frame" and "geom" tags, which specify new rigid body frames of reference
95 | or geometric objects, respectively. The "frame" tag requires four attributes,
96 | "jointName" (string), "jointType" (currently accepts either "rotational" or
97 | "prismatic", "jointMin" (floating point), and "jointMax" (floating point), the
98 | last two of which define the joint limits. Additionally, the frame tag requires
99 | three nested tags, "position", "orientation", and "axis", each of which require
100 | three floating point attributes, "x", "y", and "z". An example might look like
101 | this:
102 |
103 |
104 |
105 |
106 |
107 | [frame children here]
108 |
109 |
110 | This snippet defines a new frame of reference relative to its parent (the XML
111 | node directly above it in the hierarchy, or the root if the parent is the
112 | "model" tag). The transform from this frame of reference to the world is given
113 | by:
114 |
115 | T_w,f = T_w,p*Trans*R_z*R_y*R_x*R_axis(theta)
116 |
117 | where T_w,p gives the transform from the parent to the world, Trans is a
118 | translation-only transform given by the "position" tag, R_z, R_y, and R_x are
119 | rotations about the z, y, and x axes (i.e. Euler angles) given by the
120 | corresponding entries in the "orientation" tag, and R_axis is a rotation by
121 | theta around the axis defined by the "axis" tag, with theta being given by the
122 | articulated pose of the model.
123 |
124 | Finally, geometry can be rigidly attached to any frame of reference in the model
125 | by nesting a "geom" tag within a "frame" tag (or within the "model" tag for root
126 | geometry). The geometry tag requires 13 attributes: "type" (currently accepts
127 | "sphere","cylinder","cube", or "mesh"), "sx", "sy", and "sz", which define the
128 | scaling of the geometry, "tx", "ty", and "tz", which define the translation of
129 | the geometry root relative to the rigid body frame of reference, "rx", "ry" and
130 | "rz", which define the orientation relative to the rigid body frame of reference
131 | (also in Euler angles, as with the "frame" tag), and "red", "green" and "blue",
132 | which define the geometry color, which is not used for tracking but will affect
133 | how the model is rendered for debugging purposes. If "type" is set to "mesh",
134 | there is one final attribute, "meshFile", which gives the location of the mesh
135 | file, relative to the location of the XML file.
136 |
137 |
--------------------------------------------------------------------------------
/src/depth_sources/depth_source.h:
--------------------------------------------------------------------------------
1 | #ifndef DEPTH_SOURCE_H
2 | #define DEPTH_SOURCE_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace dart {
9 |
10 | enum ColorLayout {
11 | LAYOUT_RGB, LAYOUT_BGR
12 | };
13 |
14 | class DepthSourceBase {
15 |
16 | public:
17 | DepthSourceBase() :
18 | _hasColor(false),
19 | _hasTimestamps(false),
20 | _isLive(false),
21 | _depthWidth(0),
22 | _depthHeight(0),
23 | _colorWidth(0),
24 | _colorHeight(0),
25 | _frame(0) { }
26 |
27 | virtual ColorLayout getColorLayout() const { return LAYOUT_RGB; }
28 |
29 | inline bool hasColor() const { return _hasColor; }
30 |
31 | inline bool hasTimestamps() const { return _hasTimestamps; }
32 |
33 | inline bool isLive() const { return _isLive; }
34 |
35 | inline uint getDepthWidth() const { return _depthWidth; }
36 |
37 | inline uint getDepthHeight() const { return _depthHeight; }
38 |
39 | inline uint getColorWidth() const { return _colorWidth; }
40 |
41 | inline uint getColorHeight() const { return _colorHeight; }
42 |
43 | inline float2 getFocalLength() const { return _focalLength; }
44 | inline void setFocalLength(const float2 focalLength) { _focalLength = focalLength; }
45 |
46 | inline float2 getPrincipalPoint() const { return _principalPoint; }
47 | inline void setPrincipalPoint(const float2 principalPoint) { _principalPoint = principalPoint; }
48 |
49 | virtual uint64_t getDepthTime() const { return 0; }
50 |
51 | virtual uint64_t getColorTime() const { return 0; }
52 |
53 | virtual uint getFrame() const { return _frame; }
54 |
55 | virtual void setFrame(const uint frame) = 0;
56 |
57 | virtual void advance() = 0;
58 |
59 | virtual bool hasRadialDistortionParams() const = 0;
60 |
61 | virtual const float * getRadialDistortionParams() const { return 0; }
62 |
63 | virtual float getScaleToMeters() const { return 1.0f; }
64 |
65 | protected:
66 | bool _hasColor;
67 | bool _hasTimestamps;
68 | bool _isLive;
69 | uint _depthWidth;
70 | uint _depthHeight;
71 | uint _colorWidth;
72 | uint _colorHeight;
73 | uint _frame;
74 | float2 _focalLength;
75 | float2 _principalPoint;
76 |
77 | };
78 |
79 | template
80 | class DepthSource : public DepthSourceBase {
81 | public:
82 |
83 | virtual const DepthType * getDepth() const = 0;
84 | virtual const DepthType * getDeviceDepth() const = 0;
85 |
86 | virtual const ColorType * getColor() const { return 0; }
87 | };
88 |
89 | }
90 |
91 | #endif // DEPTH_SOURCE_H
92 |
--------------------------------------------------------------------------------
/src/depth_sources/depthsense_depth_source.cpp:
--------------------------------------------------------------------------------
1 | #include "depthsense_depth_source.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace dart {
10 |
11 | void * startContext(void * wrapper) {
12 | DepthSense::Context * context = (DepthSense::Context *)wrapper;
13 | context->run();
14 | pthread_exit(NULL);
15 | }
16 |
17 | DepthSenseDepthSource::DepthSenseDepthSource() : DepthSource() {
18 |
19 | _depthData = 0;
20 | _colorData = 0;
21 | _depthTime = _colorTime = 0;
22 |
23 | _nextDepthData = 0;
24 | _nextColorData = 0;
25 | _nextDepthTime = _nextColorTime = 0;
26 |
27 | }
28 |
29 | DepthSenseDepthSource::~DepthSenseDepthSource() {
30 |
31 | if (_context.isSet()) {
32 | _context.stopNodes();
33 | _context.releaseControl(_device);
34 | _context.unregisterNode(_depthNode);
35 | if (_colorNode.isSet()) {
36 | _context.unregisterNode(_colorNode);
37 | }
38 | }
39 |
40 | delete [] _depthData;
41 | cudaFree(_deviceDepthData);
42 | delete [] _colorData;
43 |
44 | delete [] _nextDepthData;
45 | delete [] _nextColorData;
46 |
47 | }
48 |
49 | bool DepthSenseDepthSource::initialize(const bool getColor,
50 | const bool enableDenoising,
51 | const uint confidenceThreshold) {
52 |
53 | _context = DepthSense::Context::createStandalone();
54 |
55 | std::vector devices = _context.getDevices();
56 |
57 | if (devices.size() == 0) {
58 | std::cerr << "could not find any DepthSense devices" << std::endl;
59 | return false;
60 | }
61 |
62 | _device = devices[0];
63 |
64 | std::vector nodes = _device.getNodes();
65 |
66 | for (int i=0; i()) {
68 | _depthNode = (DepthSense::DepthNode)nodes[i];
69 | }
70 | }
71 |
72 | if (!_depthNode.isSet()) {
73 | std::cerr << "could not find depth node" << std::endl;
74 | return false;
75 | }
76 |
77 | if (getColor) {
78 | for (int i=0; i()) {
80 | _colorNode = (DepthSense::ColorNode)nodes[i];
81 | }
82 | }
83 |
84 | if (!_colorNode.isSet()) {
85 | std::cerr << "could not find color node" << std::endl;
86 | return false;
87 | }
88 |
89 | _hasColor = true;
90 | }
91 |
92 | _context.requestControl(_device);
93 |
94 | _context.registerNode(_depthNode);
95 |
96 | _depthNode.setEnableDepthMap(true);
97 | _depthNode.setEnableDenoising(enableDenoising);
98 | _depthNode.setConfidenceThreshold(confidenceThreshold);
99 |
100 | if (getColor) {
101 | _context.registerNode(_colorNode);
102 | _colorNode.setEnableColorMap(true);
103 | DepthSense::ColorNode::Configuration config = _colorNode.getConfiguration();
104 | // config.frameFormat = DepthSense::FRAME_FORMAT_QVGA;
105 | config.compression = DepthSense::COMPRESSION_TYPE_MJPEG;
106 | // config.framerate = 30;
107 | _colorNode.setConfiguration(config);
108 | }
109 |
110 | DepthSense::StereoCameraParameters parameters = _device.getStereoCameraParameters();
111 |
112 | _depthWidth = parameters.depthIntrinsics.width;
113 | _depthHeight = parameters.depthIntrinsics.height;
114 |
115 | _focalLength = make_float2(228.0,228.0);
116 | _principalPoint = make_float2(_depthWidth/2,_depthHeight/2);
117 |
118 | _depthData = new ushort[_depthWidth*_depthHeight];
119 | memset(_depthData,0,_depthWidth*_depthHeight*sizeof(ushort));
120 | cudaMalloc(&_deviceDepthData,_depthWidth*_depthHeight*sizeof(ushort));
121 | _nextDepthData = new ushort[_depthWidth*_depthHeight];
122 |
123 | if (getColor) {
124 | _colorWidth = parameters.colorIntrinsics.width;
125 | _colorHeight = parameters.colorIntrinsics.height;
126 |
127 | _colorData = new uchar3[_colorWidth*_colorHeight];
128 | memset(_colorData,0,_colorWidth*_colorHeight*sizeof(uchar3));
129 | _nextColorData = new uchar3[_colorWidth*_colorHeight];
130 | }
131 |
132 | _hasTimestamps = true;
133 | _isLive = true;
134 |
135 | _depthTime = 0;
136 | _colorTime = 0;
137 |
138 | pthread_mutex_init(&_depthMutex,NULL);
139 | pthread_mutex_init(&_colorMutex,NULL);
140 | pthread_t contextThread;
141 | pthread_create(&contextThread, NULL, startContext, (void*)&_context);
142 |
143 | _depthNode.newSampleReceivedEvent().connect(this, &DepthSenseDepthSource::updateDepth);
144 | if (getColor) {
145 | _colorNode.newSampleReceivedEvent().connect(this, &DepthSenseDepthSource::updateColor);
146 | }
147 |
148 | _context.startNodes();
149 |
150 | advance();
151 |
152 | return true;
153 | }
154 |
155 | void DepthSenseDepthSource::advance() {
156 |
157 | // swap depth buffers
158 | pthread_mutex_lock(&_depthMutex);
159 | if (_nextDepthTime > _depthTime) {
160 | ushort * tmp = _depthData;
161 | _depthData = _nextDepthData;
162 | _nextDepthData = tmp;
163 | _depthTime = _nextDepthTime;
164 | _frame++;
165 | }
166 | pthread_mutex_unlock(&_depthMutex);
167 |
168 | // swap color buffers
169 | pthread_mutex_lock(&_colorMutex);
170 | if (_nextColorTime > _colorTime) {
171 | uchar3 * tmp = _colorData;
172 | _colorData = _nextColorData;
173 | _nextColorData = tmp;
174 | _colorTime = _nextColorTime;
175 | }
176 | pthread_mutex_unlock(&_colorMutex);
177 |
178 | cudaMemcpy(_deviceDepthData,_depthData,_depthWidth*_depthHeight*sizeof(ushort),cudaMemcpyHostToDevice);
179 |
180 | }
181 |
182 | void DepthSenseDepthSource::updateDepth(DepthSense::DepthNode node, DepthSense::DepthNode::NewSampleReceivedData data) {
183 |
184 | pthread_mutex_lock(&_depthMutex);
185 | _nextDepthTime = data.timeOfCapture;
186 | memcpy(_nextDepthData,data.depthMap,_depthWidth*_depthHeight*sizeof(ushort));
187 | pthread_mutex_unlock(&_depthMutex);
188 |
189 | }
190 |
191 | void DepthSenseDepthSource::updateColor(DepthSense::ColorNode node, DepthSense::ColorNode::NewSampleReceivedData data) {
192 |
193 | pthread_mutex_lock(&_colorMutex);
194 | _nextColorTime = data.timeOfCapture;
195 | memcpy(_nextColorData,data.colorMap,_colorWidth*_colorHeight*sizeof(uchar3));
196 | pthread_mutex_unlock(&_colorMutex);
197 |
198 | }
199 |
200 | }
201 |
--------------------------------------------------------------------------------
/src/depth_sources/depthsense_depth_source.h:
--------------------------------------------------------------------------------
1 | #ifndef DEPTHSENSE_DEPTH_SOURCE_H
2 | #define DEPTHSENSE_DEPTH_SOURCE_H
3 |
4 | #include "depth_source.h"
5 |
6 | #include "DepthSense.hxx"
7 |
8 | #include
9 |
10 | namespace dart {
11 |
12 | class DepthSenseDepthSource : public DepthSource {
13 | public:
14 | DepthSenseDepthSource();
15 | ~DepthSenseDepthSource();
16 |
17 | bool initialize(const bool getColor=true,
18 | const bool enableDenoising=true,
19 | const uint confidenceThreshold=250);
20 |
21 | const ushort * getDepth() const { return _depthData; }
22 |
23 | const ushort * getDeviceDepth() const { return _deviceDepthData; }
24 |
25 | const uchar3 * getColor() const { return _colorData; }
26 |
27 | ColorLayout getColorLayout() const { return LAYOUT_BGR; }
28 |
29 | uint64_t getDepthTime() const { return _depthTime; }
30 |
31 | uint64_t getColorTime() const { return _colorTime; }
32 |
33 | void setFrame(const uint frame) { }
34 |
35 | void advance();
36 |
37 | bool hasRadialDistortionParams() const { return false; }
38 |
39 | float getScaleToMeters() const { return 1.e-3; }
40 |
41 | private:
42 | void updateDepth(DepthSense::DepthNode node, DepthSense::DepthNode::NewSampleReceivedData data);
43 | void updateColor(DepthSense::ColorNode node, DepthSense::ColorNode::NewSampleReceivedData data);
44 |
45 | DepthSense::Context _context;
46 | DepthSense::Device _device;
47 | DepthSense::DepthNode _depthNode;
48 | DepthSense::ColorNode _colorNode;
49 | uint64_t _colorTime;
50 | uint64_t _depthTime;
51 | pthread_mutex_t _depthMutex;
52 | pthread_mutex_t _colorMutex;
53 | ushort * _depthData;
54 | ushort * _deviceDepthData;
55 | uchar3 * _colorData;
56 |
57 | ushort * _nextDepthData;
58 | uint64_t _nextDepthTime;
59 | uchar3 * _nextColorData;
60 | uint64_t _nextColorTime;
61 | };
62 |
63 | }
64 |
65 | #endif // DEPTHSENSE_DEPTH_SOURCE_H
66 |
--------------------------------------------------------------------------------
/src/depth_sources/openni_depth_source.h:
--------------------------------------------------------------------------------
1 | #ifndef OPENNI_DEPTH_SOURCE_H
2 | #define OPENNI_DEPTH_SOURCE_H
3 |
4 | #include "depth_source.h"
5 | #include
6 | #include
7 |
8 | namespace dart {
9 |
10 | class OpenNIDepthSource : public DepthSource {
11 | public:
12 | OpenNIDepthSource();
13 |
14 | ~OpenNIDepthSource();
15 |
16 | bool initialize(const char * deviceURI = openni::ANY_DEVICE,
17 | const bool getColor = true,
18 | const uint depthWidth = 640,
19 | const uint depthHeight = 480,
20 | const uint depthFPS = 30,
21 | const uint colorWidth = 640,
22 | const uint colorHeight = 480,
23 | const uint colorFPS = 30,
24 | const bool mirror = false,
25 | const bool frameSync = true,
26 | const bool registerDepth = true);
27 |
28 | const ushort * getDepth() const;
29 |
30 | const ushort * getDeviceDepth() const;
31 |
32 | const uchar3 * getColor() const;
33 |
34 | ColorLayout getColorLayout() const { return LAYOUT_RGB; }
35 |
36 | uint64_t getDepthTime() const;
37 |
38 | uint64_t getColorTime() const;
39 |
40 | void setFrame(const uint frame);
41 |
42 | void advance();
43 |
44 | bool hasRadialDistortionParams() const { return false; }
45 |
46 | inline float getScaleToMeters() const { return 1/(1000.0f); }
47 |
48 | private:
49 | openni::Device _device;
50 | openni::VideoStream _depthStream;
51 | openni::VideoStream _colorStream;
52 | openni::VideoFrameRef _depthFrame;
53 | openni::VideoFrameRef _colorFrame;
54 | int _frameIndexOffset;
55 | ushort * _deviceDepth;
56 | };
57 |
58 | }
59 |
60 | #endif // OPENNI_DEPTH_SOURCE_H
61 |
--------------------------------------------------------------------------------
/src/depth_sources/pango_depth_source.h:
--------------------------------------------------------------------------------
1 | #ifndef PVN_DEPTH_SOURCE_H
2 | #define PVN_DEPTH_SOURCE_H
3 |
4 | #include "depth_source.h"
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include "util/string_format.h"
17 |
18 | #include "util/image_io.h"
19 | #include "util/mirrored_memory.h"
20 | #include "vector_types.h"
21 |
22 | namespace dart{
23 |
24 | template
25 | class PangoDepthSource : public DepthSource {
26 | public:
27 | PangoDepthSource();
28 |
29 | ~PangoDepthSource();
30 |
31 | bool initialize(const std::string & pangoFilename,
32 | const float2 focalLength,
33 | const float2 principalPoint = make_float2(0,0),
34 | const uint depthWidth = 0,
35 | const uint depthHeight = 0,
36 | const float scaleToMeters = 1.f);
37 |
38 | #ifdef CUDA_BUILD
39 | const DepthType * getDepth() const { return _depthData->hostPtr(); }
40 | const DepthType * getDeviceDepth() const { return _depthData->devicePtr(); }
41 | #else
42 | const DepthType * getDepth() const { return _depthData; }
43 | const DepthType * getDeviceDepth() const { return 0; }
44 | #endif // CUDA_BUILD
45 |
46 | //const ColorType * getColor() const { return _colorData; }
47 |
48 | //ColorLayout getColorLayout() const { return LAYOUT_RGB; }
49 |
50 | uint64_t getDepthTime() const { return _depthTimes[this->_frame]; }
51 |
52 | //uint64_t getColorTime() const { return _colorTimes[this->_frame]; }
53 |
54 | void setFrame(const uint frame);
55 |
56 | void advance();
57 |
58 | bool hasRadialDistortionParams() const { return false; }
59 |
60 | float getScaleToMeters() const { return _scaleToMeters; }
61 |
62 | private:
63 |
64 | void readDepth();
65 | //void readColor();
66 |
67 | #ifdef CUDA_BUILD
68 | MirroredVector * _depthData;
69 | #else
70 | DepthType * _depthData;
71 | #endif // CUDA_BUILD
72 | uint _firstDepthFrame;
73 | uint _lastDepthFrame;
74 | std::string _pangoFilename;
75 | float _scaleToMeters;
76 | std::vector _depthTimes;
77 |
78 | pangolin::VideoRecordRepeat _video;
79 | };
80 |
81 | // Implementation
82 | template
83 | PangoDepthSource::PangoDepthSource() :
84 | DepthSource(),
85 | _firstDepthFrame(0),
86 | _depthData(0) {}
87 |
88 | template
89 | PangoDepthSource::~PangoDepthSource() {
90 | #ifdef CUDA_BUILD
91 | delete _depthData;
92 | #else
93 | delete [] _depthData;
94 | #endif // CUDA_BUILD
95 | }
96 |
97 | template
98 | bool PangoDepthSource::initialize(
99 | const std::string & pangoFilename,
100 | const float2 focalLength,
101 | const float2 principalPoint,
102 | const uint depthWidth,
103 | const uint depthHeight,
104 | const float scaleToMeters){
105 |
106 | this->_frame = 0;
107 | _pangoFilename = pangoFilename;
108 | this->_focalLength = focalLength;
109 | _scaleToMeters = scaleToMeters;
110 |
111 | struct stat buffer;
112 | bool exists = (stat(pangoFilename.c_str(), &buffer) == 0);
113 | if(!exists){
114 | std::cerr << "pangolin file not found" << std::endl;
115 | return false;
116 | }
117 |
118 | std::string uri = std::string("file://") + _pangoFilename;
119 | _video.Open(uri);
120 |
121 | // set depth dimensions
122 | if(depthWidth > 0 && depthHeight > 0) {
123 | this->_depthWidth = depthWidth;
124 | this->_depthHeight = depthHeight;
125 | }
126 | else{
127 | this->_depthWidth = _video.Width();
128 | this->_depthHeight = _video.Height();
129 | }
130 |
131 | // set principal point
132 | if(principalPoint.x == 0) {
133 | this->_principalPoint = make_float2(
134 | this->_depthWidth/2, this->_depthHeight/2);
135 | } else {
136 | this->_principalPoint = principalPoint;
137 | }
138 |
139 | // allocate data
140 | #ifdef CUDA_BUILD
141 | _depthData = new MirroredVector(
142 | this->_depthWidth*this->_depthHeight);
143 | #else
144 | _depthData = new DepthType[this->_depthWidth*this->_depthHeight];
145 | #endif // CUDA_BUILD
146 |
147 | return true;
148 | }
149 |
150 | template
151 | void PangoDepthSource::setFrame(const uint frame) {
152 | //this->_frame = frame;
153 | pangolin::VideoPlaybackInterface * playback =
154 | _video.Cast();
155 | playback->Seek(frame);
156 |
157 | readDepth();
158 | #ifdef CUDA_BUILD
159 | _depthData->syncHostToDevice();
160 | #endif // CUDA_BUILD
161 |
162 | this->_frame = playback->GetCurrentFrameId();
163 | }
164 |
165 | template
166 | void PangoDepthSource::advance() {
167 | pangolin::VideoPlaybackInterface * playback =
168 | _video.Cast();
169 | if(this->_frame == playback->GetTotalFrames()){
170 | //if(this->_frame == 90){
171 | playback->Seek(0);
172 | }
173 |
174 | readDepth();
175 | #ifdef CUDA_BUILD
176 | _depthData->syncHostToDevice();
177 | #endif // CUDA_BUILD
178 |
179 | this->_frame = playback->GetCurrentFrameId();
180 | }
181 |
182 | template
183 | void PangoDepthSource::readDepth() {
184 | std::vector > tmp(1);
185 | _video.Grab((unsigned char*) _depthData->hostPtr(), tmp);
186 | }
187 |
188 | }
189 |
190 | #endif
191 |
--------------------------------------------------------------------------------
/src/geometry/geometry.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_H
2 | #define GEOMETRY_H
3 |
4 | //#include
5 | #include
6 | #include "util/vector_type_template.h"
7 |
8 | namespace dart {
9 |
10 | //----------------------------------------------------------------------------
11 | // Distance to ellipsoid functions
12 | //----------------------------------------------------------------------------
13 |
14 | //----------------------------------------------------------------------------
15 | // The ellipse is (x0/e0)^2 + (x1/e1)^2 = 1 with e0 >= e1. The query point is
16 | // (y0,y1) with y0 >= 0 and y1 >= 0. The function returns the distance from
17 | // the query point to the ellipse. It also computes the ellipse point (x0,x1)
18 | // in the first quadrant that is closest to (y0,y1).
19 | //----------------------------------------------------------------------------
20 | template
21 | Real distancePointEllipseSpecial(const Real e[2], const Real y[2], Real x[2]);
22 |
23 | //----------------------------------------------------------------------------
24 | // The ellipse is (x0/e0)^2 + (x1/e1)^2 = 1. The query point is (y0,y1).
25 | // The function returns the distance from the query point to the ellipse.
26 | // It also computes the ellipse point (x0,x1) that is closest to (y0,y1).
27 | //----------------------------------------------------------------------------
28 | template
29 | Real distancePointEllipse(const Real e[2], const Real y[2], Real x[2]);
30 |
31 | //----------------------------------------------------------------------------
32 | // The ellipsoid is (x0/e0)^2 + (x1/e1)^2 + (x2/e2)^2 = 1 with e0 >= e1 >= e2.
33 | // The query point is (y0,y1,y2) with y0 >= 0, y1 >= 0, and y2 >= 0. The
34 | // function returns the distance from the query point to the ellipsoid. It
35 | // also computes the ellipsoid point (x0,x1,x2) in the first octant that is
36 | // closest to (y0,y1,y2).
37 | //----------------------------------------------------------------------------
38 | template
39 | Real distancePointEllipsoidSpecial(const Real e[3], const Real y[3], Real x[3]);
40 |
41 | //----------------------------------------------------------------------------
42 | // The ellipsoid is (x0/e0)^2 + (x1/e1)^2 + (x2/e2)^2 = 1. The query point is
43 | // (y0,y1,y2). The function returns the distance from the query point to the
44 | // ellipsoid. It also computes the ellipsoid point (x0,x1,x2) that is
45 | // closest to (y0,y1,y2).
46 | //----------------------------------------------------------------------------
47 | template
48 | Real distancePointEllipsoid(const Real e[3], const Real y[3], Real x[3]);
49 |
50 |
51 | float distancePointTriangle(const float3 p, const float3 A, const float3 B, const float3 C);
52 |
53 | float distancePointTriangle(const float3 p, const float3 A, const float3 B, const float3 C, float & s, float & t);
54 |
55 | float distancePointTriangle(const float3 p, const float3 A, const float3 B, const float3 C, float3 & D);
56 |
57 | template
58 | Real distancePointLineSegment2D(const typename VectorTypeTemplate::type2 p,
59 | const typename VectorTypeTemplate::type2 a,
60 | const typename VectorTypeTemplate::type2 b );
61 |
62 | template
63 | Real signedDistancePointLineSegment2D(const typename VectorTypeTemplate::type2 p,
64 | const typename VectorTypeTemplate::type2 a,
65 | const typename VectorTypeTemplate::type2 b );
66 |
67 |
68 | //----------------------------------------------------------------------------
69 | // Rodrigues (axis-angle) matrix functions
70 | //----------------------------------------------------------------------------
71 | //template
72 | //inline void rotationMatrixFromRodrigues(const Real w[3], Eigen::MatrixBase const &R);
73 |
74 | //template
75 | //inline void rodriguesFromRotationMatrix(Real w[3], Eigen::MatrixBase const &R);
76 |
77 | //----------------------------------------------------------------------------
78 | // This calculates the derivative of a rotation matrix derived from the given
79 | // set of Rodrigues parameters, relative to those three parameters. The
80 | // computed Jacobian is stacked such that the top 3x3 matrix is the derivative
81 | // of the rotation w.r.t. wx, the next 3x3 matrix is the derivative w.r.t. wy,
82 | // and the bottom 3x3 is the derivative w.r.t. wz.
83 | //----------------------------------------------------------------------------
84 | //template
85 | //void rotationMatrixJacobianFromRodrigues(const Real w[3], Eigen::Matrix &J);
86 |
87 | //----------------------------------------------------------------------------
88 | // Axis-aligned bounding box (AABB) functions
89 | //----------------------------------------------------------------------------
90 |
91 | //----------------------------------------------------------------------------
92 | // This function calculates the axis aligned bounding box of an ellipse
93 | // specified by ((x0-c0)/e0)^2 + ((x1-c1)/e1)^2 + ((x2-c2)/e2)^2 <= 1, which
94 | // has also undergone a rotation specified by Rodrigues parameters (wx,wy,wz).
95 | // The bounding box has origin (o0,o1,o2) and size (s0,s1,s2).
96 | //----------------------------------------------------------------------------
97 | template
98 | void aabbEllipsoid(const Real e[3], const Real c[3], const Real w[3], Real o[3], Real s[3]);
99 |
100 | //----------------------------------------------------------------------------
101 | // This function calculates the axis aligned bounding box of an elliptic
102 | // cylinder with end caps specified by ((x0-c0)/e0)^2 + ((x1-c1)/e1)^2 <= 1.
103 | // The end caps are centered at (c0,c1,0) and (c0,c1,h), and the cylinder has
104 | // also undergone a rotation specified by Rodrigues parameters (wx,wy,wx). It
105 | // is assumed the rotation is about the point (c0,c1,0), i.e. the center of
106 | // the lower end cap.
107 | //----------------------------------------------------------------------------
108 | template
109 | void aabbEllipticCylinder(const Real e[2], const Real h, const Real c[3], const Real w[3], Real o[3], Real s[3]);
110 |
111 | template
112 | void aabbRectangularPrism(const Real l[3], const Real c[3], const Real w[3], Real o[3], Real s[3]);
113 |
114 | //----------------------------------------------------------------------------
115 | // Geometry-generating functions
116 | //----------------------------------------------------------------------------
117 | void generateUnitIcosphere(float3 * & verts, int3 * & indxs, int & nverts, int & nfaces, const int splits);
118 |
119 | }
120 |
121 | #endif // GEOMETRY_H
122 |
--------------------------------------------------------------------------------
/src/geometry/grid_2d.h:
--------------------------------------------------------------------------------
1 | #ifndef GRID_2D_H
2 | #define GRID_2D_H
3 |
4 | #include
5 | #include
6 | #include "util/vector_operators.h"
7 | #include "util/vector_type_template.h"
8 | #include "util/prefix.h"
9 |
10 | namespace dart {
11 |
12 | template
13 | class Grid2D {
14 |
15 | private:
16 | typedef typename VectorTypeTemplate::type2 T2;
17 |
18 | public:
19 |
20 | // ===== constructors / destructor =====
21 | PREFIX Grid2D() : dim(make_uint2(0,0)), offset(make_float2(0,0)), resolution(0), data(0) {}
22 | PREFIX Grid2D(uint2 dim) : dim(dim), offset(make_float2(0,0)), resolution(0), data(new T[dim.x*dim.y]) {}
23 | PREFIX Grid2D(uint2 dim, float2 offset, float resolution) : dim(dim), offset(offset), resolution(resolution), data(new T[dim.x*dim.y]) {}
24 | PREFIX Grid2D(const Grid2D & grid) : dim(grid.dim), offset(grid.offset), resolution(grid.resolution), data(new T[grid.dim.x*grid.dim.y]) {
25 | memcpy(data, grid.data, dim.x*dim.y*sizeof(T));
26 | }
27 | PREFIX ~Grid2D() { delete [] data; }
28 |
29 | // ===== inline member functions =====
30 | inline PREFIX Grid2D & operator= (const Grid2D & grid) {
31 | if (this == &grid) {
32 | return *this;
33 | }
34 | delete [] data;
35 | dim = grid.dim;
36 | offset = grid.offset;
37 | resolution = grid.resolution;
38 | data = new T[dim.x*dim.y];
39 | memcpy(grid.data,data,dim.x*dim.y*sizeof(T));
40 | return *this;
41 | }
42 |
43 | inline PREFIX float2 getGridCoords(const float2 & pWorld) const {
44 | return (pWorld - offset)/resolution;
45 | }
46 |
47 | inline PREFIX float2 getWorldCoords(const float2 & pGrid) const {
48 | return resolution*pGrid + offset;
49 | }
50 |
51 | inline PREFIX bool isInBounds(const float2 & pGrid) const {
52 | return (pGrid.x > 0 && pGrid.x < dim.x &&
53 | pGrid.y > 0 && pGrid.y < dim.y);
54 | }
55 |
56 | inline PREFIX bool isInBoundsInterp(const float2 & pGrid) const {
57 | return (pGrid.x > 0.50001 && pGrid.x < dim.x - 0.50001 &&
58 | pGrid.y > 0.50001 && pGrid.y < dim.y - 0.50001);
59 | }
60 |
61 | inline PREFIX bool isInBoundsGradient(const float2 & pGrid) const {
62 | return (pGrid.x > 1.50001 && pGrid.x < dim.x - 1.50001 &&
63 | pGrid.y > 1.50001 && pGrid.y < dim.y - 1.50001);
64 | }
65 |
66 | // TODO: figure out what these values should really be
67 | inline PREFIX bool isInBoundsGradientInterp(const float2 & pGrid) const {
68 | return (pGrid.x > 2.50001 && pGrid.x < dim.x - 2.50001 &&
69 | pGrid.y > 2.50001 && pGrid.y < dim.y - 2.50001);
70 | }
71 |
72 | inline PREFIX T & getValue(const int2 & v) const {
73 | return data[v.x + dim.x*v.y];
74 | }
75 |
76 | inline PREFIX T getValueInterpolated(const float2 & pGrid) const {
77 |
78 | const int x0 = (int)(pGrid.x-0.5); const float fx = (pGrid.x-0.5) - x0;
79 | const int y0 = (int)(pGrid.y-0.5); const float fy = (pGrid.y-0.5) - y0;
80 |
81 | const int x1 = x0 + 1;
82 | const int y1 = y0 + 1;
83 |
84 | if ( !(x0 >= 0 && x1 < dim.x && y0 >= 0 && y1 < dim.y) ) {
85 | printf("nope (%d)\n",isInBoundsInterp(pGrid));
86 | }
87 |
88 | const float dx0 = lerp( getValue(make_int2(x0,y0)), getValue(make_int2(x1,y0)), fx);
89 | const float dx1 = lerp( getValue(make_int2(x0,y1)), getValue(make_int2(x1,y1)), fx);
90 | const float dxy = lerp( dx0, dx1, fy );
91 |
92 | return dxy;
93 |
94 | }
95 |
96 | inline PREFIX T2 getGradient(const int2 & v) const {
97 |
98 | T2 grad;
99 |
100 | if (v.x == 0) {
101 | grad.x = data[v.x+1 + v.y*dim.x] - data[v.x + v.y*dim.x];
102 | } else if (v.x == dim.x - 1) {
103 | grad.x = data[v.x + v.y*dim.x] - data[v.x-1 + v.y*dim.x];
104 | } else {
105 | grad.x = 0.5*(data[v.x+1 + v.y*dim.x] - data[v.x-1 + v.y*dim.x]);
106 | }
107 |
108 | if (v.y == 0) {
109 | grad.y = data[v.x + (v.y+1)*dim.x] - data[v.x + v.y*dim.x];
110 | } else if (v.y == dim.y - 1) {
111 | grad.y = data[v.x + v.y*dim.x] - data[v.x + (v.y-1)*dim.x];
112 | } else {
113 | grad.y = 0.5*(data[v.x + (v.y+1)*dim.x] - data[v.x + (v.y-1)*dim.x]);
114 | }
115 |
116 | return grad;
117 |
118 | }
119 |
120 | inline PREFIX T2 getGradientInterpolated(const float2 & pGrid) const {
121 |
122 | T f_px = getValueInterpolated(pGrid + make_float2(1,0));
123 | T f_py = getValueInterpolated(pGrid + make_float2(0,1));
124 |
125 | T f_mx = getValueInterpolated(pGrid - make_float2(1,0));
126 | T f_my = getValueInterpolated(pGrid - make_float2(0,1));
127 |
128 | T2 grad;
129 | grad.x = 0.5*(f_px - f_mx);
130 | grad.y = 0.5*(f_py - f_my);
131 | return grad;
132 |
133 | }
134 |
135 | // ===== data members =====
136 | uint2 dim;
137 | float2 offset;
138 | float resolution;
139 | T * data;
140 |
141 | };
142 |
143 | } // namespace dart
144 |
145 | #endif // GRID_2D_H
146 |
--------------------------------------------------------------------------------
/src/geometry/plane_fitting.cpp:
--------------------------------------------------------------------------------
1 | #include "plane_fitting.h"
2 |
3 | #include
4 | #include "util/mirrored_memory.h"
5 |
6 | namespace dart {
7 |
8 | void fitPlane(float3 & planeNormal,
9 | float & planeIntercept,
10 | const float4 * dObsVertMap,
11 | const float4 * dObsNormMap,
12 | const int width,
13 | const int height,
14 | const float distanceThreshold,
15 | const float normalThreshold,
16 | const int maxIters,
17 | const float regularization,
18 | int * dbgAssociated) {
19 |
20 | dart::MirroredVector result(4 + 16 + 1);
21 |
22 |
23 | for (int iter=0; iter
4 | #include
5 | #include
6 | #include
7 |
8 | namespace dart {
9 |
10 | // -=-=-=-=- kernel -=-=-=-=-
11 | template
12 | __global__ void gpu_fitPlane(const float3 planeNormal,
13 | const float planeIntercept,
14 | const float4 * obsVertMap,
15 | const float4 * obsNormMap,
16 | const int width,
17 | const int height,
18 | const float distanceThreshold,
19 | const float normalThreshold,
20 | float * result,
21 | int * dbgAssociated) {
22 |
23 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
24 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
25 |
26 | if (x >= width || y >= height) {
27 | return;
28 | }
29 |
30 | const int index = x + y*width;
31 | if (dbgAssoc) { dbgAssociated[index] = 0; }
32 |
33 | if (obsVertMap[index].w == 0 || obsNormMap[index].w == 0) {
34 | return;
35 | }
36 |
37 | float3 v = make_float3(obsVertMap[index]);
38 |
39 | float dist = dot(planeNormal,v) - planeIntercept;
40 | if (fabs(dist) > distanceThreshold) {
41 | return;
42 | }
43 |
44 | float3 n = make_float3(obsNormMap[index]);
45 | if (dot(planeNormal,n) < normalThreshold) {
46 | return;
47 | }
48 |
49 | if (dbgAssoc) { dbgAssociated[index] = 1; }
50 |
51 | float J[4];
52 | J[0] = v.x;
53 | J[1] = v.y;
54 | J[2] = v.z;
55 | J[3] = -1;
56 |
57 | float * eJ = result;
58 | float * JTJ = &result[4];
59 | float * e = &result[4 + 16];
60 |
61 | for (int i=0; i<4; ++i) {
62 | float ejVal = dist*J[i];
63 | atomicAdd(&eJ[i],ejVal);
64 | for (int j=0; j<4; ++j) {
65 | float jtjVal = J[i]*J[j];
66 | atomicAdd(&JTJ[i*4 + j],jtjVal);
67 | }
68 | }
69 |
70 | atomicAdd(e,dist*dist);
71 | }
72 |
73 | __global__ void gpu_subtractPlane(float4 * obsVertMap,
74 | float4 * obsNormMap,
75 | const int width,
76 | const int height,
77 | const float3 planeNormal,
78 | const float planeIntercept,
79 | const float distanceThreshold,
80 | const float normalThreshold) {
81 |
82 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
83 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
84 |
85 | if (x >= width || y >= height) {
86 | return;
87 | }
88 |
89 | const int index = x + y*width;
90 |
91 | float3 v = make_float3(obsVertMap[index]);
92 |
93 | float dist = dot(planeNormal,v) - planeIntercept;
94 | //if (fabs(dist) > distanceThreshold) {
95 | if (dist > distanceThreshold) {
96 | return;
97 | }
98 |
99 | if (obsNormMap[index].w == 1.0) {
100 | float3 n = make_float3(obsNormMap[index]);
101 | if (dot(planeNormal,n) < normalThreshold) {
102 | return;
103 | }
104 | }
105 |
106 | obsVertMap[index].w = -1.0f;
107 | obsNormMap[index].w = -1.0f;
108 |
109 | }
110 |
111 | // -=-=-=-=- interface -=-=-=-=-
112 | void fitPlaneIter(const float3 planeNormal,
113 | const float planeIntercept,
114 | const float4 * dObsVertMap,
115 | const float4 * dObsNormMap,
116 | const int width,
117 | const int height,
118 | const float distanceThreshold,
119 | const float normalThreshold,
120 | const float regularization,
121 | float * dResult,
122 | int * dbgAssociated) {
123 |
124 | dim3 block(16,8,1);
125 | dim3 grid( ceil( width / (float)block.x), ceil(height / (float)block.y ));
126 |
127 | if (dbgAssociated == 0) {
128 | gpu_fitPlane<<>>(planeNormal,
129 | planeIntercept,
130 | dObsVertMap,
131 | dObsNormMap,
132 | width,
133 | height,
134 | distanceThreshold,
135 | normalThreshold,
136 | dResult,
137 | dbgAssociated);
138 | } else {
139 | gpu_fitPlane<<>>(planeNormal,
140 | planeIntercept,
141 | dObsVertMap,
142 | dObsNormMap,
143 | width,
144 | height,
145 | distanceThreshold,
146 | normalThreshold,
147 | dResult,
148 | dbgAssociated);
149 | }
150 |
151 |
152 | }
153 |
154 | void subtractPlane_(float4 * dObsVertMap,
155 | float4 * dObsNormMap,
156 | const int width,
157 | const int height,
158 | const float3 planeNormal,
159 | const float planeIntercept,
160 | const float distanceThreshold,
161 | const float normalThreshold) {
162 |
163 | dim3 block(16,8,1);
164 | dim3 grid( ceil( width / (float)block.x), ceil(height / (float)block.y ));
165 |
166 | gpu_subtractPlane<<>>(dObsVertMap,
167 | dObsNormMap,
168 | width,
169 | height,
170 | planeNormal,
171 | planeIntercept,
172 | distanceThreshold,
173 | normalThreshold);
174 |
175 | }
176 |
177 | }
178 |
--------------------------------------------------------------------------------
/src/geometry/plane_fitting.h:
--------------------------------------------------------------------------------
1 | #ifndef PLANE_FITTING_H
2 | #define PLANE_FITTING_H
3 |
4 | #include
5 |
6 | namespace dart {
7 |
8 | void fitPlane(float3 & planeNormal,
9 | float & planeIntercept,
10 | const float4 * dObsVertMap,
11 | const float4 * dObsNormMap,
12 | const int width,
13 | const int height,
14 | const float distanceThreshold,
15 | const float normalThreshold,
16 | const int maxIters,
17 | const float regularization,
18 | int * dbgAssociated = 0);
19 |
20 | void fitPlaneIter(const float3 planeNormal,
21 | const float planeIntercept,
22 | const float4 * dObsVertMap,
23 | const float4 * dObsNormMap,
24 | const int width,
25 | const int height,
26 | const float distanceThreshold,
27 | const float normalThreshold,
28 | const float regularization,
29 | float * dResult,
30 | int * dbgAssocaited);
31 |
32 | void subtractPlane_(float4 * dObsVertMap,
33 | float4 * dObsNormMap,
34 | const int width,
35 | const int height,
36 | const float3 planeNormal,
37 | const float planeIntercept,
38 | const float distanceThreshold,
39 | const float normalThreshold);
40 |
41 | }
42 |
43 | #endif // PLANE_FITTING_H
44 |
--------------------------------------------------------------------------------
/src/geometry/sdf.h:
--------------------------------------------------------------------------------
1 | #ifndef SDF_H
2 | #define SDF_H
3 |
4 | #include "geometry/SE3.h"
5 | #include "grid_3d.h"
6 | #include "mesh/mesh.h"
7 |
8 | namespace dart {
9 |
10 | void projectToSdfSurface(const Grid3D & sdf, float3 & pointGrid, const float threshold = 1e-5, const int maxIters = 100);
11 |
12 | void analyticMeshSdf(Grid3D & sdf, const Mesh & mesh);
13 |
14 | void analyticBoxSdf(Grid3D & sdf, SE3 T_bg, const float3 boxMin, const float3 boxMax);
15 |
16 | void analyticSphereSdf(Grid3D & sdf, SE3 T_sg, const float sphereRadius);
17 |
18 | }
19 |
20 | #endif // SDF_H
21 |
--------------------------------------------------------------------------------
/src/img_proc/bilateral_filter.cu:
--------------------------------------------------------------------------------
1 | #include "bilateral_filter.h"
2 |
3 | #include
4 | #include
5 |
6 | namespace dart {
7 |
8 | template
9 | __global__ void gpu_bilateralFilter(const T * depthIn,
10 | float * depthOut,
11 | const int width,
12 | const int height,
13 | const float domainFactor,
14 | const float rangeFactor) {
15 |
16 | const int twidth = 16;
17 | const int theight = 16;
18 | const int swidth = twidth+8;
19 | const int sheight = theight+8;
20 | const int nreads = (swidth*sheight)/(twidth*theight);
21 |
22 | __shared__ T sdata[swidth*sheight];
23 |
24 | const int tid = threadIdx.y*blockDim.x + threadIdx.x;
25 |
26 | for (int i=0; i<=nreads; i++) {
27 | const int readi = tid + i*twidth*theight;
28 | if (readi < swidth*sheight) {
29 | const int row = readi / swidth;
30 | const int col = readi % swidth;
31 | const int x = blockIdx.x*blockDim.x - 4 + col;
32 | const int y = blockIdx.y*blockDim.y - 4 + row;
33 | if (x >= 0 && x < width && y >=0 && y < height) {
34 | sdata[readi] = depthIn[x + y*width];
35 | }
36 | }
37 | }
38 |
39 | __syncthreads();
40 |
41 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
42 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
43 | const int index = x + y*width;
44 |
45 | const int bx = threadIdx.x + 4;
46 | const int by = threadIdx.y + 4;
47 |
48 | float d = sdata[bx + by*swidth];
49 |
50 | if (d > 0) {
51 |
52 | float new_d = 0;
53 | float total_weight = 0;
54 |
55 | int min_dx = max(-4,-x);
56 | int max_dx = min(4,width-x-1);
57 | int min_dy = max(-4,-y);
58 | int max_dy = min(4,height-y-1);
59 |
60 | for (int dy = min_dy; dy <= max_dy; dy++) {
61 | for (int dx = min_dx; dx <= max_dx; dx++) {
62 |
63 | float dd = sdata[bx + dx + (by+dy)*swidth];
64 |
65 | if ( dd > 0 ) {
66 |
67 | float rangeDist2 = (d-dd)*(d-dd);
68 | float domainDist2 = dx*dx + dy*dy;
69 |
70 | float weight = expf( -domainDist2*domainFactor - rangeDist2*rangeFactor);
71 |
72 | new_d += (weight*dd);
73 | total_weight += weight;
74 |
75 | }
76 |
77 | }
78 | }
79 |
80 | depthOut[index] = (new_d / total_weight);
81 |
82 | } else {
83 | depthOut[index] = 0;
84 | }
85 |
86 | }
87 |
88 | template
89 | void bilateralFilter(const T * depthIn, float * depthOut, const int width, const int height, const float sigmaDomain, const float sigmaRange) {
90 |
91 | dim3 block(16,16,1);
92 | dim3 grid( (width) / block.x, (height) / block.y);
93 |
94 | gpu_bilateralFilter<<>>(depthIn, depthOut, width, height, 1.0/(2*sigmaDomain*sigmaDomain), 1.0/(2*sigmaRange*sigmaRange));
95 |
96 | cudaDeviceSynchronize();
97 |
98 | cudaError_t err = cudaGetLastError();
99 | if (err != cudaSuccess) {
100 | std::cerr << "Error: " << cudaGetErrorString(err) << std::endl;
101 | }
102 |
103 | }
104 |
105 | template void bilateralFilter(const float * depthIn, float * depthOut, const int width, const int height, const float sigmaDomain, const float sigmaRange);
106 | template void bilateralFilter(const double * depthIn, float * depthOut, const int width, const int height, const float sigmaDomain, const float sigmaRange);
107 | template void bilateralFilter(const ushort * depthIn, float * depthOut, const int width, const int height, const float sigmaDomain, const float sigmaRange);
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/img_proc/bilateral_filter.h:
--------------------------------------------------------------------------------
1 | #ifndef BILATERAL_FILTER_H
2 | #define BILATERAL_FILTER_H
3 |
4 | namespace dart {
5 |
6 | template
7 | void bilateralFilter(const T * depthIn, float * depthOut, const int width, const int height, const float sigmaDomain, const float sigmaRange);
8 |
9 | }
10 |
11 | #endif // BILATERAL_FILTER_H
12 |
--------------------------------------------------------------------------------
/src/img_proc/img_ops.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tschmidt23/dart/37adc66580a15c5b438986d77621ebd8f5f450c3/src/img_proc/img_ops.cpp
--------------------------------------------------------------------------------
/src/img_proc/img_ops.cu:
--------------------------------------------------------------------------------
1 | #include "img_ops.h"
2 |
3 | namespace dart {
4 |
5 | // -=-=-=-=-=-=-=-=-=- kernels -=-=-=-=-=-=-=-=-=-
6 | __global__ void gpu_imageSquare(float * out, const float * in, const int width, const int height) {
7 |
8 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
9 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
10 |
11 | if (x >= width || y >= height) {
12 | return;
13 | }
14 |
15 | int index = x + y*width;
16 | out[index] = in[index]*in[index];
17 |
18 | }
19 |
20 | __global__ void gpu_imageSqrt(float * out, const float * in, const int width, const int height) {
21 |
22 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
23 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
24 |
25 | if (x >= width || y >= height) {
26 | return;
27 | }
28 |
29 | int index = x + y*width;
30 | out[index] = sqrtf(in[index]);
31 |
32 | }
33 |
34 | template
35 | __global__ void gpu_imageFlipX(T * out, const T * in, const int width, const int height) {
36 |
37 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
38 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
39 |
40 | if (x >= width || y >= height) {
41 | return;
42 | }
43 |
44 | out[x + y*width] = in[width - x + y*width];
45 |
46 | }
47 |
48 | template
49 | __global__ void gpu_imageFlipXInPlace(T * img, const int width, const int height) {
50 |
51 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
52 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
53 |
54 | if (x >= width/2 || y >= height) {
55 | return;
56 | }
57 |
58 | T tmp = img[x + y*width];
59 | img[x + y*width] = img[width - x + y*width];
60 | img[width - x + y*width] = tmp;
61 |
62 | }
63 |
64 | template
65 | __global__ void gpu_imageFlipY(T * out, const T * in, const int width, const int height) {
66 |
67 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
68 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
69 |
70 | if (x >= width || y >= height) {
71 | return;
72 | }
73 |
74 | out[x + y*width] = in[x + (height-y)*width];
75 |
76 | }
77 |
78 | template
79 | __global__ void gpu_imageFlipYInPlace(T * img, const int width, const int height) {
80 |
81 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
82 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
83 |
84 | if (x >= width || y >= height/2) {
85 | return;
86 | }
87 |
88 | T tmp = img[x + y*width];
89 | img[x + y*width] = img[x + (height-y)*width];
90 | img[x + (height-y)*width] = tmp;
91 |
92 | }
93 |
94 | template
95 | __global__ void gpu_unitNormalize(const T * in, T * out, const int width, const int height, const T zeroVal, const T range) {
96 |
97 | const int x = blockIdx.x*blockDim.x + threadIdx.x;
98 | const int y = blockIdx.y*blockDim.y + threadIdx.y;
99 |
100 | const int index = x + y*width;
101 | out[index] = fmaxf(fminf((in[index] - zeroVal)/range,(T)1),(T)0);
102 |
103 | }
104 |
105 | // -=-=-=-=-=-=-=-=-=- interface -=-=-=-=-=-=-=-=-=-
106 | void imageSquare(float * out, const float * in, const int width, const int height) {
107 |
108 | dim3 block(16,8,1);
109 | dim3 grid( ceil( width / (float)block.x), ceil( height / (float)block.y ));
110 |
111 | gpu_imageSquare<<>>(out,in,width,height);
112 | }
113 |
114 | void imageSqrt(float * out, const float * in, const int width, const int height) {
115 |
116 | dim3 block(16,8,1);
117 | dim3 grid( ceil( width / (float)block.x), ceil( height / (float)block.y ));
118 |
119 | gpu_imageSqrt<<>>(out,in,width,height);
120 |
121 | }
122 |
123 | template
124 | void imageFlipX(T * out, const T * in, const int width, const int height) {
125 |
126 | dim3 block(16,8,1);
127 |
128 | if (out == in) {
129 | dim3 grid( ceil( width/2 / (float)block.x), ceil( height / (float)block.y ));
130 | gpu_imageFlipXInPlace<<>>(out,width,height);
131 | }
132 | else {
133 | dim3 grid( ceil( width / (float)block.x), ceil( height / (float)block.y ));
134 | gpu_imageFlipX<<>>(out,in,width,height);
135 | }
136 |
137 | }
138 |
139 | template
140 | void imageFlipY(T * out, const T * in, const int width, const int height) {
141 |
142 | dim3 block(16,8,1);
143 |
144 | if (out == in) {
145 | dim3 grid( ceil( width / (float)block.x), ceil( height/2 / (float)block.y ));
146 | gpu_imageFlipYInPlace<<>>(out,width,height);
147 | }
148 | else {
149 | dim3 grid( ceil( width / (float)block.x), ceil( height / (float)block.y ));
150 | gpu_imageFlipY<<>>(out,in,width,height);
151 | }
152 |
153 | }
154 |
155 | template
156 | void unitNormalize(const T * in, T * out, const int width, const int height, const T zeroVal, const T oneVal) {
157 |
158 | dim3 block(16,16,1);
159 | dim3 grid( ceil((float)width / block.x), ceil((float)height / block.y));
160 |
161 | T range = oneVal - zeroVal;
162 |
163 | gpu_unitNormalize<<>>(in,out,width,height,zeroVal,range);
164 |
165 | cudaDeviceSynchronize();
166 |
167 | }
168 |
169 |
170 | #define COMPILE_IMAGE_OPS(type) \
171 | template void imageFlipX(type * out, const type * in, const int width, const int height); \
172 | template void imageFlipY(type * out, const type * in, const int width, const int height); \
173 | template void unitNormalize(const type * in, type * out, const int width, const int height, const type zeroVal, const type oneVal);
174 |
175 | COMPILE_IMAGE_OPS(float)
176 | COMPILE_IMAGE_OPS(ushort)
177 | //COMPILE_IMAGE_OPS(uchar3)
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/src/img_proc/img_ops.h:
--------------------------------------------------------------------------------
1 | #ifndef IMG_MATH_H
2 | #define IMG_MATH_H
3 |
4 | namespace dart {
5 |
6 | void imageSquare(float * out, const float * in, const int width, const int height);
7 |
8 | void imageSqrt(float * out, const float * in, const int width, const int height);
9 |
10 | template
11 | void imageFlipX(T * out, const T * in, const int width, const int height);
12 |
13 | template
14 | void imageFlipY(T * out, const T * in, const int width, const int height);
15 |
16 | template
17 | void unitNormalize(const T * in, T * out, const int width, const int height, const T zeroVal, const T oneVal);
18 |
19 |
20 | }
21 |
22 | #endif // IMG_MATH_H
23 |
--------------------------------------------------------------------------------
/src/img_proc/organized_point_cloud.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tschmidt23/dart/37adc66580a15c5b438986d77621ebd8f5f450c3/src/img_proc/organized_point_cloud.cpp
--------------------------------------------------------------------------------
/src/img_proc/organized_point_cloud.h:
--------------------------------------------------------------------------------
1 | #ifndef ORGANIZED_POINT_CLOUD_H
2 | #define ORGANIZED_POINT_CLOUD_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace dart {
9 |
10 | template
11 | void depthToVertices(const DepthType * depthIn, float4 * vertOut, const int width, const int height, const float2 pp, const float2 fl, const float2 range = make_float2(0,std::numeric_limits::infinity()));
12 |
13 | template
14 | void depthToVertices(const DepthType * depthIn, float4 * vertOut, const int width, const int height, const float2 pp, const float2 fl, const float2 range, const float scale);
15 |
16 | template
17 | void depthToVertices(const DepthType * depthIn, float4 * vertOut, const int width, const int height, const float * calibrationParams, const float2 range);
18 |
19 | template
20 | void depthToVertices(const DepthType * depthIn, float4 * vertOut, const int width, const int height, const float * calibrationParams, const float2 range, const float scale);
21 |
22 | void verticesToNormals(const float4 * vertIn, float4 * normOut, const int width, const int height);
23 |
24 | void eliminatePlane(float4 * verts, const float4 * norms, const int width, const int height, const float3 planeNormal, const float planeD, const float epsDist = 0.01, const float epsNorm = 0.1);
25 |
26 | void cropBox(float4 * verts, const int width, const int height, const float3 & boxMin, const float3 & boxMax);
27 |
28 | void maskPointCloud(float4 * verts, const int width, const int height, const int * mask);
29 |
30 | }
31 |
32 | #endif // ORGANIZED_POINT_CLOUD_H
33 |
--------------------------------------------------------------------------------
/src/img_proc/resampling.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tschmidt23/dart/37adc66580a15c5b438986d77621ebd8f5f450c3/src/img_proc/resampling.cpp
--------------------------------------------------------------------------------
/src/img_proc/resampling.h:
--------------------------------------------------------------------------------
1 | #ifndef RESAMPLING_H
2 | #define RESAMPLING_H
3 |
4 | #include
5 |
6 | namespace dart {
7 |
8 | void downsampleAreaAverage(const float * imgIn, const uint2 dimIn, float * imgOut, const int factor);
9 |
10 | void downsampleAreaAverage(const uchar3 * imgIn, const uint2 dimIn, uchar3 * imgOut, const int factor);
11 |
12 | void downsampleAreaAverage(const uchar4 * imgIn, const uint2 dimIn, uchar4 * imgOut, const int factor);
13 |
14 | void downsampleNearest(const float * imgIn, const uint2 dimIn, float * imgOut, const int factor);
15 |
16 | void downsampleNearest(const uchar3 * imgIn, const uint2 dimIn, uchar3 * imgOut, const int factor);
17 |
18 | void downsampleMin(const float * imgIn, const uint2 dimIn, float * imgOut, const int factor, bool ignoreZero = true);
19 |
20 | }
21 |
22 | #endif // RESAMPLING_H
23 |
24 |
--------------------------------------------------------------------------------
/src/mesh/assimp_mesh_reader.cpp:
--------------------------------------------------------------------------------
1 | #include "assimp_mesh_reader.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace dart {
10 |
11 | dart::Mesh * AssimpMeshReader::readMesh(const std::string filename) const {
12 |
13 | const struct aiScene * scene = aiImportFile(filename.c_str(),0); //aiProcess_JoinIdenticalVertices);
14 | if (scene == 0) {
15 | std::cerr << "error: " << aiGetErrorString() << std::endl;
16 | return 0;
17 | }
18 |
19 | if (scene->mNumMeshes != 1) {
20 | std::cerr << "there are " << scene->mNumMeshes << " meshes in " << filename << std::endl;
21 | aiReleaseImport(scene);
22 | return 0;
23 | }
24 |
25 | aiMesh * aiMesh = scene->mMeshes[0];
26 |
27 | dart::Mesh * mesh = new dart::Mesh(aiMesh->mNumVertices,aiMesh->mNumFaces);
28 |
29 | for (int f=0; fnFaces; ++f) {
30 | aiFace& face = aiMesh->mFaces[f];
31 | if (face.mNumIndices != 3) {
32 | std::cerr << filename << " is not a triangle mesh" << std::endl;
33 | delete mesh;
34 | aiReleaseImport(scene);
35 | return 0;
36 | }
37 | mesh->faces[f] = make_int3(face.mIndices[0],face.mIndices[1],face.mIndices[2]);
38 | }
39 | for (int v=0; vnVertices; ++v) {
40 | aiVector3D & vertex = aiMesh->mVertices[v];
41 | mesh->vertices[v] = make_float3(vertex.x,vertex.y,vertex.z);
42 | aiVector3D & normal = aiMesh->mNormals[v];
43 | mesh->normals[v] = make_float3(normal.x,normal.y,normal.z);
44 | }
45 |
46 | aiReleaseImport(scene);
47 |
48 | return mesh;
49 |
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/mesh/assimp_mesh_reader.h:
--------------------------------------------------------------------------------
1 | #ifndef ASSIMP_MESH_READER_H
2 | #define ASSIMP_MESH_READER_H
3 |
4 | #include "util/model_renderer.h"
5 |
6 | namespace dart {
7 |
8 | class AssimpMeshReader : public dart::MeshReader {
9 | public:
10 | dart::Mesh * readMesh(const std::string filename) const;
11 | };
12 |
13 | }
14 |
15 | #endif // ASSIMP_MESH_READER_H
16 |
--------------------------------------------------------------------------------
/src/mesh/mesh.cpp:
--------------------------------------------------------------------------------
1 | #include "mesh.h"
2 |
3 | #include
4 | #include
5 |
6 | namespace dart {
7 |
8 | void Mesh::writeToObjFile(const char * filename) {
9 |
10 | std::ofstream stream(filename);
11 | std::cout << "writing " << nVertices << " vertices to " << filename << std::endl;
12 | for (int v=0; v= nVertices || faces[f].y < 0 || faces[f].y >= nVertices || faces[f].z < 0 || faces[f].z >= nVertices) {
18 | std::cout << "face " << f << " has out-of-bounds vertices" << std::endl;
19 | }
20 | if (faces[f].x == faces[f].y || faces[f].y == faces[f].z || faces[f].z == faces[f].x) {
21 | std::cout << "face " << f << " has repeated vertices" << std::endl;
22 | }
23 | stream << "f " << faces[f].x+1 << "//" << faces[f].x+1 << " " << faces[f].y+1 << "//" << faces[f].y+1 << " " << faces[f].z+1 << "//" << faces[f].z+1 << std::endl;
24 | }
25 | stream.close();
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/mesh/mesh.h:
--------------------------------------------------------------------------------
1 | #ifndef MESH_H
2 | #define MESH_H
3 |
4 | #include
5 | #include
6 |
7 | namespace dart {
8 |
9 | class Mesh {
10 | public:
11 |
12 | /**
13 | * The default mesh constructor.
14 | * All data members are initialized to null pointers, and will need to be allocated later.
15 | */
16 | Mesh() : faces(0), vertices(0), normals(0), nVertices(0), nFaces(0) { }
17 |
18 | /**
19 | * Constructs a mesh with preallocated mesh data.
20 | * The arrays for vertices, normals, and faces are allocated to the appropriate size, but the values are undefined.
21 | * @param numVertices The number of vertices in the mesh.
22 | * @param numFaces The number of faces in the mesh.
23 | */
24 | Mesh(const int numVertices, const int numFaces) :
25 | faces(new int3[numFaces]),
26 | vertices(new float3[numVertices]),
27 | normals(new float3[numVertices]),
28 | nVertices(numVertices),
29 | nFaces(numFaces) { }
30 |
31 | Mesh(const Mesh & copy) :
32 | faces(new int3[copy.nFaces]),
33 | vertices(new float3[copy.nVertices]),
34 | normals(new float3[copy.nVertices]),
35 | nVertices(copy.nVertices),
36 | nFaces(copy.nFaces) {
37 | memcpy(faces,copy.faces,copy.nFaces*sizeof(int3));
38 | memcpy(vertices,copy.vertices,copy.nVertices*sizeof(float3));
39 | memcpy(normals,copy.normals,copy.nVertices*sizeof(float3));
40 | }
41 |
42 | ~Mesh() { delete faces; delete vertices; delete normals; }
43 |
44 | void writeToObjFile(const char * filename);
45 |
46 | /**
47 | * The face data array. Each entry defines a face consisting of three indices into the vertex array.
48 | */
49 | int3 * faces;
50 |
51 | /**
52 | * The vertex data array. Each entry defines a vertex.
53 | */
54 | float3 * vertices;
55 |
56 | /**
57 | * The normal data array. Each entry defines the normal of the corresponding entry in the vertex data array.
58 | */
59 | float3 * normals;
60 |
61 | /**
62 | * The number of vertices in the mesh.
63 | */
64 | int nVertices;
65 |
66 | /**
67 | * The number of faces in the mesh.
68 | */
69 | int nFaces;
70 | };
71 |
72 | }
73 |
74 | #endif // MESH_H
75 |
--------------------------------------------------------------------------------
/src/mesh/mesh_proc.cpp:
--------------------------------------------------------------------------------
1 | #include "mesh_proc.h"
2 |
3 | #include
4 | #include