24#include <opencv2/calib3d.hpp>
25#include <opencv2/core.hpp>
26#include <opencv2/imgproc.hpp>
30#define OPENCV_DISABLE_EIGEN_TENSOR_SUPPORT
31#include <opencv2/core/eigen.hpp>
41 (Eigen::Matrix3d() << 0, -1, 0, 0, 0, -1, 1, 0, 0).finished()};
43 (Eigen::Matrix3d() << 0, 0, 1, -1, 0, 0, 0, -1, 0).finished()};
46 const std::vector<cv::Point2f>& points) {
47 std::vector<int> outputHull{};
48 cv::convexHull(points, outputHull);
49 std::vector<cv::Point2f> convexPoints;
50 for (
size_t i = 0; i < outputHull.size(); i++) {
51 convexPoints.push_back(points[outputHull[i]]);
57 const std::vector<cv::Point2f>& points) {
58 return cv::minAreaRect(points);
70 const std::vector<frc::Translation3d>& translations) {
71 std::vector<cv::Point3f> retVal;
72 retVal.reserve(translations.size());
73 for (
size_t i = 0; i < translations.size(); i++) {
75 retVal.emplace_back(cv::Point3f{trl.X().to<
float>(), trl.Y().to<
float>(),
76 trl.Z().to<
float>()});
82 const frc::Rotation3d& rotation) {
83 std::vector<cv::Point3f> retVal{};
85 retVal.emplace_back(cv::Point3d{
86 rot.GetQuaternion().ToRotationVector()(0),
87 rot.GetQuaternion().ToRotationVector()(1),
88 rot.GetQuaternion().ToRotationVector()(2),
93[[maybe_unused]]
static cv::Point2f
AvgPoint(std::vector<cv::Point2f> points) {
94 if (points.size() == 0) {
97 cv::reduce(points, points, 0, cv::REDUCE_AVG);
102 const std::vector<cv::Point2f>& points) {
103 std::vector<photon::TargetCorner> retVal;
104 retVal.reserve(points.size());
105 for (
size_t i = 0; i < points.size(); i++) {
112 const std::vector<cv::Point2f>& points) {
113 std::vector<std::pair<float, float>> retVal;
114 retVal.reserve(points.size());
115 for (
size_t i = 0; i < points.size(); i++) {
116 retVal.emplace_back(std::make_pair(points[i].x, points[i].y));
122 const std::vector<std::pair<float, float>>& corners) {
123 std::vector<cv::Point2f> retVal;
124 retVal.reserve(corners.size());
125 for (
size_t i = 0; i < corners.size(); i++) {
126 retVal.emplace_back(cv::Point2f{corners[i].first, corners[i].second});
132 const std::vector<photon::TargetCorner>& corners) {
133 std::vector<cv::Point2f> retVal;
134 retVal.reserve(corners.size());
135 for (
size_t i = 0; i < corners.size(); i++) {
136 retVal.emplace_back(cv::Point2f{
static_cast<float>(corners[i].x),
137 static_cast<float>(corners[i].y)});
143 const std::vector<cv::Point2f>& points) {
144 return cv::boundingRect(points);
148 const Eigen::Matrix<double, 3, 3>& cameraMatrix,
149 const Eigen::Matrix<double, 8, 1>& distCoeffs,
151 const std::vector<frc::Translation3d>& objectTranslations) {
155 cv::Mat cameraMat(cameraMatrix.rows(), cameraMatrix.cols(), CV_64F);
156 cv::eigen2cv(cameraMatrix, cameraMat);
157 cv::Mat distCoeffsMat(distCoeffs.rows(), distCoeffs.cols(), CV_64F);
158 cv::eigen2cv(distCoeffs, distCoeffsMat);
159 std::vector<cv::Point2f> imagePoints{};
160 cv::projectPoints(objectPoints, rvec, tvec, cameraMat, distCoeffsMat,
167 bool backwards,
int shiftStart) {
168 size_t size = elements.size();
169 int dir = backwards ? -1 : 1;
170 std::vector<T> reordered{elements};
171 for (
size_t i = 0; i < size; i++) {
172 int index = (i * dir + shiftStart * dir) % size;
174 index = size + index;
176 reordered[i] = elements[index];
191 cv::Mat wrapped{tvecInput.rows, tvecInput.cols, CV_32F};
192 tvecInput.convertTo(wrapped, CV_32F);
193 data = wrapped.at<cv::Vec3f>(cv::Point{0, 0});
195 units::meter_t{data[1]},
196 units::meter_t{data[2]}});
201 cv::Mat wrapped{rvecInput.rows, rvecInput.cols, CV_32F};
202 rvecInput.convertTo(wrapped, CV_32F);
203 data = wrapped.at<cv::Vec3f>(cv::Point{0, 0});
205 frc::Rotation3d{Eigen::Vector3d{data[0], data[1], data[2]}});
209 const Eigen::Matrix<double, 3, 3>& cameraMatrix,
210 const Eigen::Matrix<double, 8, 1>& distCoeffs,
211 std::vector<frc::Translation3d> modelTrls,
212 std::vector<cv::Point2f> imagePoints) {
216 std::vector<cv::Mat> rvecs;
217 std::vector<cv::Mat> tvecs;
218 cv::Mat rvec = cv::Mat::zeros(3, 1, CV_32F);
219 cv::Mat tvec = cv::Mat::zeros(3, 1, CV_32F);
220 cv::Mat reprojectionError = cv::Mat::zeros(2, 1, CV_32F);
222 cv::Mat cameraMat(cameraMatrix.rows(), cameraMatrix.cols(), CV_32F);
223 cv::eigen2cv(cameraMatrix, cameraMat);
224 cv::Mat distCoeffsMat(distCoeffs.rows(), distCoeffs.cols(), CV_32F);
225 cv::eigen2cv(distCoeffs, distCoeffsMat);
228 frc::Transform3d best{};
229 std::optional<frc::Transform3d> alt{std::nullopt};
231 for (
int tries = 0; tries < 2; tries++) {
232 cv::solvePnPGeneric(objectMat, imagePoints, cameraMat, distCoeffsMat, rvecs,
233 tvecs,
false, cv::SOLVEPNP_IPPE_SQUARE, rvec, tvec,
236 errors = reprojectionError.at<cv::Vec2f>(cv::Point{0, 0});
240 if (tvecs.size() > 1) {
245 if (!std::isnan(errors[0])) {
248 cv::Point2f pt = imagePoints[0];
255 if (std::isnan(errors[0])) {
256 fmt::print(
"SolvePNP_Square failed!\n");
262 result.
alt = alt.value();
263 result.
ambiguity = errors[0] / errors[1];
276 const Eigen::Matrix<double, 3, 3>& cameraMatrix,
277 const Eigen::Matrix<double, 8, 1>& distCoeffs,
278 std::vector<frc::Translation3d> modelTrls,
279 std::vector<cv::Point2f> imagePoints) {
281 std::vector<cv::Mat> rvecs{};
282 std::vector<cv::Mat> tvecs{};
283 cv::Mat rvec = cv::Mat::zeros(3, 1, CV_32F);
284 cv::Mat tvec = cv::Mat::zeros(3, 1, CV_32F);
285 cv::Mat reprojectionError = cv::Mat::zeros(2, 1, CV_32F);
287 cv::Mat cameraMat(cameraMatrix.rows(), cameraMatrix.cols(), CV_64F);
288 cv::eigen2cv(cameraMatrix, cameraMat);
289 cv::Mat distCoeffsMat(distCoeffs.rows(), distCoeffs.cols(), CV_64F);
290 cv::eigen2cv(distCoeffs, distCoeffsMat);
293 frc::Transform3d best{};
295 cv::solvePnPGeneric(objectMat, imagePoints, cameraMat, distCoeffsMat, rvecs,
296 tvecs,
false, cv::SOLVEPNP_SQPNP, rvec, tvec,
299 error = reprojectionError.at<
float>(cv::Point{0, 0});
303 if (std::isnan(error)) {
304 fmt::print(
"SolvePNP_Square failed!\n");
Definition TargetCorner.h:25
static std::vector< cv::Point3f > RotationToRVec(const frc::Rotation3d &rotation)
Definition OpenCVHelp.h:81
static cv::RotatedRect GetMinAreaRect(const std::vector< cv::Point2f > &points)
Definition OpenCVHelp.h:56
static frc::Rotation3d NWU_TO_EDN
Definition OpenCVHelp.h:40
static std::vector< photon::TargetCorner > PointsToTargetCorners(const std::vector< cv::Point2f > &points)
Definition OpenCVHelp.h:101
static cv::Point2f AvgPoint(std::vector< cv::Point2f > points)
Definition OpenCVHelp.h:93
static frc::Rotation3d RotationNWUtoEDN(const frc::Rotation3d &rot)
Definition OpenCVHelp.h:65
static frc::Rotation3d RVecToRotation(const cv::Mat &rvecInput)
Definition OpenCVHelp.h:199
static std::optional< photon::PnpResult > SolvePNP_SQPNP(const Eigen::Matrix< double, 3, 3 > &cameraMatrix, const Eigen::Matrix< double, 8, 1 > &distCoeffs, std::vector< frc::Translation3d > modelTrls, std::vector< cv::Point2f > imagePoints)
Definition OpenCVHelp.h:275
static frc::Translation3d TranslationEDNToNWU(const frc::Translation3d &trl)
Definition OpenCVHelp.h:181
static cv::Rect GetBoundingRect(const std::vector< cv::Point2f > &points)
Definition OpenCVHelp.h:142
static frc::Translation3d TranslationNWUtoEDN(const frc::Translation3d &trl)
Definition OpenCVHelp.h:61
static frc::Rotation3d RotationEDNToNWU(const frc::Rotation3d &rot)
Definition OpenCVHelp.h:185
static frc::Rotation3d EDN_TO_NWU
Definition OpenCVHelp.h:42
static std::vector< std::pair< float, float > > PointsToCorners(const std::vector< cv::Point2f > &points)
Definition OpenCVHelp.h:111
static std::vector< T > ReorderCircular(const std::vector< T > elements, bool backwards, int shiftStart)
Definition OpenCVHelp.h:166
static std::vector< cv::Point3f > TranslationToTVec(const std::vector< frc::Translation3d > &translations)
Definition OpenCVHelp.h:69
static frc::Translation3d TVecToTranslation(const cv::Mat &tvecInput)
Definition OpenCVHelp.h:189
static std::vector< cv::Point2f > ProjectPoints(const Eigen::Matrix< double, 3, 3 > &cameraMatrix, const Eigen::Matrix< double, 8, 1 > &distCoeffs, const RotTrlTransform3d &camRt, const std::vector< frc::Translation3d > &objectTranslations)
Definition OpenCVHelp.h:147
static std::vector< cv::Point2f > GetConvexHull(const std::vector< cv::Point2f > &points)
Definition OpenCVHelp.h:45
static std::optional< photon::PnpResult > SolvePNP_Square(const Eigen::Matrix< double, 3, 3 > &cameraMatrix, const Eigen::Matrix< double, 8, 1 > &distCoeffs, std::vector< frc::Translation3d > modelTrls, std::vector< cv::Point2f > imagePoints)
Definition OpenCVHelp.h:208
static std::vector< cv::Point2f > CornersToPoints(const std::vector< std::pair< float, float > > &corners)
Definition OpenCVHelp.h:121
Definition VisionEstimation.h:32
double altReprojErr
Definition PnpResultStruct.h:33
double bestReprojErr
Definition PnpResultStruct.h:32
double ambiguity
Definition PnpResultStruct.h:34
frc::Transform3d alt
Definition PnpResultStruct.h:31
frc::Transform3d best
Definition PnpResultStruct.h:30
Definition PnpResult.h:29