12#ifndef ARUCO_DETECTION_HPP
13#define ARUCO_DETECTION_HPP
15#include "../../AutonomyLogging.h"
16#include "../../util/vision/ImageOperations.hpp"
21#include <opencv2/opencv.hpp>
53 int nFramesSinceLastHit;
54 double dStraightLineDistance;
73 cvCenter.
x += stTag.CornerBL.
x + stTag.CornerBR.
x + stTag.CornerTL.
x + stTag.CornerTR.
x;
74 cvCenter.
y += stTag.CornerBL.
y + stTag.CornerBR.
y + stTag.CornerTL.
y + stTag.CornerTR.
y;
102 LOG_ERROR(logging::g_qSharedLogger,
"PreprocessFrame() requires a BGR image.");
108 cv::filter2D(cvOutputFrame, cvOutputFrame, -1, constants::ARUCO_SHARPEN_KERNEL_EXTRA);
143 std::vector<int> vIDs;
144 std::vector<std::vector<cv::Point2f>> cvMarkerCorners, cvRejectedCandidates;
147 cvArucoDetector.
detectMarkers(cvFrame, cvMarkerCorners, vIDs, cvRejectedCandidates);
150 std::vector<ArucoTag> vDetectedTags;
151 vDetectedTags.reserve(vIDs.size());
154 for (
long unsigned int unIter = 0; unIter < vIDs.size(); unIter++)
158 stDetectedTag.nID = vIDs[unIter];
160 stDetectedTag.CornerTL = cvMarkerCorners[unIter][0];
161 stDetectedTag.CornerTR = cvMarkerCorners[unIter][1];
162 stDetectedTag.CornerBR = cvMarkerCorners[unIter][2];
163 stDetectedTag.CornerBL = cvMarkerCorners[unIter][3];
166 vDetectedTags.push_back(stDetectedTag);
170 return vDetectedTags;
188 std::vector<int> vIDs;
189 std::vector<std::vector<cv::Point2f>> cvMarkers;
192 for (
long unsigned int nIter = 0; nIter < vDetectedTags.size(); ++nIter)
195 vIDs.emplace_back(vDetectedTags[nIter].nID);
198 std::vector<cv::Point2f> cvMarkerCorners;
199 cvMarkerCorners.emplace_back(vDetectedTags[nIter].CornerTL);
200 cvMarkerCorners.emplace_back(vDetectedTags[nIter].CornerTR);
201 cvMarkerCorners.emplace_back(vDetectedTags[nIter].CornerBR);
202 cvMarkerCorners.emplace_back(vDetectedTags[nIter].CornerBL);
204 cvMarkers.emplace_back(cvMarkerCorners);
208 if (!cvDetectionsFrame.
empty() && (cvDetectionsFrame.
channels() == 1 || cvDetectionsFrame.
channels() == 3))
216 LOG_ERROR(logging::g_qSharedLogger,
217 "ArucoDetect: Unable to draw markers on image because it is empty or because it has {} channels. (Should be 1 or 3)",
237 if (constants::ZED_COORD_SYSTEM != sl::COORDINATE_SYSTEM::LEFT_HANDED_Y_UP)
240 LOG_CRITICAL(logging::g_qSharedLogger,
"ArucoDetection: Calculations won't work for anything other than ZED coordinate system == LEFT_HANDED_Y_UP");
247 if (cvCenter.
y > cvPointCloud.
rows || cvCenter.
x > cvPointCloud.
cols || cvCenter.
y < 0 || cvCenter.
x < 0)
249 LOG_ERROR(logging::g_qSharedLogger,
250 "Detected tag center ({}, {}) out of point cloud's domain ({},{})",
260 float fForward = cvCoordinate[2];
261 float fRight = cvCoordinate[0];
262 float fUp = cvCoordinate[1];
265 stTag.dStraightLineDistance =
sqrt(
pow(fForward, 2) +
pow(fRight, 2) +
pow(fUp, 2));
268 stTag.dYawAngle =
atan2(fRight, fForward);
293 cvObjPoints.
at<
cv::Vec3f>(3) =
cv::Vec3f{constants::ARUCO_TAG_SIDE_LENGTH, constants::ARUCO_TAG_SIDE_LENGTH, 0};
303 cv::solvePnP(cvObjPoints, cvImgPoints, cvCameraMatrix, cvDistCoeffs, cvRotVec, cvTransVec);
306 double dForward = cvTransVec[2];
307 double dRight = cvTransVec[0];
308 double dUp = cvTransVec[1];
311 stTag.dStraightLineDistance = std::sqrt(std::pow(dForward, 2) + std::pow(dRight, 2) + std::pow(dUp, 2));
314 stTag.dYawAngle = std::atan2(dRight, dForward);
void detectMarkers(InputArray image, OutputArrayOfArrays corners, OutputArray ids, OutputArrayOfArrays rejectedImgPoints=noArray()) const
bool solvePnP(InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int flags=SOLVEPNP_ITERATIVE)
void sqrt(InputArray src, OutputArray dst)
void pow(InputArray src, double power, OutputArray dst)
__device__ __forceinline__ float1 atan2(const uchar1 &a, const uchar1 &b)
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT)
void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays corners, InputArray ids=noArray(), Scalar borderColor=Scalar(0, 255, 0))
Namespace containing functions related to ArUco operations on images.
Definition ArucoDetection.hpp:34
void EstimatePoseFromPointCloud(const cv::Mat &cvPointCloud, ArucoTag &stTag)
Estimate the pose of a position with respect to the observer using a point cloud.
Definition ArucoDetection.hpp:234
cv::Point2f FindTagCenter(const ArucoTag &stTag)
Given an ArucoTag struct find the center point of the corners.
Definition ArucoDetection.hpp:67
std::vector< ArucoTag > Detect(const cv::Mat &cvFrame, const cv::aruco::ArucoDetector &cvArucoDetector)
Detect ArUco tags in the provided image.
Definition ArucoDetection.hpp:140
void DrawDetections(cv::Mat &cvDetectionsFrame, const std::vector< ArucoTag > &vDetectedTags)
Given a vector of ArucoTag structs draw each tag corner and ID onto the given image.
Definition ArucoDetection.hpp:185
void PreprocessFrame(const cv::Mat &cvInputFrame, cv::Mat &cvOutputFrame)
Preprocess images for specifically for the Aruco Detect() method. This method creates a copy of the c...
Definition ArucoDetection.hpp:96
void EstimatePoseFromPNP(cv::Mat &cvCameraMatrix, cv::Mat &cvDistCoeffs, ArucoTag &stTag)
Estimate the pose of a position with respect to the observer using an image.
Definition ArucoDetection.hpp:281
void ColorReduce(cv::Mat &cvFrame, int nDiv=64)
Given an image and a divisor, divide the precision of the elements.
Definition ImageOperations.hpp:295
Represents a single ArUco tag. Stores all information about a specific tag detection.
Definition ArucoDetection.hpp:44