blob: ee621dd8afccd99e729a6ddb7946d391c2c4a110 [file] [log] [blame]
#ifndef FRC971_VISION_VISION_UTIL_LIB_H_
#define FRC971_VISION_VISION_UTIL_LIB_H_
#include <optional>
#include <string_view>
#include "Eigen/Dense"
#include "Eigen/Geometry"
#include "Eigen/SVD"
#include "opencv2/imgproc.hpp"
#include "frc971/vision/calibration_generated.h"
#include "frc971/vision/ceres/types.h"
// Extract the CameraExtrinsics from a CameraCalibration struct
namespace frc971::vision {
std::optional<cv::Mat> CameraExtrinsics(
const frc971::vision::calibration::CameraCalibration *camera_calibration);
// Extract the CameraIntrinsics from a CameraCalibration struct
cv::Mat CameraIntrinsics(
const frc971::vision::calibration::CameraCalibration *camera_calibration);
// Extract the CameraDistCoeffs from a CameraCalibration struct
cv::Mat CameraDistCoeffs(
const frc971::vision::calibration::CameraCalibration *camera_calibration);
// Get the camera number from a camera channel name, e.g., return 2 from
// "/camera2". Returns nullopt if string doesn't start with "/camera" or does
// not have a number
std::optional<uint16_t> CameraNumberFromChannel(std::string camera_channel);
// Return a calibration filename to save to based on the given data
std::string CalibrationFilename(std::string calibration_folder,
std::string node_name, int team_number,
int camera_number, std::string camera_id,
std::string timestamp);
// Utility functions for dealing with ceres::examples::Pose3d structs
class PoseUtils {
public:
// Embeds a 3d pose into an affine transformation
static Eigen::Affine3d Pose3dToAffine3d(
const ceres::examples::Pose3d &pose3d);
// Inverse of above function
static ceres::examples::Pose3d Affine3dToPose3d(const Eigen::Affine3d &H);
// Computes pose_2 relative to pose_1. This is equivalent to (pose_1^-1 *
// pose_2)
static ceres::examples::Pose3d ComputeRelativePose(
const ceres::examples::Pose3d &pose_1,
const ceres::examples::Pose3d &pose_2);
// Computes pose_2 given a pose_1 and pose_2 relative to pose_1. This is
// equivalent to (pose_1 * pose_2_relative)
static ceres::examples::Pose3d ComputeOffsetPose(
const ceres::examples::Pose3d &pose_1,
const ceres::examples::Pose3d &pose_2_relative);
// Converts a rotation with roll, pitch, and yaw into a quaternion
static Eigen::Quaterniond EulerAnglesToQuaternion(const Eigen::Vector3d &rpy);
// Inverse of above function
static Eigen::Vector3d QuaternionToEulerAngles(const Eigen::Quaterniond &q);
// Converts a 3d rotation matrix into a rotation with roll, pitch, and yaw
static Eigen::Vector3d RotationMatrixToEulerAngles(const Eigen::Matrix3d &R);
};
// Compute the average of a set of quaternions
Eigen::Vector4d QuaternionAverage(std::vector<Eigen::Vector4d> quaternions);
// Compute the average pose given a list of translations (as
// Eigen::Vector3d's) and rotations (as Eigen::Vector4d quaternions)
// Returned as an Eigen::Affine3d pose
// Also, compute the variance of each of these list of vectors
Eigen::Affine3d ComputeAveragePose(
std::vector<Eigen::Vector3d> &translation_list,
std::vector<Eigen::Vector4d> &rotation_list,
Eigen::Vector3d *translation_variance = nullptr,
Eigen::Vector3d *rotation_variance = nullptr);
// Helper function to compute average pose when supplied with list
// of Eigen::Affine3d's
Eigen::Affine3d ComputeAveragePose(
std::vector<Eigen::Affine3d> &pose_list,
Eigen::Vector3d *translation_variance = nullptr,
Eigen::Vector3d *rotation_variance = nullptr);
} // namespace frc971::vision
#endif // FRC971_VISION_VISION_UTIL_LIB_H_