56 static_cast<double>(config.
width())));
58 const double y_scale = 1.0 / ((
static_cast<double>(imagerHeight) /
59 static_cast<double>(config.
height())));
71 const size_t rgb_stride = luma.
width * 3;
73 for(uint32_t y=0; y< luma.
height; ++y)
75 const size_t row_offset = y * rgb_stride;
77 for(uint32_t x=0; x< luma.
width; ++x)
79 memcpy(output + row_offset + (3 * x), ycbcrToBgr<uint8_t>(luma, chroma, x, y).
data(), 3);
88 Eigen::Matrix4d q_matrix = Eigen::Matrix4d::Zero();
90 const auto scale = compute_scale(config, device_info);
101 const auto fx = calibration.
left.
P[0][0] * scale.x_scale;
102 const auto cx = calibration.
left.
P[0][2] * scale.x_scale;
103 const auto fy = calibration.
left.
P[1][1] * scale.y_scale;
104 const auto cy = calibration.
left.
P[1][2] * scale.y_scale;
105 const auto tx = calibration.
right.
P[0][3] / calibration.
right.
P[0][0];
106 const auto cx_prime = calibration.
right.
P[0][2] * scale.x_scale;
108 q_matrix(0,0) = fy * tx;
109 q_matrix(1,1) = fx * tx;
110 q_matrix(0,3) = -fy * cx * tx;
111 q_matrix(1,3) = -fx * cy * tx;
112 q_matrix(2,3) = fx * fy * tx;
114 q_matrix(3,3) = fy * (cx - cx_prime);
123 sensor_msgs::CameraInfo camera_info;
125 camera_info.width = config.
width();
126 camera_info.height = config.
height();
128 camera_info.P[0] = calibration.
P[0][0] * scale.x_scale;
129 camera_info.P[1] = calibration.
P[0][1];
130 camera_info.P[2] = calibration.
P[0][2] * scale.x_scale;
131 camera_info.P[3] = calibration.
P[0][3] * scale.x_scale;
132 camera_info.P[4] = calibration.
P[1][0];
133 camera_info.P[5] = calibration.
P[1][1] * scale.y_scale;
134 camera_info.P[6] = calibration.
P[1][2] * scale.y_scale;
135 camera_info.P[7] = calibration.
P[1][3];
136 camera_info.P[8] = calibration.
P[2][0];
137 camera_info.P[9] = calibration.
P[2][1];
138 camera_info.P[10] = calibration.
P[2][2];
139 camera_info.P[11] = calibration.
P[2][3];
141 camera_info.K[0] = calibration.
M[0][0] * scale.x_scale;
142 camera_info.K[1] = calibration.
M[0][1];
143 camera_info.K[2] = calibration.
M[0][2] * scale.x_scale;
144 camera_info.K[3] = calibration.
M[1][0];
145 camera_info.K[4] = calibration.
M[1][1] * scale.y_scale;
146 camera_info.K[5] = calibration.
M[1][2] * scale.y_scale;
147 camera_info.K[6] = calibration.
M[2][0];
148 camera_info.K[7] = calibration.
M[2][1];
149 camera_info.K[8] = calibration.
M[2][2];
151 camera_info.R[0] = calibration.
R[0][0];
152 camera_info.R[1] = calibration.
R[0][1];
153 camera_info.R[2] = calibration.
R[0][2];
154 camera_info.R[3] = calibration.
R[1][0];
155 camera_info.R[4] = calibration.
R[1][1];
156 camera_info.R[5] = calibration.
R[1][2];
157 camera_info.R[6] = calibration.
R[2][0];
158 camera_info.R[7] = calibration.
R[2][1];
159 camera_info.R[8] = calibration.
R[2][2];
165 camera_info.D.resize(8);
166 for (
size_t i=0 ; i < 8 ; ++i)
168 camera_info.D[i] = calibration.
D[i];
177 if (calibration.
D[7] == 0.0 && calibration.
D[6] == 0.0 && calibration.
D[5] == 0.0)
195 const auto scale = compute_scale(config, device_info);
197 const cv::Matx33d K(calibration.
M[0][0] * scale.x_scale,
199 calibration.
M[0][2] * scale.x_scale,
201 calibration.
M[1][1] * scale.y_scale,
202 calibration.
M[1][2] * scale.y_scale,
205 calibration.
M[2][2]);
207 const cv::Matx33d R(calibration.
R[0][0],
215 calibration.
R[2][2]);
217 const cv::Matx34d P(calibration.
P[0][0] * scale.x_scale,
219 calibration.
P[0][2] * scale.x_scale,
220 calibration.
P[0][3] * scale.x_scale,
222 calibration.
P[1][1] * scale.y_scale,
223 calibration.
P[1][2] * scale.y_scale,
228 calibration.
P[2][3]);
230 const bool plumbob = calibration.
D[7] == 0.0 && calibration.
D[6] == 0.0 && calibration.
D[5] == 0.0;
232 cv::Mat D(plumbob ? 5 : 8, 1, CV_64FC1);
233 for (
int i = 0; i < D.rows ; ++i)
235 D.at<
double>(i) = calibration.
D[i];
238 cv::initUndistortRectifyMap(K, D, R, P, cv::Size(config.
width(), config.
height()), CV_32FC1, remap.
map1, remap.
map2);
247 calibration_(calibration),
248 device_info_(device_info),
249 q_matrix_(
makeQ(config_, calibration_, device_info_)),
250 left_camera_info_(
makeCameraInfo(config_, calibration_.left, compute_scale(config_, device_info_))),
251 right_camera_info_(
makeCameraInfo(config_, calibration_.right, compute_scale(config_, device_info_))),
252 aux_camera_info_(
makeCameraInfo(config_, calibration_.aux, config_.cameraProfile() ==
crl::multisense::Full_Res_Aux_Cam ?
253 ScaleT{1., 1.} : compute_scale(config_, device_info_))),
254 left_remap_(std::make_shared<RectificationRemapT>(
makeRectificationRemap(config_, calibration_.left, device_info_))),
255 right_remap_(std::make_shared<RectificationRemapT>(
makeRectificationRemap(config_, calibration_.right, device_info_)))
266 std::lock_guard<std::mutex> lock(
mutex_);
282 std::lock_guard<std::mutex> lock(
mutex_);
295 std::lock_guard<std::mutex> lock(
mutex_);
302 std::lock_guard<std::mutex> lock(
mutex_);
309 std::lock_guard<std::mutex> lock(
mutex_);
325 std::lock_guard<std::mutex> lock(
mutex_);
343 std::lock_guard<std::mutex> lock(
mutex_);
351 const sensor_msgs::CameraInfo &left_camera_info,
352 const sensor_msgs::CameraInfo &right_camera_info)
const 356 return Eigen::Vector3f{std::numeric_limits<float>::max(),
357 std::numeric_limits<float>::max(),
358 std::numeric_limits<float>::max()};
362 const double &fx = left_camera_info.P[0];
363 const double &fy = left_camera_info.P[5];
364 const double &cx = left_camera_info.P[2];
365 const double &cy = left_camera_info.P[6];
366 const double &cx_right = right_camera_info.P[2];
367 const double tx = right_camera_info.P[3] / right_camera_info.P[0];
369 const double xB = ((fy * tx) * u) + (-fy * cx * tx);
370 const double yB = ((fx * tx) * v) + (-fx * cy * tx);
371 const double zB = (fx * fy * tx);
372 const double invB = 1. / (-fy * d) + (fy * (cx - cx_right));
374 return Eigen::Vector3f{
static_cast<float>(xB * invB), static_cast<float>(yB * invB),
static_cast<float>(zB * invB)};
379 std::lock_guard<std::mutex> lock(
mutex_);
385 const sensor_msgs::CameraInfo &aux_camera_info)
const 387 const double &fx = aux_camera_info.P[0];
388 const double &fy = aux_camera_info.P[5];
389 const double &cx = aux_camera_info.P[2];
390 const double &cy = aux_camera_info.P[6];
391 const double &fxtx = aux_camera_info.P[3];
392 const double &fyty = aux_camera_info.P[7];
393 const double &tz = aux_camera_info.P[11];
398 const double uB = (fx * left_rectified_point(0) + (cx * left_rectified_point(2)) + fxtx);
399 const double vB = (fy * left_rectified_point(1) + (cy * left_rectified_point(2)) + fyty);
400 const double invB = 1.0 / (left_rectified_point(2) + tz);
402 return Eigen::Vector2f{
static_cast<float>(uB * invB), static_cast<float>(vB * invB)};
407 std::lock_guard<std::mutex> lock(
mutex_);
414 std::lock_guard<std::mutex> lock(
mutex_);
429 return std::isfinite(
T());
434 const Eigen::Vector3d auxT =
aux_T();
435 return std::isfinite(auxT(0)) && std::isfinite(auxT(1)) && std::isfinite(auxT(2)) ;
441 std::lock_guard<std::mutex> lock(
mutex_);
444 camera_info.header.frame_id = frame_id;
445 camera_info.header.stamp = stamp;
453 std::lock_guard<std::mutex> lock(
mutex_);
456 camera_info.header.frame_id = frame_id;
457 camera_info.header.stamp = stamp;
473 std::lock_guard<std::mutex> lock(
mutex_);
476 camera_info.header.frame_id = frame_id;
477 camera_info.header.stamp = stamp;
478 camera_info.width = width;
479 camera_info.height = height;
486 std::lock_guard<std::mutex> lock(
mutex_);
493 std::lock_guard<std::mutex> lock(
mutex_);
sensor_msgs::CameraInfo right_camera_info_
const std::string RATIONAL_POLYNOMIAL
Eigen::Matrix4d Q() const
Q stereo reprojection matrix see: https://docs.opencv.org/4.3.0/d9/d0c/group__calib3d.html#ga1bc1152bd57d63bc524204f21fde6e02.
static CRL_CONSTEXPR CameraProfile Full_Res_Aux_Cam
sensor_msgs::CameraInfo makeCameraInfo(const crl::multisense::image::Config &config, const crl::multisense::image::Calibration::Data &calibration, const crl::multisense::system::DeviceInfo &device_info, bool scale_calibration)
sensor_msgs::CameraInfo auxCameraInfo(const std::string &frame_id, const ros::Time &stamp, const OperatingResolutionT &resolution) const
void updateConfig(const crl::multisense::image::Config &config)
OperatingResolutionT operatingStereoResolution() const
Get the current main stereo pair operating resolution. This resolution applies for both the mono and ...
const crl::multisense::system::DeviceInfo & device_info_
RectificationRemapT makeRectificationRemap(const crl::multisense::image::Config &config, const crl::multisense::image::Calibration::Data &calibration, const crl::multisense::system::DeviceInfo &device_info)
static constexpr size_t S30_AUX_CAM_HEIGHT
OperatingResolutionT operatingAuxResolution() const
Get the current aux camera operating resolution. This resolution applies for just the mono topics...
bool validAux() const
Determine if the Aux calibration is valid.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW StereoCalibrationManager(const crl::multisense::image::Config &config, const crl::multisense::image::Calibration &calibration, const crl::multisense::system::DeviceInfo &device_info)
Eigen::Vector3f reproject(size_t u, size_t v, double d) const
Reproject disparity values into 3D.
sensor_msgs::CameraInfo leftCameraInfo(const std::string &frame_id, const ros::Time &stamp) const
sensor_msgs::CameraInfo left_camera_info_
static constexpr size_t S30_AUX_CAM_WIDTH
ROSCPP_DECL std::string remap(const std::string &name)
std::shared_ptr< RectificationRemapT > rightRemap() const
double T() const
Translation which transforms points from the rectified left camera frame into the recified right came...
Eigen::Matrix4d makeQ(const crl::multisense::image::Config &config, const crl::multisense::image::Calibration &calibration, const crl::multisense::system::DeviceInfo &device_info)
constexpr Eigen::Matrix< T, 3, 1 > ycbcrToBgr(const crl::multisense::image::Header &luma, const crl::multisense::image::Header &chroma, size_t u, size_t v)
crl::multisense::image::Config config() const
const crl::multisense::image::Calibration calibration_
std::shared_ptr< RectificationRemapT > leftRemap() const
sensor_msgs::CameraInfo aux_camera_info_
const std::string PLUMB_BOB
std::shared_ptr< RectificationRemapT > left_remap_
std::shared_ptr< RectificationRemapT > right_remap_
bool validRight() const
Determine if the Right calibration is valid.
crl::multisense::image::Config config_
CameraProfile cameraProfile() const
sensor_msgs::CameraInfo rightCameraInfo(const std::string &frame_id, const ros::Time &stamp) const
Eigen::Vector2f rectifiedAuxProject(const Eigen::Vector3f &left_rectified_point) const
Project points corresponding to disparity measurements in the left rectified image frame into the aux...
Eigen::Vector3d aux_T() const
Translation which transforms points from the rectified left camera frame into the rectified aux camer...
Eigen::Matrix4d q_matrix_