blob: 08def5bef78635d78d683839fac4abce2ca0b648 [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"
9#include "frc971/vision/vision_generated.h"
10
11DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
12DEFINE_string(channel, "/camera", "Channel name for the image.");
13
14DEFINE_string(capture, "",
15 "If set, capture a single image and save it to this filename.");
16
17namespace frc971 {
18namespace vision {
19namespace {
20
21aos::Fetcher<CameraImage> image_fetcher;
22bool DisplayLoop() {
23 const CameraImage *image;
24
25 // Read next image
26 if (!image_fetcher.Fetch()) {
27 VLOG(2) << "Couldn't fetch next image";
28 return true;
29 }
30
31 image = image_fetcher.get();
32 CHECK(image != nullptr) << "Couldn't read image";
33
34 // Create color image:
35 cv::Mat image_color_mat(cv::Size(image->cols(), image->rows()), CV_8UC2,
36 (void *)image->data()->data());
37 cv::Mat bgr_image(cv::Size(image->cols(), image->rows()), CV_8UC3);
38 cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
39
40 if (!FLAGS_capture.empty()) {
Ravago Jones17e13a22023-01-28 17:12:11 -080041 if (absl::EndsWith(FLAGS_capture, ".bfbs")) {
42 aos::WriteFlatbufferToFile(FLAGS_capture, image_fetcher.CopyFlatBuffer());
43 } else {
44 cv::imwrite(FLAGS_capture, bgr_image);
45 }
46
Austin Schuhdb2ed9d2022-12-26 14:02:26 -080047 return false;
48 }
49
50 cv::imshow("Display", bgr_image);
51 int keystroke = cv::waitKey(1);
52 if ((keystroke & 0xFF) == static_cast<int>('c')) {
53 // Convert again, to get clean image
54 cv::cvtColor(image_color_mat, bgr_image, cv::COLOR_YUV2BGR_YUYV);
55 std::stringstream name;
56 name << "capture-" << aos::realtime_clock::now() << ".png";
57 cv::imwrite(name.str(), bgr_image);
58 LOG(INFO) << "Saved image file: " << name.str();
59 } else if ((keystroke & 0xFF) == static_cast<int>('q')) {
60 return false;
61 }
62 return true;
63}
64
65void ViewerMain() {
66 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
67 aos::configuration::ReadConfig(FLAGS_config);
68
69 aos::ShmEventLoop event_loop(&config.message());
70
71 image_fetcher = event_loop.MakeFetcher<CameraImage>(FLAGS_channel);
72
73 // Run the display loop
74 event_loop.AddPhasedLoop(
75 [&event_loop](int) {
76 if (!DisplayLoop()) {
77 LOG(INFO) << "Calling event_loop Exit";
78 event_loop.Exit();
79 };
80 },
81 ::std::chrono::milliseconds(100));
82
83 event_loop.Run();
84
85 image_fetcher = aos::Fetcher<CameraImage>();
86}
87
88} // namespace
89} // namespace vision
90} // namespace frc971
91
92int main(int argc, char **argv) {
93 aos::InitGoogle(&argc, &argv);
94 frc971::vision::ViewerMain();
95}