Add viewer replay for 2022
Signed-off-by: Milind Upadhyay <milind.upadhyay@gmail.com>
Change-Id: Ic6a4fc0cc9edc68ba6b48ce92ce13814ab9e5ae6
diff --git a/y2022/vision/BUILD b/y2022/vision/BUILD
index e9543cf..02f7fc7 100644
--- a/y2022/vision/BUILD
+++ b/y2022/vision/BUILD
@@ -239,6 +239,26 @@
)
cc_binary(
+ name = "viewer_replay",
+ srcs = [
+ "viewer_replay.cc",
+ ],
+ data = [
+ "//y2022:aos_config",
+ ],
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//y2022:__subpackages__"],
+ deps = [
+ ":blob_detector_lib",
+ "//aos:init",
+ "//aos/events:simulated_event_loop",
+ "//aos/events/logging:log_reader",
+ "//frc971/vision:vision_fbs",
+ "//third_party:opencv",
+ ],
+)
+
+cc_binary(
name = "extrinsics_calibration",
srcs = [
"extrinsics_calibration.cc",
diff --git a/y2022/vision/viewer_replay.cc b/y2022/vision/viewer_replay.cc
new file mode 100644
index 0000000..c1bf88b
--- /dev/null
+++ b/y2022/vision/viewer_replay.cc
@@ -0,0 +1,81 @@
+#include "aos/events/logging/log_reader.h"
+#include "aos/events/simulated_event_loop.h"
+#include "aos/init.h"
+#include "frc971/vision/vision_generated.h"
+#include "opencv2/calib3d.hpp"
+#include "opencv2/features2d.hpp"
+#include "opencv2/highgui/highgui.hpp"
+#include "opencv2/imgproc.hpp"
+#include "y2022/vision/blob_detector.h"
+
+DEFINE_string(node, "pi1", "Node name to replay.");
+DEFINE_string(image_save_prefix, "/tmp/img",
+ "Prefix to use for saving images from the logfile.");
+DEFINE_bool(display, false, "If true, display the images with a timeout.");
+DEFINE_bool(detected_only, false,
+ "If true, only write images which had blobs (unfiltered) detected");
+DEFINE_bool(filtered_only, false,
+ "If true, only write images which had blobs (filtered) detected");
+
+namespace y2022 {
+namespace vision {
+namespace {
+
+void ViewerMain(int argc, char *argv[]) {
+ std::vector<std::string> unsorted_logfiles =
+ aos::logger::FindLogs(argc, argv);
+
+ // Open logfiles
+ aos::logger::LogReader reader(aos::logger::SortParts(unsorted_logfiles));
+ reader.Register();
+ const aos::Node *node = nullptr;
+ if (aos::configuration::MultiNode(reader.configuration())) {
+ node = aos::configuration::GetNode(reader.configuration(), FLAGS_node);
+ }
+ std::unique_ptr<aos::EventLoop> event_loop =
+ reader.event_loop_factory()->MakeEventLoop("player", node);
+
+ int image_count = 0;
+ event_loop->MakeWatcher(
+ "/camera/decimated",
+ [&image_count](const frc971::vision::CameraImage &image) {
+ // Create color image:
+ cv::Mat image_color_mat(cv::Size(image.cols(), image.rows()), CV_8UC2,
+ (void *)image.data()->data());
+ cv::Mat image_mat(cv::Size(image.cols(), image.rows()), CV_8UC3);
+ cv::cvtColor(image_color_mat, image_mat, cv::COLOR_YUV2BGR_YUYV);
+
+ bool use_image = true;
+ if (FLAGS_detected_only || FLAGS_filtered_only) {
+ BlobDetector::BlobResult blob_result;
+ BlobDetector::ExtractBlobs(image_mat, &blob_result);
+
+ use_image =
+ ((FLAGS_filtered_only ? blob_result.filtered_blobs.size()
+ : blob_result.unfiltered_blobs.size()) > 0);
+ }
+ if (use_image) {
+ if (!FLAGS_image_save_prefix.empty()) {
+ cv::imwrite(FLAGS_image_save_prefix +
+ std::to_string(image_count++) + ".png",
+ image_mat);
+ }
+ if (FLAGS_display) {
+ cv::imshow("Display", image_mat);
+ cv::waitKey(FLAGS_detected_only || FLAGS_filtered_only ? 10 : 1);
+ }
+ }
+ });
+
+ reader.event_loop_factory()->Run();
+}
+
+} // namespace
+} // namespace vision
+} // namespace y2022
+
+// Quick and lightweight viewer for image logs
+int main(int argc, char **argv) {
+ aos::InitGoogle(&argc, &argv);
+ y2022::vision::ViewerMain(argc, argv);
+}