forked from IntelRealSense/librealsense
-
Notifications
You must be signed in to change notification settings - Fork 0
/
python.hpp
239 lines (216 loc) · 11.1 KB
/
python.hpp
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/* License: Apache 2.0. See LICENSE file in root directory.
Copyright(c) 2017 Intel Corporation. All Rights Reserved. */
#ifndef LIBREALSENSE_PYTHON_HPP
#define LIBREALSENSE_PYTHON_HPP
#include <pybind11/pybind11.h>
// convenience functions
#include <pybind11/operators.h>
// STL conversions
#include <pybind11/stl.h>
// std::chrono::*
#include <pybind11/chrono.h>
// makes certain STL containers opaque to prevent expensive copies
#include <pybind11/stl_bind.h>
// makes std::function conversions work
#include <pybind11/functional.h>
#define NAME pyrealsense2
#define SNAME "pyrealsense2"
// For rs2_format
#include "../include/librealsense2/h/rs_sensor.h"
namespace py = pybind11;
using namespace pybind11::literals;
// Hacky little bit of half-functions to make .def(BIND_DOWNCAST) look nice for binding as/is functions
#define BIND_DOWNCAST(class, downcast) "is_"#downcast, &rs2::class::is<rs2::downcast>).def("as_"#downcast, &rs2::class::as<rs2::downcast>
// Binding enums
const std::string rs2_prefix{ "rs2_" };
std::string make_pythonic_str(std::string str);
#define BIND_ENUM(module, rs2_enum_type, RS2_ENUM_COUNT, docstring) BIND_ENUM_CUSTOM( module, rs2_enum_type, 0, RS2_ENUM_COUNT-1, docstring)
#define BIND_ENUM_CUSTOM(module, rs2_enum_type, FIRST, LAST, docstring) \
static std::string rs2_enum_type##pyclass_name = std::string(#rs2_enum_type).substr(rs2_prefix.length()); \
/* Above 'static' is required in order to keep the string alive since py::class_ does not copy it */ \
py::enum_<rs2_enum_type> py_##rs2_enum_type(module, rs2_enum_type##pyclass_name.c_str(), docstring); \
/* std::cout << std::endl << "## " << rs2_enum_type##pyclass_name << ":" << std::endl; */ \
for (int i = FIRST; i <= LAST; i++) \
{ \
rs2_enum_type v = static_cast<rs2_enum_type>(i); \
const char* enum_name = rs2_enum_type##_to_string(v); \
auto python_name = make_pythonic_str(enum_name); \
py_##rs2_enum_type.value(python_name.c_str(), v); \
/* std::cout << " - " << python_name << std::endl; */ \
}
// Binding arrays and matrices
template<typename T, size_t SIZE>
void copy_raw_array(T(&dst)[SIZE], const std::array<T, SIZE>& src)
{
for (size_t i = 0; i < SIZE; i++)
{
dst[i] = src[i];
}
}
template<typename T, size_t NROWS, size_t NCOLS>
void copy_raw_2d_array(T(&dst)[NROWS][NCOLS], const std::array<std::array<T, NCOLS>, NROWS>& src)
{
for (size_t i = 0; i < NROWS; i++)
{
for (size_t j = 0; j < NCOLS; j++)
{
dst[i][j] = src[i][j];
}
}
}
template <typename T, size_t N>
std::string array_to_string(const T(&arr)[N])
{
std::ostringstream oss;
oss << "[";
for (int i = 0; i < N; i++)
{
if (i != 0)
oss << ", ";
oss << arr[i];
}
oss << "]";
return oss.str();
}
template <typename T, size_t N, size_t M>
std::string matrix_to_string(const T(&arr)[N][M])
{
std::ostringstream oss;
oss << "[";
for (int i = 0; i < N; i++)
{
if (i != 0)
oss << ", ";
oss << "[";
for (int j = 0; j < M; j++)
{
if (j != 0)
oss << ", ";
oss << arr[i][j];
}
oss << "]";
}
oss << "]";
return oss.str();
}
#define BIND_RAW_ARRAY_GETTER(T, member, valueT, SIZE) [](const T& self) -> const std::array<valueT, SIZE>& { return reinterpret_cast<const std::array<valueT, SIZE>&>(self.member); }
#define BIND_RAW_ARRAY_SETTER(T, member, valueT, SIZE) [](T& self, const std::array<valueT, SIZE>& src) { copy_raw_array(self.member, src); }
#define BIND_RAW_2D_ARRAY_GETTER(T, member, valueT, NROWS, NCOLS) [](const T& self) -> const std::array<std::array<valueT, NCOLS>, NROWS>& { return reinterpret_cast<const std::array<std::array<valueT, NCOLS>, NROWS>&>(self.member); }
#define BIND_RAW_2D_ARRAY_SETTER(T, member, valueT, NROWS, NCOLS) [](T& self, const std::array<std::array<valueT, NCOLS>, NROWS>& src) { copy_raw_2d_array(self.member, src); }
#define BIND_RAW_ARRAY_PROPERTY(T, member, valueT, SIZE) #member, BIND_RAW_ARRAY_GETTER(T, member, valueT, SIZE), BIND_RAW_ARRAY_SETTER(T, member, valueT, SIZE)
#define BIND_RAW_2D_ARRAY_PROPERTY(T, member, valueT, NROWS, NCOLS) #member, BIND_RAW_2D_ARRAY_GETTER(T, member, valueT, NROWS, NCOLS), BIND_RAW_2D_ARRAY_SETTER(T, member, valueT, NROWS, NCOLS)
// TODO: Fill in missing formats
// Map format->data type for various things
template <rs2_format> struct FmtToType { using type = uint8_t; }; // Default to uint8_t
#define MAP_FMT_TO_TYPE(F, T) template <> struct FmtToType<F> { using type = T; }
MAP_FMT_TO_TYPE(RS2_FORMAT_Z16, uint16_t);
//MAP_FMT_TO_TYPE(RS2_FORMAT_DISPARITY16, );
MAP_FMT_TO_TYPE(RS2_FORMAT_XYZ32F, float);
MAP_FMT_TO_TYPE(RS2_FORMAT_YUYV, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_RGB8, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_BGR8, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_RGBA8, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_BGRA8, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_Y8, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_Y16, uint16_t);
//MAP_FMT_TO_TYPE(RS2_FORMAT_RAW10, );
MAP_FMT_TO_TYPE(RS2_FORMAT_RAW16, uint16_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_RAW8, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_UYVY, uint8_t);
//MAP_FMT_TO_TYPE(RS2_FORMAT_MOTION_RAW, );
MAP_FMT_TO_TYPE(RS2_FORMAT_MOTION_XYZ32F, float);
//MAP_FMT_TO_TYPE(RS2_FORMAT_GPIO_RAW, );
//MAP_FMT_TO_TYPE(RS2_FORMAT_6DOF, );
MAP_FMT_TO_TYPE(RS2_FORMAT_DISPARITY32, float);
MAP_FMT_TO_TYPE(RS2_FORMAT_Y10BPACK, uint8_t);
MAP_FMT_TO_TYPE(RS2_FORMAT_DISTANCE, float);
//MAP_FMT_TO_TYPE(RS2_FORMAT_MJPEG, );
MAP_FMT_TO_TYPE(RS2_FORMAT_Y8I, uint8_t);
//MAP_FMT_TO_TYPE(RS2_FORMAT_Y12I, );
//MAP_FMT_TO_TYPE(RS2_FORMAT_INZI, );
MAP_FMT_TO_TYPE(RS2_FORMAT_INVI, uint8_t);
//MAP_FMT_TO_TYPE(RS2_FORMAT_W10, );
MAP_FMT_TO_TYPE(RS2_FORMAT_FG, uint16_t);
//MAP_FMT_TO_TYPE(RS2_FORMAT_Y411, ); // RS2_FORMAT_Y411 is 12 bit per pixel and don't fit to any type
template <rs2_format FMT> struct itemsize {
static constexpr size_t func() { return sizeof(typename FmtToType<FMT>::type); }
};
template <rs2_format FMT> struct fmtstring {
static const std::string func() { return py::format_descriptor<typename FmtToType<FMT>::type>::format(); }
};
template<template<rs2_format> class F>
/*constexpr*/ auto fmt_to_value(rs2_format fmt) -> typename std::result_of<decltype(&F<RS2_FORMAT_ANY>::func)()>::type {
switch (fmt) {
case RS2_FORMAT_Z16: return F<RS2_FORMAT_Z16>::func();
case RS2_FORMAT_DISPARITY16: return F<RS2_FORMAT_DISPARITY16>::func();
case RS2_FORMAT_XYZ32F: return F<RS2_FORMAT_XYZ32F>::func();
case RS2_FORMAT_YUYV: return F<RS2_FORMAT_YUYV>::func();
case RS2_FORMAT_RGB8: return F<RS2_FORMAT_RGB8>::func();
case RS2_FORMAT_BGR8: return F<RS2_FORMAT_BGR8>::func();
case RS2_FORMAT_RGBA8: return F<RS2_FORMAT_RGBA8>::func();
case RS2_FORMAT_BGRA8: return F<RS2_FORMAT_BGRA8>::func();
case RS2_FORMAT_Y8: return F<RS2_FORMAT_Y8>::func();
case RS2_FORMAT_Y16: return F<RS2_FORMAT_Y16>::func();
case RS2_FORMAT_RAW10: return F<RS2_FORMAT_RAW10>::func();
case RS2_FORMAT_RAW16: return F<RS2_FORMAT_RAW16>::func();
case RS2_FORMAT_RAW8: return F<RS2_FORMAT_RAW8>::func();
case RS2_FORMAT_UYVY: return F<RS2_FORMAT_UYVY>::func();
case RS2_FORMAT_MOTION_RAW: return F<RS2_FORMAT_MOTION_RAW>::func();
case RS2_FORMAT_MOTION_XYZ32F: return F<RS2_FORMAT_MOTION_XYZ32F>::func();
case RS2_FORMAT_GPIO_RAW: return F<RS2_FORMAT_GPIO_RAW>::func();
case RS2_FORMAT_6DOF: return F<RS2_FORMAT_6DOF>::func();
case RS2_FORMAT_DISPARITY32: return F<RS2_FORMAT_DISPARITY32>::func();
case RS2_FORMAT_Y10BPACK: return F<RS2_FORMAT_Y10BPACK>::func();
case RS2_FORMAT_DISTANCE: return F<RS2_FORMAT_DISTANCE>::func();
case RS2_FORMAT_MJPEG: return F<RS2_FORMAT_MJPEG>::func();
case RS2_FORMAT_Y8I: return F<RS2_FORMAT_Y8I>::func();
case RS2_FORMAT_Y12I: return F<RS2_FORMAT_Y12I>::func();
case RS2_FORMAT_INZI: return F<RS2_FORMAT_INZI>::func();
case RS2_FORMAT_INVI: return F<RS2_FORMAT_INVI>::func();
case RS2_FORMAT_W10: return F<RS2_FORMAT_W10>::func();
case RS2_FORMAT_FG: return F<RS2_FORMAT_FG>::func();
case RS2_FORMAT_Y411: return F<RS2_FORMAT_Y411>::func();
// c++11 standard doesn't allow throw in constexpr function switch case
case RS2_FORMAT_COUNT: throw std::runtime_error("format.count is not a valid value for arguments of type format!");
default: return F<RS2_FORMAT_ANY>::func();
}
}
// Support Python's buffer protocol
class BufData {
public:
void *_ptr = nullptr; // Pointer to the underlying storage
size_t _itemsize = 0; // Size of individual items in bytes
std::string _format; // For homogeneous buffers, this should be set to format_descriptor<T>::format()
size_t _ndim = 0; // Number of dimensions
std::vector<size_t> _shape; // Shape of the tensor (1 entry per dimension)
std::vector<size_t> _strides; // Number of entries between adjacent entries (for each per dimension)
public:
BufData(void *ptr, size_t itemsize, const std::string& format, size_t ndim, const std::vector<size_t> &shape, const std::vector<size_t> &strides)
: _ptr(ptr), _itemsize(itemsize), _format(format), _ndim(ndim), _shape(shape), _strides(strides) {}
BufData(void *ptr, size_t itemsize, const std::string& format, size_t size)
: BufData(ptr, itemsize, format, 1, std::vector<size_t> { size }, std::vector<size_t> { itemsize }) { }
BufData(void *ptr, // Raw data pointer
size_t itemsize, // Size of the type in bytes
const std::string& format, // Data type's format descriptor (e.g. "@f" for float xyz)
size_t dim, // number of data elements per group (e.g. 3 for float xyz)
size_t count) // Number of groups
: BufData(ptr, itemsize, format, 2, std::vector<size_t> { count, dim }, std::vector<size_t> { itemsize*dim, itemsize }) { }
};
/*PYBIND11_MAKE_OPAQUE(std::vector<rs2::stream_profile>)*/
// Partial module definition functions
void init_c_files(py::module &m);
void init_types(py::module &m);
void init_frame(py::module &m);
void init_options(py::module &m);
void init_processing(py::module &m);
void init_sensor(py::module &m);
void init_device(py::module &m);
void init_record_playback(py::module &m);
void init_context(py::module &m);
void init_pipeline(py::module &m);
void init_internal(py::module &m);
void init_export(py::module &m);
void init_advanced_mode(py::module &m);
void init_serializable_device(py::module& m);
void init_util(py::module &m);
#endif // LIBREALSENSE_PYTHON_HPP