blob: 7a2b9a245f2ac8617ff4e79f6cde9fd851e422d7 [file] [log] [blame]
Milind Upadhyayf61e1482022-02-11 20:42:55 -08001#ifndef Y2022_VISION_TARGET_ESTIMATOR_H_
2#define Y2022_VISION_TARGET_ESTIMATOR_H_
milind-u92195982022-01-22 20:29:31 -08003
Milind Upadhyayf61e1482022-02-11 20:42:55 -08004#include <optional>
5
6#include "Eigen/Dense"
7#include "Eigen/Geometry"
8#include "opencv2/core/types.hpp"
milind-u92195982022-01-22 20:29:31 -08009#include "opencv2/imgproc.hpp"
Philipp Schrader790cb542023-07-05 21:06:52 -070010
Milind Upadhyay8f38ad82022-03-03 10:06:18 -080011#include "y2022/vision/blob_detector.h"
milind-u92195982022-01-22 20:29:31 -080012#include "y2022/vision/target_estimate_generated.h"
13
14namespace y2022::vision {
Milind Upadhyay14279de2022-02-26 16:07:53 -080015
Milind Upadhyay8f38ad82022-03-03 10:06:18 -080016// Class to estimate the distance and rotation of the camera from the
Milind Upadhyayf61e1482022-02-11 20:42:55 -080017// target.
milind-u92195982022-01-22 20:29:31 -080018class TargetEstimator {
19 public:
Milind Upadhyayf61e1482022-02-11 20:42:55 -080020 TargetEstimator(cv::Mat intrinsics, cv::Mat extrinsics);
21
22 // Runs the solver to estimate the target
Milind Upadhyayf61e1482022-02-11 20:42:55 -080023 // If image != std::nullopt, the solver's progress will be displayed
24 // graphically.
Milind Upadhyay8f38ad82022-03-03 10:06:18 -080025 void Solve(const std::vector<BlobDetector::BlobStats> &blob_stats,
Milind Upadhyayf61e1482022-02-11 20:42:55 -080026 std::optional<cv::Mat> image);
27
28 // Cost function for the solver.
29 // Takes in the rotation of the camera in the hub's frame, the horizontal
30 // polar coordinates of the camera in the hub's frame, and the height of the
31 // camera (can change if the robot is shaking).
32 // Hub frame is relative to the center of the bottom of the hub.
33 // Compares the projected pieces of tape with these values to the detected
34 // blobs for calculating the cost.
35 template <typename S>
36 bool operator()(const S *const roll, const S *const pitch, const S *const yaw,
37 const S *const distance, const S *const theta,
38 const S *const camera_height, S *residual) const;
39
40 inline double roll() const { return roll_; }
41 inline double pitch() const { return pitch_; }
42 inline double yaw() const { return yaw_; }
43
44 inline double distance() const { return distance_; }
45 inline double angle_to_camera() const { return angle_to_camera_; }
46 inline double angle_to_target() const { return M_PI - yaw_; }
47 inline double camera_height() const { return camera_height_; }
48
Milind Upadhyay14279de2022-02-26 16:07:53 -080049 inline double confidence() const { return confidence_; }
50
Milind Upadhyay3336f3a2022-04-01 21:45:57 -070051 // Draws the distance, angle, rotation, and projected tape on the given image
Milind Upadhyayf61e1482022-02-11 20:42:55 -080052 void DrawEstimate(cv::Mat view_image) const;
milind-u92195982022-01-22 20:29:31 -080053
54 private:
Milind Upadhyayf61e1482022-02-11 20:42:55 -080055 // 3d points of the visible pieces of tape in the hub's frame
56 static const std::vector<cv::Point3d> kTapePoints;
Milind Upadhyay8f38ad82022-03-03 10:06:18 -080057 // 3d outer points of the middle piece of tape in the hub's frame,
58 // clockwise around the rectangle
59 static const std::array<cv::Point3d, 4> kMiddleTapePiecePoints;
60
Milind Upadhyay3336f3a2022-04-01 21:45:57 -070061 // Computes matrix of hub in camera's frame
62 template <typename S>
63 Eigen::Transform<S, 3, Eigen::Affine> ComputeHubCameraTransform(
64 S roll, S pitch, S yaw, S distance, S theta, S camera_height) const;
65
Milind Upadhyay8f38ad82022-03-03 10:06:18 -080066 template <typename S>
67 cv::Point_<S> ProjectToImage(
68 cv::Point3d tape_point_hub,
Milind Upadhyay3336f3a2022-04-01 21:45:57 -070069 const Eigen::Transform<S, 3, Eigen::Affine> &H_hub_camera) const;
Milind Upadhyayf61e1482022-02-11 20:42:55 -080070
71 template <typename S>
Austin Schuha685b5d2022-04-02 14:53:54 -070072 size_t ClosestTape(size_t centroid_index,
73 const std::vector<cv::Point_<S>> &tape_points) const;
74
75 template <typename S>
76 cv::Point_<S> DistanceFromTapeIndex(
Milind Upadhyay1c76a042022-04-02 20:42:42 -070077 size_t centroid_index, size_t tape_index,
Milind Upadhyayf61e1482022-02-11 20:42:55 -080078 const std::vector<cv::Point_<S>> &tape_points) const;
79
Milind Upadhyay3336f3a2022-04-01 21:45:57 -070080 void DrawProjectedHub(const std::vector<cv::Point2d> &tape_points_proj,
81 cv::Mat view_image) const;
82
Milind Upadhyay8f38ad82022-03-03 10:06:18 -080083 std::vector<BlobDetector::BlobStats> blob_stats_;
84 size_t middle_blob_index_;
Milind Upadhyay1c76a042022-04-02 20:42:42 -070085 double max_blob_area_;
Milind Upadhyayf61e1482022-02-11 20:42:55 -080086 std::optional<cv::Mat> image_;
87
88 Eigen::Matrix3d intrinsics_;
89 Eigen::Matrix4d extrinsics_;
90
91 double roll_;
92 double pitch_;
93 double yaw_;
94
95 double distance_;
96 double angle_to_camera_;
97 double camera_height_;
Milind Upadhyay14279de2022-02-26 16:07:53 -080098 double confidence_;
milind-u92195982022-01-22 20:29:31 -080099};
100
101} // namespace y2022::vision
102
Milind Upadhyayf61e1482022-02-11 20:42:55 -0800103#endif // Y2022_VISION_TARGET_ESTIMATOR_H_