blob: e8dc3ebc5a4afe340a47ca2d4292f2ae5af2167c [file] [log] [blame]
Austin Schuh25837f22021-06-27 15:49:14 -07001#ifndef Y2020_VISION_CHARUCO_LIB_H_
2#define Y2020_VISION_CHARUCO_LIB_H_
3
4#include <functional>
5#include <string_view>
6
7#include <opencv2/aruco/charuco.hpp>
8#include <opencv2/calib3d.hpp>
9#include "Eigen/Dense"
10#include "Eigen/Geometry"
11
12#include "absl/types/span.h"
13#include "aos/events/event_loop.h"
14#include "y2020/vision/sift/sift_generated.h"
15#include "y2020/vision/sift/sift_training_generated.h"
16
17namespace frc971 {
18namespace vision {
19
20// Class to find extrinsics for a specified pi's camera using the provided
21// training data.
22class CameraCalibration {
23 public:
24 CameraCalibration(const absl::Span<const uint8_t> training_data_bfbs,
25 std::string_view pi);
26
27 // Intrinsics for the located camera.
28 cv::Mat CameraIntrinsics() const;
29 Eigen::Matrix3d CameraIntrinsicsEigen() const;
30
31 // Distortion coefficients for the located camera.
32 cv::Mat CameraDistCoeffs() const;
33
34 private:
35 // Finds the camera specific calibration flatbuffer.
36 const sift::CameraCalibration *FindCameraCalibration(
37 const sift::TrainingData *const training_data, std::string_view pi) const;
38
39 // Pointer to this camera's calibration parameters.
40 const sift::CameraCalibration *camera_calibration_;
41};
42
43// Class to call a function with a cv::Mat and age when an image shows up on the
44// provided channel. This hides all the conversions and wrangling needed to
45// view the image.
46class ImageCallback {
47 public:
48 ImageCallback(aos::EventLoop *event_loop, std::string_view channel,
49 std::function<void(cv::Mat, double)> &&fn);
50
51 private:
52 aos::EventLoop *event_loop_;
53 std::function<void(cv::Mat, double)> handle_image_;
54};
55
56// Class which calls a callback each time an image arrives with the information
57// extracted from it.
58class CharucoExtractor {
59 public:
60 // The callback takes the following arguments:
61 // cv::Mat -> image with overlays drawn on it.
62 // const double -> Duration between when the image was captured and this
63 // callback was called.
64 // std::vector<int> -> charuco_ids
65 // std::vector<cv::Point2f> -> charuco_corners
66 // bool -> true if rvec/tvec is valid.
67 // Eigen::Vector3d -> rvec
68 // Eigen::Vector3d -> tvec
69 CharucoExtractor(aos::EventLoop *event_loop, std::string_view pi,
70 std::function<void(cv::Mat, const double, std::vector<int>,
71 std::vector<cv::Point2f>, bool,
72 Eigen::Vector3d, Eigen::Vector3d)> &&fn);
73
74 // Returns the aruco dictionary in use.
75 cv::Ptr<cv::aruco::Dictionary> dictionary() const { return dictionary_; }
76 // Returns the aruco board in use.
77 cv::Ptr<cv::aruco::CharucoBoard> board() const { return board_; }
78
79 // Returns the camera matrix for this camera.
80 const cv::Mat camera_matrix() const { return camera_matrix_; }
81 // Returns the distortion coefficients for this camera.
82 const cv::Mat dist_coeffs() const { return dist_coeffs_; }
83
84 private:
85 // Handles the image by detecting the charuco board in it and calling the
86 // callback with the extracted board corners, corresponding IDs, and pose.
87 void HandleImage(cv::Mat rgb_image, const double age_double);
88
89 CameraCalibration calibration_;
90
91 cv::Ptr<cv::aruco::Dictionary> dictionary_;
92 cv::Ptr<cv::aruco::CharucoBoard> board_;
93
94 const cv::Mat camera_matrix_;
95 const Eigen::Matrix3d eigen_camera_matrix_;
96 const cv::Mat dist_coeffs_;
97
98 const std::optional<uint16_t> pi_number_;
99
100 ImageCallback image_callback_;
101
102 // Function to call.
103 std::function<void(cv::Mat, const double, std::vector<int>,
104 std::vector<cv::Point2f>, bool, Eigen::Vector3d,
105 Eigen::Vector3d)>
106 handle_charuco_;
107};
108
109} // namespace vision
110} // namespace frc971
111
112#endif // Y2020_VISION_CHARUCO_LIB_H_