59 template<
typename Color>
79 template<
typename Color =
void>
82 std::vector<Point<Color>>
cloud;
107 float invalid_value = 0);
125 template<
typename Color>
127 const std::optional<Image> &color,
131 size_t color_step = 0;
132 double color_disparity_scale = 0.0;
134 if constexpr (std::is_same_v<Color, void>)
148 color_step =
sizeof(Color);
151 color->width != disparity.
width ||
152 color->height != disparity.
height ||
153 disparity.
width < 0 ||
159 const double tx = calibration.
right.
P[0][3] / calibration.
right.
P[0][0];
160 const double color_tx = color->calibration.P[0][3] / color->calibration.P[0][0];
161 color_disparity_scale = color_tx / tx;
164 constexpr
double scale = 1.0 / 16.0;
166 const double squared_range = max_range * max_range;
172 const double tx = calibration.
right.
P[0][3] / calibration.
right.
P[0][0];
173 const double cx_prime = calibration.
right.
P[0][2];
175 const double fytx = fy * tx;
176 const double fxtx = fx * tx;
178 const double fycxtx = fy * cx * tx;
179 const double fxcytx = fx * cy * tx;
180 const double fxfytx = fx * fy * tx;
181 const double fycxcxprime = fy * (cx - cx_prime);
186 for (
size_t h = 0 ; h < static_cast<size_t>(disparity.
height) ; ++h)
188 for (
size_t w = 0 ; w < static_cast<size_t>(disparity.
width) ; ++w)
191 (h * disparity.
width *
sizeof(uint16_t)) +
192 (w *
sizeof(uint16_t));
195 static_cast<double>(*
reinterpret_cast<const uint16_t*
>(disparity.
raw_data->data() + index)) * scale;
202 const double inversebeta = 1.0 / (-fy * d + fycxcxprime);
203 const double x = ((fytx * w) + (-fycxtx)) * inversebeta;
204 const double y = ((fxtx * h) + (-fxcytx)) * inversebeta;
205 const double z = fxfytx * inversebeta;
207 if ((x*x + y*y + z*z) > squared_range)
212 if constexpr (std::is_same_v<Color, void>)
214 output.cloud.push_back(
Point<Color>{
static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z)});
221 const size_t color_index = color->image_data_offset +
222 (h * color->width * color_step) +
223 static_cast<size_t>((
static_cast<double>(w) - (color_disparity_scale * d))) * color_step;
225 const Color color_pixel = *
reinterpret_cast<const Color*
>(color->raw_data->data() + color_index);
227 output.cloud.push_back(
Point<Color>{
static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z),
239 template<
typename Color>
245 if constexpr (std::is_same_v<Color, void>)
252 return create_color_pointcloud<Color>(frame.
get_image(disparity_source), std::nullopt, max_range, frame.
calibration);
261 return create_color_pointcloud<Color>(frame.
get_image(disparity_source),
275 template <
typename Color>
278 std::ofstream ply(path, std::ios::binary);
284 std::ostringstream header;
286 header <<
"format binary_little_endian 1.0\n";
287 header <<
"element vertex " << point_cloud.
cloud.size() <<
"\n";
288 header <<
"property float x\n";
289 header <<
"property float y\n";
290 header <<
"property float z\n";
292 if constexpr (std::is_same_v<Color, uint8_t>)
294 header <<
"property uchar intensity\n";
296 else if constexpr (std::is_same_v<Color, uint16_t>)
298 header <<
"property ushort intensity\n";
300 else if constexpr (std::is_same_v<Color, std::array<uint8_t, 3>>)
302 header <<
"property uchar red\n";
303 header <<
"property uchar green\n";
304 header <<
"property uchar blue\n";
306 else if (!std::is_same_v<Color, void>)
308 throw std::runtime_error(
"Unsupported color type");
311 header <<
"end_header\n";
313 std::string header_str = header.str();
314 ply.write(header_str.c_str(), header_str.size());
316 for (
const auto &point : point_cloud.
cloud)
318 ply.write(
reinterpret_cast<const char*
>(&point.x),
sizeof(point.x));
319 ply.write(
reinterpret_cast<const char*
>(&point.y),
sizeof(point.y));
320 ply.write(
reinterpret_cast<const char*
>(&point.z),
sizeof(point.z));
322 if constexpr (std::is_same_v<Color, std::array<uint8_t, 3>>)
324 uint8_t red = point.color[2];
325 uint8_t green = point.color[1];
326 uint8_t blue = point.color[0];
327 ply.write(
reinterpret_cast<const char*
>(&red),
sizeof(red));
328 ply.write(
reinterpret_cast<const char*
>(&green),
sizeof(green));
329 ply.write(
reinterpret_cast<const char*
>(&blue),
sizeof(blue));
331 else if constexpr (std::is_same_v<Color, void>)
338 ply.write(
reinterpret_cast<const char*
>(&point.color),
sizeof(point.color));