forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
depth_image_to_point_cloud.h
135 lines (120 loc) · 5.53 KB
/
depth_image_to_point_cloud.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#pragma once
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "drake/common/drake_copyable.h"
#include "drake/math/rigid_transform.h"
#include "drake/perception/point_cloud.h"
#include "drake/systems/framework/context.h"
#include "drake/systems/framework/leaf_system.h"
#include "drake/systems/sensors/camera_info.h"
#include "drake/systems/sensors/image.h"
#include "drake/systems/sensors/pixel_types.h"
namespace drake {
namespace perception {
/// Converts a depth image to a point cloud.
///
/// @system
/// name: DepthImageToPointCloud
/// input_ports:
/// - depth_image
/// - color_image (optional)
/// - camera_pose (optional)
/// output_ports:
/// - point_cloud
/// @endsystem
///
/// The system has an input port that takes a depth image, an optional input
/// port that takes a color image, and an additional optional input port that
/// takes the camera_pose, X_PC. If the camera_pose input is connected, then
/// the point cloud is represented in the parent frame (e.g., if camera_pose is
/// the pose of the camera in the world frame, then the point_cloud output will
/// be a PointCloud in the world frame). If the camera_pose input is not
/// connected, the PointCloud will be represented in the camera frame. Note
/// that if a color image is provided, it must be in the same frame as the depth
/// image.
///
/// If a pixel is NaN, the converted point will be (NaN, NaN, NaN). If a pixel
/// is kTooClose or kTooFar (as defined by ImageTraits), the converted point
/// will be (+Inf, +Inf, +Inf). Note that this matches the convention used by
/// the Point Cloud Library (PCL).
///
/// @ingroup perception_systems
class DepthImageToPointCloud final : public systems::LeafSystem<double> {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(DepthImageToPointCloud)
/// Constructs the converter.
///
/// @param[in] camera_info The camera info.
/// @param[in] depth_pixel_type The pixel type of the depth image input.
/// Only 16U and 32F are supported.
/// @param[in] scale The depth image input is multiplied by this scale factor
/// before projecting to a point cloud. (This is useful for converting mm
/// to meters, etc.)
/// @param[in] fields The fields the point cloud contains.
explicit DepthImageToPointCloud(
const systems::sensors::CameraInfo& camera_info,
systems::sensors::PixelType depth_pixel_type =
systems::sensors::PixelType::kDepth32F,
float scale = 1.0, pc_flags::BaseFieldT fields = pc_flags::kXYZs);
/// Returns the abstract valued input port that expects either an
/// ImageDepth16U or ImageDepth32F (depending on the constructor argument).
const systems::InputPort<double>& depth_image_input_port() const {
return this->get_input_port(depth_image_input_port_);
}
/// Returns the abstract valued input port that expects an ImageRgba8U.
const systems::InputPort<double>& color_image_input_port() const {
return this->get_input_port(color_image_input_port_);
}
/// Returns the abstract valued input port that expects X_PC as a
/// RigidTransformd. (This input port does not necessarily need to be
/// connected; refer to the class overview for details.)
const systems::InputPort<double>& camera_pose_input_port() const {
return this->get_input_port(camera_pose_input_port_);
}
/// Returns the abstract valued output port that provides a PointCloud.
/// Only the channels passed into the constructor argument "fields" are
/// present.
const systems::OutputPort<double>& point_cloud_output_port() const {
return LeafSystem<double>::get_output_port(0);
}
/// Converts a depth image to a point cloud using direct arguments instead of
/// System input and output ports. The semantics are the same as documented
/// in the class overview and constructor.
///
/// @param[in,out] cloud Destination for point data; must not be nullptr.
/// The `cloud` will be resized to match the size of the depth image. The
/// `cloud` must have the XYZ channel enabled.
static void Convert(
const systems::sensors::CameraInfo& camera_info,
const std::optional<math::RigidTransformd>& camera_pose,
const systems::sensors::ImageDepth32F& depth_image,
const std::optional<systems::sensors::ImageRgba8U>& color_image,
const std::optional<float>& scale, PointCloud* cloud);
/// Converts a depth image to a point cloud using direct arguments instead of
/// System input and output ports. The semantics are the same as documented
/// in the class overview and constructor.
///
/// @param[in,out] cloud Destination for point data; must not be nullptr.
/// The `cloud` will be resized to match the size of the depth image. The
/// `cloud` must have the XYZ channel enabled.
static void Convert(
const systems::sensors::CameraInfo& camera_info,
const std::optional<math::RigidTransformd>& camera_pose,
const systems::sensors::ImageDepth16U& depth_image,
const std::optional<systems::sensors::ImageRgba8U>& color_image,
const std::optional<float>& scale, PointCloud* cloud);
private:
void CalcOutput16U(const systems::Context<double>&, PointCloud*) const;
void CalcOutput32F(const systems::Context<double>&, PointCloud*) const;
const systems::sensors::CameraInfo camera_info_;
const systems::sensors::PixelType depth_pixel_type_;
const float scale_;
const pc_flags::BaseFieldT fields_;
systems::InputPortIndex depth_image_input_port_{};
systems::InputPortIndex color_image_input_port_{};
systems::InputPortIndex camera_pose_input_port_{};
};
} // namespace perception
} // namespace drake