blob: e89e9d85fd17817813bf91dd7b6a7e62321ce176 [file] [log] [blame]
Tyler Chatowbf0609c2021-07-31 16:13:27 -07001#include <gtk/gtk.h>
Parker Schuhd7db83d2017-02-08 20:49:15 -08002#include <netdb.h>
3#include <unistd.h>
4
Tyler Chatowbf0609c2021-07-31 16:13:27 -07005#include <cstdio>
6#include <cstdlib>
Parker Schuhd7db83d2017-02-08 20:49:15 -08007#include <memory>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07008#include <vector>
Parker Schuhd7db83d2017-02-08 20:49:15 -08009
Tyler Chatowbf0609c2021-07-31 16:13:27 -070010#include "aos/vision/blob/codec.h"
11#include "aos/vision/blob/range_image.h"
12#include "aos/vision/blob/stream_view.h"
13#include "aos/vision/events/epoll_events.h"
Parker Schuhd7db83d2017-02-08 20:49:15 -080014#include "aos/vision/events/socket_types.h"
15#include "aos/vision/events/tcp_client.h"
Tyler Chatowbf0609c2021-07-31 16:13:27 -070016#include "aos/vision/image/image_types.h"
17#include "aos/vision/image/jpeg_routines.h"
Parker Schuhd7db83d2017-02-08 20:49:15 -080018#include "y2016/vision/blob_filters.h"
Tyler Chatowbf0609c2021-07-31 16:13:27 -070019#include "y2016/vision/stereo_geometry.h"
20#include "y2016/vision/vision_data.pb.h"
Parker Schuhd7db83d2017-02-08 20:49:15 -080021
22using namespace aos::vision;
23
24class StereoViewer {
25 public:
26 StereoViewer(int width, int height)
27 : blob_filt_(ImageFormat(width, height), 40, 100, 250000) {
28 overlays_.push_back(&overlay_);
29 view_.view()->SetOverlays(&overlays_);
30
31 // Uncomment to enable blob_filt_ overlay.
32 // blob_filt_.EnableOverlay(&overlay_);
33 finder_.EnableOverlay(&overlay_);
34 }
35
36 virtual ~StereoViewer() {}
37
38 void SetBlob(int camera_index, BlobList &blobl) {
39 if (camera_index == 0) {
40 left_blobs.swap(blobl);
41 new_left = true;
42 } else {
43 right_blobs.swap(blobl);
44 new_right = true;
45 }
46 }
47
48 void Process(ImageFormat fmt) {
49 if (new_left && new_right) {
50 overlay_.Reset();
51 DrawCross(overlay_, Vector<2>(fmt.w / 2.0, fmt.h / 2.0), {0, 255, 0});
52
53 view_.SetFormatAndClear(fmt);
54 printf("right (%d) left (%d)\n", (int)left_blobs.size(),
55 (int)right_blobs.size());
56 std::vector<std::pair<Vector<2>, Vector<2>>> cornersA =
57 finder_.Find(blob_filt_.FilterBlobs(left_blobs));
58 std::vector<std::pair<Vector<2>, Vector<2>>> cornersB =
59 finder_.Find(blob_filt_.FilterBlobs(right_blobs));
60 view_.DrawBlobList(left_blobs, {255, 0, 0});
61 view_.DrawSecondBlobList(right_blobs, {0, 255, 0}, {0, 0, 255});
62 view_.view()->Redraw();
63 new_left = false;
64 new_right = false;
65 }
66 }
67
68 private:
69 void DrawCross(PixelLinesOverlay &overlay, Vector<2> center, PixelRef color) {
Parker Schuh24ee58d2017-03-11 16:13:23 -080070 overlay.AddLine(Vector<2>(center.x() - 50, center.y()),
Tyler Chatowbf0609c2021-07-31 16:13:27 -070071 Vector<2>(center.x() + 50, center.y()), color);
Parker Schuh24ee58d2017-03-11 16:13:23 -080072 overlay.AddLine(Vector<2>(center.x(), center.y() - 50),
Tyler Chatowbf0609c2021-07-31 16:13:27 -070073 Vector<2>(center.x(), center.y() + 50), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -080074 }
75
76 // where we darw for debugging
77 PixelLinesOverlay overlay_;
78
79 // container for viewer
80 std::vector<OverlayBase *> overlays_;
81 BlobStreamViewer view_;
82
83 bool new_left = false;
84 BlobList left_blobs;
85 bool new_right = false;
86 BlobList right_blobs;
87
88 // our blob processing object
89 HistogramBlobFilter blob_filt_;
90
91 // corner finder to align aiming
92 CornerFinder finder_;
93};
94
95class BufferedLengthDelimReader {
96 public:
97 union data_len {
98 uint32_t len;
99 char buf[4];
100 };
101 BufferedLengthDelimReader() {
102 num_read_ = 0;
103 img_read_ = -1;
104 }
105 template <typename Lamb>
106 void up(int fd, Lamb lam) {
107 ssize_t count;
108 if (img_read_ < 0) {
109 count = read(fd, &len_.buf[num_read_], sizeof(len_.buf) - num_read_);
110 if (count < 0) return;
111 num_read_ += count;
112 if (num_read_ < 4) return;
113 num_read_ = 0;
114 img_read_ = 0;
115 data_.clear();
116 if (len_.len > 200000) {
117 printf("bad size: %d\n", len_.len);
118 exit(-1);
119 }
120 data_.resize(len_.len);
121 } else {
122 count = read(fd, &data_[img_read_], len_.len - img_read_);
123 if (count < 0) return;
124 img_read_ += count;
125 if (img_read_ < (int)len_.len) return;
126 lam(DataRef{&data_[0], len_.len});
127 img_read_ = -1;
128 }
129 }
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700130
Parker Schuhd7db83d2017-02-08 20:49:15 -0800131 private:
132 data_len len_;
133 int num_read_;
134 std::vector<char> data_;
135 int img_read_;
136};
137
138class ProtoClient : public aos::events::TcpClient {
139 public:
140 ProtoClient(int camera_index, int width, int height, const char *hostname,
141 int portno, StereoViewer *stereo)
142 : aos::events::TcpClient(hostname, portno),
143 camera_index_(camera_index),
144 fmt_(width, height),
145 stereo_(stereo) {}
146
147 void ReadEvent() override {
148 read_.up(fd(), [&](DataRef data) {
149 BlobList blobl;
150 y2016::vision::VisionData target;
151 if (target.ParseFromArray(data.data(), data.size())) {
152 auto &raw = target.raw();
153 ParseBlobList(&blobl, raw.data());
154 stereo_->SetBlob(camera_index_, blobl);
155 stereo_->Process(fmt_);
156 }
157 });
158 }
159
160 int camera_index_;
161
162 ImageFormat fmt_;
163
164 BufferedLengthDelimReader read_;
165 std::unique_ptr<PixelRef[]> outbuf;
166 ImagePtr ptr;
167 StereoViewer *stereo_;
168
169 private:
170};
171
172int main(int argc, char *argv[]) {
173 aos::events::EpollLoop loop;
174 gtk_init(&argc, &argv);
175
176 y2016::vision::Calibration calib =
177 y2016::vision::StereoGeometry("competition").calibration();
178
179 StereoViewer stereo(calib.camera_image_width(), calib.camera_image_height());
180
181 ProtoClient client0(0, calib.camera_image_width(),
182 calib.camera_image_height(),
183 calib.jetson_ip_addr().data(), 8082, &stereo);
184 ProtoClient client1(1, calib.camera_image_width(),
185 calib.camera_image_height(),
186 calib.jetson_ip_addr().data(), 8083, &stereo);
187
188 loop.Add(&client0);
189 loop.Add(&client1);
190 loop.RunWithGtkMain();
191 return EXIT_SUCCESS;
192}