59template<
typename Color>
82template<
typename Color =
void>
85 std::vector<Point<Color>>
cloud;
111 fx_(reference_cal.P[0][0]),
112 fy_(reference_cal.P[1][1]),
113 cx_(reference_cal.P[0][2]),
114 cy_(reference_cal.P[1][2]),
115 tx_(matching_cal.P[0][3] / matching_cal.P[0][0]),
116 cx_prime_(matching_cal.P[0][2]),
119 fycxtx_(fy_ * cx_ * tx_),
120 fxcytx_(fx_ * cy_ * tx_),
121 fxfytx_(fx_ * fy_ * tx_),
122 fycxcxprime_(fy_ * (cx_ - cx_prime_))
128 const double inversebeta = 1.0 / (-fy_ * disparity + fycxcxprime_);
129 const double x = ((fytx_ * pixel.
u) + (-fycxtx_)) * inversebeta;
130 const double y = ((fxtx_ * pixel.
v) + (-fxcytx_)) * inversebeta;
131 const double z = fxfytx_ * inversebeta;
133 return Point<void>{
static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z)};
142 double cx_prime_ = 0.0;
147 double fycxtx_ = 0.0;
148 double fxcytx_ = 0.0;
149 double fxfytx_ = 0.0;
150 double fycxcxprime_ = 0.0;
179 bool compute_in_aux_frame =
false,
180 float invalid_value = 0);
194 const Pixel &rectified_aux_pixel,
195 size_t max_pixel_search_window,
196 double pixel_epsilon,
231template<
typename Color>
233 const std::optional<Image> &color,
237 size_t color_step = 0;
238 double color_disparity_scale = 0.0;
240 if constexpr (std::is_same_v<Color, void>)
254 color_step =
sizeof(Color);
257 color->width != disparity.
width ||
258 color->height != disparity.
height ||
259 disparity.
width < 0 ||
265 const double tx = calibration.
right.
P[0][3] / calibration.
right.
P[0][0];
266 const double color_tx = color->calibration.P[0][3] / color->calibration.P[0][0];
267 color_disparity_scale = color_tx / tx;
270 constexpr double scale = 1.0 / 16.0;
272 const double squared_range = max_range * max_range;
279 for (
size_t h = 0 ; h < static_cast<size_t>(disparity.
height) ; ++h)
281 for (
size_t w = 0 ; w < static_cast<size_t>(disparity.
width) ; ++w)
284 (h * disparity.
width *
sizeof(uint16_t)) +
285 (w *
sizeof(uint16_t));
288 static_cast<double>(*
reinterpret_cast<const uint16_t*
>(disparity.
raw_data->data() + index)) * scale;
297 if ((x*x + y*y + z*z) > squared_range)
302 if constexpr (std::is_same_v<Color, void>)
304 output.
cloud.push_back(
Point<Color>{
static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z)});
311 const size_t color_index = color->image_data_offset +
312 (h * color->width * color_step) +
313 static_cast<size_t>((
static_cast<double>(w) - (color_disparity_scale * d))) * color_step;
315 const Color color_pixel = *
reinterpret_cast<const Color*
>(color->raw_data->data() + color_index);
317 output.
cloud.push_back(
Point<Color>{
static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z),
334template<
typename Color>
340 if constexpr (std::is_same_v<Color, void>)
374template <
typename Color>
377 std::ofstream
ply(
path, std::ios::binary);
383 std::ostringstream
header;
385 header <<
"format binary_little_endian 1.0\n";
387 header <<
"property float x\n";
388 header <<
"property float y\n";
389 header <<
"property float z\n";
391 if constexpr (std::is_same_v<Color, uint8_t>)
393 header <<
"property uchar intensity\n";
395 else if constexpr (std::is_same_v<Color, uint16_t>)
397 header <<
"property ushort intensity\n";
399 else if constexpr (std::is_same_v<Color, std::array<uint8_t, 3>>)
401 header <<
"property uchar red\n";
402 header <<
"property uchar green\n";
403 header <<
"property uchar blue\n";
405 else if (!std::is_same_v<Color, void>)
407 throw std::runtime_error(
"Unsupported color type");
417 ply.write(
reinterpret_cast<const char*
>(&
point.x),
sizeof(
point.x));
418 ply.write(
reinterpret_cast<const char*
>(&
point.y),
sizeof(
point.y));
419 ply.write(
reinterpret_cast<const char*
>(&
point.z),
sizeof(
point.z));
421 if constexpr (std::is_same_v<Color, std::array<uint8_t, 3>>)
426 ply.write(
reinterpret_cast<const char*
>(&red),
sizeof(red));
427 ply.write(
reinterpret_cast<const char*
>(&
green),
sizeof(
green));
428 ply.write(
reinterpret_cast<const char*
>(&blue),
sizeof(blue));
430 else if constexpr (std::is_same_v<Color, void>)
437 ply.write(
reinterpret_cast<const char*
>(&
point.color),
sizeof(
point.color));
Copyright 2013-2025 Carnegie Robotics, LLC 4501 Hatfield Street, Pittsburgh, PA 15201 http://www....
QMatrix(const CameraCalibration &reference_cal, const CameraCalibration &matching_cal)
Construct a minimal Q matrix from calibrations.
Point< void > reproject(const Pixel &pixel, double disparity) const
MULTISENSE_API std::optional< Point< void > > get_aux_3d_point(const ImageFrame &frame, const Pixel &rectified_aux_pixel, size_t max_pixel_search_window, double pixel_epsilon, const DataSource &disparity_source=DataSource::LEFT_DISPARITY_RAW)
for a given pixel in the aux image, return the corresponding 3D point associated with the aux pixel
MULTISENSE_API std::optional< PointCloud< Color > > create_color_pointcloud(const Image &disparity, const std::optional< Image > &color, double max_range, const StereoCalibration &calibration)
Create a point cloud from a image frame and a color source.
MULTISENSE_API std::optional< Image > create_bgr_from_ycbcr420(const Image &luma, const Image &chroma, const DataSource &output_source)
Convert a YCbCr420 luma + chroma image into a BGR color image.
DataSource
Identifies which camera or data source the image is from.
MULTISENSE_API std::string to_string(const Status &status)
Convert a status object to a user readable string.
MULTISENSE_API bool write_pointcloud_ply(const PointCloud< Color > &point_cloud, const std::filesystem::path &path)
Write a point cloud to a ply file.
MULTISENSE_API std::optional< Image > create_bgr_image(const ImageFrame &frame, const DataSource &output_source)
Convert a YCbCr420 luma + chroma image into a BGR color image.
MULTISENSE_API bool write_image(const Image &image, const std::filesystem::path &path)
Write a image to a specific path on disk.
MULTISENSE_API std::optional< Image > create_depth_image(const ImageFrame &frame, const Image::PixelFormat &depth_format, const DataSource &disparity_source=DataSource::LEFT_DISPARITY_RAW, bool compute_in_aux_frame=false, float invalid_value=0)
Create a depth image from a image frame.
MULTISENSE_API std::optional< PointCloud< void > > create_pointcloud(const ImageFrame &frame, double max_range, const DataSource &disparity_source=DataSource::LEFT_DISPARITY_RAW)
std::array< std::array< float, 4 >, 3 > P
Rectified projection matrix which takes points in the origin camera coordinate frame and projects the...
A frame containing multiple images (indexed by DataSource).
bool has_image(const DataSource &source) const
Check if we have an image for a given data source.
Represents a single image plus metadata.
int width
Width of the image in pixels.
PixelFormat format
The format of the image data stored in the raw_data stored in the raw_data buffer.
PixelFormat
Pixel formats.
CameraCalibration calibration
The scaled calibration associated with the image.
int height
Height of the image in pixels.
int64_t image_data_offset
An offset into the raw_data pointer where the image data starts.
std::shared_ptr< const std::vector< uint8_t > > raw_data
A pointer to the raw image data sent from the camera.
Pixel coordinates in a image.
A pointcloud containing a collection of colorized points.
std::vector< Point< Color > > cloud
Make sure our Points and point clouds are packed for applications which might need to handle the unde...
CameraCalibration right
Calibration information for the right camera.