blob: 7877a57aa7dfff18840cd1eceddd7f33a52750a0 [file] [log] [blame]
Austin Schuhdb2ed9d2022-12-26 14:02:26 -08001#include <opencv2/highgui/highgui.hpp>
2#include <opencv2/imgproc.hpp>
3
Ravago Jones17e13a22023-01-28 17:12:11 -08004#include "absl/strings/match.h"
Austin Schuhdb2ed9d2022-12-26 14:02:26 -08005#include "aos/events/shm_event_loop.h"
6#include "aos/init.h"
Ravago Jones17e13a22023-01-28 17:12:11 -08007#include "aos/json_to_flatbuffer.h"
Austin Schuhdb2ed9d2022-12-26 14:02:26 -08008#include "aos/time/time.h"
milind-uc3cf9752023-02-20 23:07:30 -08009#include "frc971/constants/constants_sender_lib.h"
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080010#include "frc971/vision/vision_generated.h"
milind-uc3cf9752023-02-20 23:07:30 -080011#include "opencv2/calib3d.hpp"
12#include "opencv2/imgproc.hpp"
13#include "y2023/vision/april_debug_generated.h"
14#include "y2023/vision/vision_util.h"
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080015
16DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
17DEFINE_string(channel, "/camera", "Channel name for the image.");
18
19DEFINE_string(capture, "",
20 "If set, capture a single image and save it to this filename.");
21
Austin Schuhceb96542023-02-04 11:43:33 -080022DEFINE_int32(rate, 100, "Time in milliseconds to wait between images");
23
milind-uc3cf9752023-02-20 23:07:30 -080024namespace y2023 {
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080025namespace vision {
26namespace {
27
milind-uc3cf9752023-02-20 23:07:30 -080028using frc971::vision::CameraImage;
29
30bool DisplayLoop(const cv::Mat intrinsics, const cv::Mat dist_coeffs,
31 aos::Fetcher<CameraImage> *image_fetcher,
32 aos::Fetcher<AprilDebug> *april_debug_fetcher) {
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080033 const CameraImage *image;
milind-uc3cf9752023-02-20 23:07:30 -080034 std::optional<const AprilDebug *> april_debug = std::nullopt;
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080035
36 // Read next image
milind-uc3cf9752023-02-20 23:07:30 -080037 if (!image_fetcher->Fetch()) {
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080038 VLOG(2) << "Couldn't fetch next image";
39 return true;
40 }
milind-uc3cf9752023-02-20 23:07:30 -080041 image = image_fetcher->get();
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080042 CHECK(image != nullptr) << "Couldn't read image";
43
milind-uc3cf9752023-02-20 23:07:30 -080044 if (april_debug_fetcher->Fetch()) {
45 april_debug = april_debug_fetcher->get();
46 } else {
47 VLOG(2) << "Couldn't fetch next target map";
48 }
49
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080050 // Create color image:
51 cv::Mat image_color_mat(cv::Size(image->cols(), image->rows()), CV_8UC2,
52 (void *)image->data()->data());
53 cv::Mat bgr_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
54 cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
55
56 if (!FLAGS_capture.empty()) {
Ravago Jones17e13a22023-01-28 17:12:11 -080057 if (absl::EndsWith(FLAGS_capture, ".bfbs")) {
milind-uc3cf9752023-02-20 23:07:30 -080058 aos::WriteFlatbufferToFile(FLAGS_capture,
59 image_fetcher->CopyFlatBuffer());
Ravago Jones17e13a22023-01-28 17:12:11 -080060 } else {
61 cv::imwrite(FLAGS_capture, bgr_image);
62 }
63
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080064 return false;
65 }
66
milind-uc3cf9752023-02-20 23:07:30 -080067 cv::Mat undistorted_image;
68 cv::undistort(bgr_image, undistorted_image, intrinsics, dist_coeffs);
69
70 if (april_debug.has_value() && april_debug.value()->corners()->size() > 0) {
71 for (const auto *corners : *april_debug.value()->corners()) {
72 std::vector<cv::Point> points;
73 for (const auto *point_fbs : *corners->points()) {
74 points.emplace_back(point_fbs->x(), point_fbs->y());
75 }
76 cv::polylines(undistorted_image, points, true, cv::Scalar(255, 0, 0), 10);
77 }
78 }
79
80 cv::imshow("Display", undistorted_image);
81
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080082 int keystroke = cv::waitKey(1);
83 if ((keystroke & 0xFF) == static_cast<int>('c')) {
84 // Convert again, to get clean image
85 cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
86 std::stringstream name;
87 name << "capture-" << aos::realtime_clock::now() << ".png";
88 cv::imwrite(name.str(), bgr_image);
89 LOG(INFO) << "Saved image file: " << name.str();
90 } else if ((keystroke & 0xFF) == static_cast<int>('q')) {
91 return false;
92 }
93 return true;
94}
95
96void ViewerMain() {
97 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
98 aos::configuration::ReadConfig(FLAGS_config);
99
milind-uc3cf9752023-02-20 23:07:30 -0800100 frc971::constants::WaitForConstants<Constants>(&config.message());
101
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800102 aos::ShmEventLoop event_loop(&config.message());
103
milind-uc3cf9752023-02-20 23:07:30 -0800104 frc971::constants::ConstantsFetcher<Constants> constants_fetcher(&event_loop);
105 const auto *calibration_data = FindCameraCalibration(
106 constants_fetcher.constants(), event_loop.node()->name()->string_view());
107 const cv::Mat intrinsics = CameraIntrinsics(calibration_data);
108 const cv::Mat dist_coeffs = CameraDistCoeffs(calibration_data);
109
110 aos::Fetcher<CameraImage> image_fetcher =
111 event_loop.MakeFetcher<CameraImage>(FLAGS_channel);
112 aos::Fetcher<AprilDebug> april_debug_fetcher =
113 event_loop.MakeFetcher<AprilDebug>("/camera");
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800114
115 // Run the display loop
116 event_loop.AddPhasedLoop(
milind-uc3cf9752023-02-20 23:07:30 -0800117 [&](int) {
118 if (!DisplayLoop(intrinsics, dist_coeffs, &image_fetcher,
119 &april_debug_fetcher)) {
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800120 LOG(INFO) << "Calling event_loop Exit";
121 event_loop.Exit();
122 };
123 },
Austin Schuhceb96542023-02-04 11:43:33 -0800124 ::std::chrono::milliseconds(FLAGS_rate));
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800125
126 event_loop.Run();
127
128 image_fetcher = aos::Fetcher<CameraImage>();
129}
130
131} // namespace
132} // namespace vision
milind-uc3cf9752023-02-20 23:07:30 -0800133} // namespace y2023
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800134
135int main(int argc, char **argv) {
136 aos::InitGoogle(&argc, &argv);
milind-uc3cf9752023-02-20 23:07:30 -0800137 y2023::vision::ViewerMain();
Austin Schuhdb2ed9d2022-12-26 14:02:26 -0800138}