blob: 1c15259b249acc60f27a5efef4ecb99fd324f393 [file] [log] [blame]
Parker Schuhd7db83d2017-02-08 20:49:15 -08001#include <endian.h>
Parker Schuhd7db83d2017-02-08 20:49:15 -08002#include <gdk/gdk.h>
3#include <gtk/gtk.h>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07004#include <sys/stat.h>
Parker Schuhd7db83d2017-02-08 20:49:15 -08005
Tyler Chatowbf0609c2021-07-31 16:13:27 -07006#include <cstdio>
7#include <cstdlib>
8#include <fstream>
9#include <memory>
10#include <vector>
11
12#include "aos/vision/blob/stream_view.h"
Parker Schuhd7db83d2017-02-08 20:49:15 -080013#include "aos/vision/events/epoll_events.h"
14#include "aos/vision/events/tcp_server.h"
Tyler Chatowbf0609c2021-07-31 16:13:27 -070015#include "aos/vision/image/image_stream.h"
16#include "aos/vision/image/jpeg_routines.h"
17#include "aos/vision/image/reader.h"
Parker Schuhd7db83d2017-02-08 20:49:15 -080018#include "y2016/vision/blob_filters.h"
19// #include "y2016/vision/process_targets.h"
20
Stephan Pleinesf63bde82024-01-13 15:59:33 -080021namespace y2016::vision {
Parker Schuhd7db83d2017-02-08 20:49:15 -080022using namespace aos::vision;
23
Tyler Chatowbf0609c2021-07-31 16:13:27 -070024::aos::vision::Vector<2> CreateCenterFromTarget(double lx, double ly, double rx,
25 double ry) {
Parker Schuhd7db83d2017-02-08 20:49:15 -080026 return ::aos::vision::Vector<2>((lx + rx) / 2.0, (ly + ry) / 2.0);
27}
28
29double TargetWidth(double lx, double ly, double rx, double ry) {
30 double dx = lx - rx;
31 double dy = ly - ry;
32 return ::std::hypot(dx, dy);
33}
34
Tyler Chatowbf0609c2021-07-31 16:13:27 -070035void SelectTargets(std::vector<std::pair<Vector<2>, Vector<2>>> &left_target,
36 std::vector<std::pair<Vector<2>, Vector<2>>> &right_target,
Parker Schuhd7db83d2017-02-08 20:49:15 -080037 ::aos::vision::Vector<2> *center_left,
38 ::aos::vision::Vector<2> *center_right) {
39 // No good targets. Let the caller decide defaults.
40 if (right_target.size() == 0 || left_target.size() == 0) {
41 return;
42 }
43
44 // Only one option, we have to go with it.
45 if (right_target.size() == 1 && left_target.size() == 1) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -070046 *center_left = CreateCenterFromTarget(
47 left_target[0].first.x(), left_target[0].first.y(),
48 left_target[0].second.x(), left_target[0].second.y());
Parker Schuhd7db83d2017-02-08 20:49:15 -080049 *center_right = CreateCenterFromTarget(
Tyler Chatowbf0609c2021-07-31 16:13:27 -070050 right_target[0].first.x(), right_target[0].first.y(),
51 right_target[0].second.x(), right_target[0].second.y());
Parker Schuhd7db83d2017-02-08 20:49:15 -080052 return;
53 }
54
55 // Now we have to make a decision.
56 double min_angle = -1.0;
57 int left_index = 0;
58 // First pick the widest target from the left.
59 for (size_t i = 0; i < left_target.size(); i++) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -070060 const double h = left_target[i].first.y() - left_target[i].second.y();
61 const double wid1 =
62 TargetWidth(left_target[i].first.x(), left_target[i].first.y(),
63 left_target[i].second.x(), left_target[i].second.y());
Parker Schuhd7db83d2017-02-08 20:49:15 -080064 const double angle = h / wid1;
65 if (min_angle == -1.0 || ::std::abs(angle) < ::std::abs(min_angle)) {
66 min_angle = angle;
67 left_index = i;
68 }
69 }
70 // Calculate the angle of the bottom edge for the left.
Tyler Chatowbf0609c2021-07-31 16:13:27 -070071 double h =
72 left_target[left_index].first.y() - left_target[left_index].second.y();
Parker Schuhd7db83d2017-02-08 20:49:15 -080073
74 double good_ang = min_angle;
75 double min_ang_err = -1.0;
76 int right_index = -1;
Tyler Chatowbf0609c2021-07-31 16:13:27 -070077 // Now pick the bottom edge angle from the right that lines up best with the
78 // left.
Parker Schuhd7db83d2017-02-08 20:49:15 -080079 for (size_t j = 0; j < right_target.size(); j++) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -070080 double wid2 =
81 TargetWidth(right_target[j].first.x(), right_target[j].first.y(),
82 right_target[j].second.x(), right_target[j].second.y());
83 h = right_target[j].first.y() - right_target[j].second.y();
84 double ang = h / wid2;
Parker Schuhd7db83d2017-02-08 20:49:15 -080085 double ang_err = ::std::abs(good_ang - ang);
86 if (min_ang_err == -1.0 || min_ang_err > ang_err) {
87 min_ang_err = ang_err;
88 right_index = j;
89 }
90 }
91
Tyler Chatowbf0609c2021-07-31 16:13:27 -070092 *center_left = CreateCenterFromTarget(
93 left_target[left_index].first.x(), left_target[left_index].first.y(),
94 left_target[left_index].second.x(), left_target[left_index].second.y());
95 *center_right = CreateCenterFromTarget(right_target[right_index].first.x(),
96 right_target[right_index].first.y(),
97 right_target[right_index].second.x(),
98 right_target[right_index].second.y());
Parker Schuhd7db83d2017-02-08 20:49:15 -080099}
100
Parker Schuhd7db83d2017-02-08 20:49:15 -0800101long GetFileSize(std::string filename) {
102 struct stat stat_buf;
103 int rc = stat(filename.c_str(), &stat_buf);
104 return rc == 0 ? stat_buf.st_size : -1;
105}
106
107class OutputFile {
108 public:
109 OutputFile(const std::string &fname) : ofs(fname, std::ofstream::out) {}
110
111 void Emit(const BlobList &blobl, int64_t timestamp) {
112 int tmp_size = CalculateSize(blobl) + sizeof(int32_t) + sizeof(uint64_t);
113 tmp_buf.resize(tmp_size, 0);
114 {
115 char *buf = Int64Codec::Write(&tmp_buf[0], tmp_size);
116 buf = Int64Codec::Write(buf, timestamp);
117 SerializeBlob(blobl, buf);
118 }
119 ofs.write(&tmp_buf[0], tmp_size);
120 printf("blob_size: %d\n", tmp_size);
121 }
122
123 std::vector<char> tmp_buf;
124
125 std::ofstream ofs;
126};
127
128class InputFile {
129 public:
130 InputFile(const std::string &fname)
131 : ifs_(fname, std::ifstream::in), len_(GetFileSize(fname)) {
132 if (len_ <= 0) {
133 printf("File (%s) not found. Size (%d)\n", fname.c_str(), (int)len_);
134 fflush(stdout);
135 }
136 assert(len_ > 0);
137 tmp_buf_.resize(len_, 0);
138 ifs_.read(&tmp_buf_[0], len_);
139 buf_ = &tmp_buf_[0];
140 }
141
142 bool ReadNext(BlobList *blob_list, uint64_t *timestamp) {
143 if (buf_ - &tmp_buf_[0] >= len_) return false;
144 if (prev_ != nullptr) prev_frames_.emplace_back(prev_);
145 prev_ = buf_;
146 buf_ += sizeof(uint32_t);
147 *timestamp = Int64Codec::Read(&buf_);
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700148 // auto* buf_tmp = buf_;
Parker Schuhd7db83d2017-02-08 20:49:15 -0800149 buf_ = ParseBlobList(blob_list, buf_);
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700150 // fprintf(stderr, "read frame: %lu, buf_size: %lu\n", *timestamp, buf_ -
151 // buf_tmp);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800152 return true;
153 }
154
155 bool ReadPrev(BlobList *blob_list, uint64_t *timestamp) {
156 if (prev_frames_.empty()) return false;
157 buf_ = prev_frames_.back();
158 prev_frames_.pop_back();
159 buf_ += sizeof(uint32_t);
160 *timestamp = Int64Codec::Read(&buf_);
161 buf_ = ParseBlobList(blob_list, buf_);
162 prev_ = nullptr;
163 return true;
164 }
165
166 private:
167 std::vector<const char *> prev_frames_;
168 const char *buf_;
169 const char *prev_ = nullptr;
170 std::ifstream ifs_;
171
172 long len_;
173 std::vector<char> tmp_buf_;
174};
175
176class BlobStreamFrame {
177 public:
178 BlobList blob_list;
179 uint64_t timestamp;
180 void ReadNext(InputFile *fin) {
181 blob_list.clear();
182 if (!fin->ReadNext(&blob_list, &timestamp)) {
183 exit(0);
184 return;
185 }
186 }
187 bool ReadPrev(InputFile *fin) {
188 blob_list.clear();
189 return fin->ReadPrev(&blob_list, &timestamp);
190 }
191};
192
193const char *kHudText =
194 "commands:\n"
195 " SPACE - pause\n"
196 " c - continue to next target\n"
197 " s - single step while paused\n"
198 " k - pause on next target frame\n"
199 " u - change window scaling\n"
200 " a - single step backward\n"
201 " q - quit\n"
202 " h - help\n";
203
204class NetworkForwardingImageStream : public aos::events::EpollWait {
205 public:
206 NetworkForwardingImageStream(ImageFormat fmt, int debug_level,
207 const std::string &fname1,
208 const std::string &fname2)
209 : fmt_(fmt),
210 ifs1_(fname1),
211 ifs2_(fname2),
212 blob_filt_(fmt, 40, 750, 250000),
213 finder_(0.25, 35) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700214 text_overlay_.draw_fn = [this](RenderInterface *render, double /*width*/,
215 double /*height*/) {
Parker Schuhd7db83d2017-02-08 20:49:15 -0800216 render->SetSourceRGB(1.0, 1.0, 1.0);
217 if (hud_text) render->Text(20, 20, 0, 0, kHudText);
218 };
219
220 overlays_.push_back(&overlay_);
221 overlays_.push_back(&text_overlay_);
222 view_.view()->SetOverlays(&overlays_);
223
224 if (debug_level > 0) {
225 finder_.EnableOverlay(&overlay_);
226 }
227 if (debug_level > 1) {
228 blob_filt_.EnableOverlay(&overlay_);
229 }
230
231 frame1.ReadNext(&ifs1_);
232 frame2.ReadNext(&ifs2_);
233
234 std::pair<int, int> skip =
235 TickFrame(std::max(frame1.timestamp, frame2.timestamp));
236 printf("Initialzation skipped (%d, %d)\n", skip.first, skip.second);
237
238 ms_event_delta_ = 20;
239 play_forward = true;
240 paused = false;
241 single_step = false;
242 pause_on_next_target = true;
243 continue_to_next_target = false;
244 view_.view()->SetScale(scale_factor);
245 view_.view()->key_press_event = [this](uint32_t keyval) {
246 play_forward = true;
247 switch (keyval) {
248 case GDK_KEY_space:
249 paused = !paused;
250 pause_on_next_target = false;
251 continue_to_next_target = false;
252 break;
253 case GDK_KEY_c:
254 pause_on_next_target = true;
255 continue_to_next_target = true;
256 paused = false;
257 break;
258 case GDK_KEY_s:
259 single_step = true;
260 continue_to_next_target = false;
261 paused = true;
262 break;
263 case GDK_KEY_k:
264 pause_on_next_target = true;
265 continue_to_next_target = false;
266 paused = false;
267 break;
268 case GDK_KEY_u:
269 if (scale_factor == 1.0) {
270 scale_factor = 0.75;
271 view_.view()->SetScale(0.75);
272 } else {
273 scale_factor = 1.0;
274 view_.view()->SetScale(1.0);
275 view_.view()->MoveTo(150, -220);
276 }
277 break;
278 case GDK_KEY_a:
279 play_forward = false;
280 single_step = true;
281 paused = true;
282 break;
283 case GDK_KEY_q:
284 exit(0);
285 case GDK_KEY_h:
286 hud_text = !hud_text;
287 break;
288 default:
289 printf("pressed: %s\n", gdk_keyval_name(keyval));
290 }
291 };
292 }
293
294 double scale_factor = 1.0;
295 bool hud_text = true;
296 bool play_forward;
297 bool paused;
298 bool single_step;
299 bool pause_on_next_target;
300 bool continue_to_next_target;
301
302 std::string distance_text;
303
304 std::pair<int, int> TickFrame(uint64_t time) {
305 timestamp_ += time;
306 return TickToFrame(timestamp_);
307 }
308
309 std::pair<int, int> TickBackFrame(uint64_t time) {
310 timestamp_ -= time;
311 return TickBackToFrame(timestamp_);
312 }
313
314 std::pair<int, int> TickToFrame(uint64_t timestamp) {
315 std::pair<int, int> skip(0, 0);
316 while (frame1.timestamp < timestamp) {
317 frame1.ReadNext(&ifs1_);
318 skip.first++;
319 }
320 while (frame2.timestamp < timestamp) {
321 frame2.ReadNext(&ifs2_);
322 skip.second++;
323 }
324 return skip;
325 }
326
327 std::pair<int, int> TickBackToFrame(uint64_t timestamp) {
328 std::pair<int, int> skip(0, 0);
329 while (frame1.timestamp >= timestamp) {
330 if (!frame1.ReadPrev(&ifs1_)) break;
331 skip.first++;
332 }
333 while (frame2.timestamp >= timestamp) {
334 if (!frame2.ReadPrev(&ifs2_)) break;
335 skip.second++;
336 }
337 frame1.ReadPrev(&ifs1_);
338 frame2.ReadPrev(&ifs2_);
339 return skip;
340 }
341 BlobStreamFrame frame1;
342 BlobStreamFrame frame2;
343 uint64_t timestamp_ = 0;
344
345 Vector<2> GetCenter(const BlobList &blob_list) {
346 std::vector<std::pair<Vector<2>, Vector<2>>> corners =
347 finder_.Find(blob_filt_.FilterBlobs(blob_list));
348
349 if (corners.size() == 1) {
350 Vector<2> center = (corners[0].first + corners[0].second) * (0.5);
351 return center;
352 }
353 return {0, 0};
354 }
355
356 void DrawSuperSpeed() {
357 PixelRef color = {0, 255, 255};
358 // S
Parker Schuh24ee58d2017-03-11 16:13:23 -0800359 overlay_.AddLine(Vector<2>(200, 100), Vector<2>(100, 100), color);
360 overlay_.AddLine(Vector<2>(100, 100), Vector<2>(100, 300), color);
361 overlay_.AddLine(Vector<2>(100, 300), Vector<2>(200, 300), color);
362 overlay_.AddLine(Vector<2>(200, 300), Vector<2>(200, 500), color);
363 overlay_.AddLine(Vector<2>(200, 500), Vector<2>(100, 500), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800364 // U
Parker Schuh24ee58d2017-03-11 16:13:23 -0800365 overlay_.AddLine(Vector<2>(250, 100), Vector<2>(250, 500), color);
366 overlay_.AddLine(Vector<2>(250, 500), Vector<2>(350, 500), color);
367 overlay_.AddLine(Vector<2>(350, 500), Vector<2>(350, 100), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800368 // P
Parker Schuh24ee58d2017-03-11 16:13:23 -0800369 overlay_.AddLine(Vector<2>(400, 100), Vector<2>(400, 500), color);
370 overlay_.AddLine(Vector<2>(400, 100), Vector<2>(500, 100), color);
371 overlay_.AddLine(Vector<2>(500, 100), Vector<2>(500, 300), color);
372 overlay_.AddLine(Vector<2>(500, 300), Vector<2>(400, 300), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800373 // E
Parker Schuh24ee58d2017-03-11 16:13:23 -0800374 overlay_.AddLine(Vector<2>(550, 100), Vector<2>(550, 500), color);
375 overlay_.AddLine(Vector<2>(550, 100), Vector<2>(650, 100), color);
376 overlay_.AddLine(Vector<2>(550, 300), Vector<2>(650, 300), color);
377 overlay_.AddLine(Vector<2>(550, 500), Vector<2>(650, 500), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800378 // R
Parker Schuh24ee58d2017-03-11 16:13:23 -0800379 overlay_.AddLine(Vector<2>(700, 100), Vector<2>(700, 500), color);
380 overlay_.AddLine(Vector<2>(700, 100), Vector<2>(800, 100), color);
381 overlay_.AddLine(Vector<2>(800, 100), Vector<2>(800, 300), color);
382 overlay_.AddLine(Vector<2>(800, 300), Vector<2>(700, 300), color);
383 overlay_.AddLine(Vector<2>(700, 350), Vector<2>(800, 500), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800384 // S
Parker Schuh24ee58d2017-03-11 16:13:23 -0800385 overlay_.AddLine(Vector<2>(200, 550), Vector<2>(100, 550), color);
386 overlay_.AddLine(Vector<2>(100, 550), Vector<2>(100, 750), color);
387 overlay_.AddLine(Vector<2>(100, 750), Vector<2>(200, 750), color);
388 overlay_.AddLine(Vector<2>(200, 750), Vector<2>(200, 950), color);
389 overlay_.AddLine(Vector<2>(200, 950), Vector<2>(100, 950), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800390 // P
Parker Schuh24ee58d2017-03-11 16:13:23 -0800391 overlay_.AddLine(Vector<2>(250, 550), Vector<2>(250, 950), color);
392 overlay_.AddLine(Vector<2>(250, 550), Vector<2>(350, 550), color);
393 overlay_.AddLine(Vector<2>(350, 550), Vector<2>(350, 750), color);
394 overlay_.AddLine(Vector<2>(350, 750), Vector<2>(250, 750), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800395 // E
Parker Schuh24ee58d2017-03-11 16:13:23 -0800396 overlay_.AddLine(Vector<2>(400, 550), Vector<2>(400, 950), color);
397 overlay_.AddLine(Vector<2>(400, 550), Vector<2>(500, 550), color);
398 overlay_.AddLine(Vector<2>(400, 750), Vector<2>(500, 750), color);
399 overlay_.AddLine(Vector<2>(400, 950), Vector<2>(500, 950), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800400 // E
Parker Schuh24ee58d2017-03-11 16:13:23 -0800401 overlay_.AddLine(Vector<2>(550, 550), Vector<2>(550, 950), color);
402 overlay_.AddLine(Vector<2>(550, 550), Vector<2>(650, 550), color);
403 overlay_.AddLine(Vector<2>(550, 750), Vector<2>(650, 750), color);
404 overlay_.AddLine(Vector<2>(550, 950), Vector<2>(650, 950), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800405 // D
Parker Schuh24ee58d2017-03-11 16:13:23 -0800406 overlay_.AddLine(Vector<2>(700, 550), Vector<2>(700, 950), color);
407 overlay_.AddLine(Vector<2>(700, 550), Vector<2>(800, 575), color);
408 overlay_.AddLine(Vector<2>(800, 575), Vector<2>(800, 925), color);
409 overlay_.AddLine(Vector<2>(800, 925), Vector<2>(700, 950), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800410 }
411
412 void UpdateNewTime(int new_delta) {
413 if (new_delta != ms_event_delta_) {
414 ms_event_delta_ = new_delta;
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700415 SetTime(::std::chrono::milliseconds(ms_event_delta_) +
416 aos::monotonic_clock::now());
Parker Schuhd7db83d2017-02-08 20:49:15 -0800417 }
418 }
419
420 void Done() override {
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700421 SetTime(::std::chrono::milliseconds(ms_event_delta_) +
422 aos::monotonic_clock::now());
Parker Schuhd7db83d2017-02-08 20:49:15 -0800423 if (paused && !single_step) return;
424 single_step = false;
425 frame_count_++;
426
427 while (true) {
428 overlay_.Reset();
429 view_.SetFormatAndClear(fmt_);
430 std::pair<int, int> skipped(1, 1);
431 // how far we will step to look for the next target
432 int nano_step = 300 * 1e6;
433 if (play_forward && seeking_target_) {
434 skipped = TickFrame(nano_step);
435 } else if (seeking_target_) {
436 skipped = TickBackFrame(nano_step);
437 } else if (play_forward) {
438 frame1.ReadNext(&ifs1_);
439 frame2.ReadNext(&ifs2_);
440 } else {
441 frame1.ReadPrev(&ifs1_);
442 frame2.ReadPrev(&ifs2_);
443 }
444 // printf("skipped (%d, %d)\n", skipped.first, skipped.second);
445
446 std::vector<std::pair<Vector<2>, Vector<2>>> corner1 =
447 finder_.Find(blob_filt_.FilterBlobs(frame1.blob_list));
448 std::vector<std::pair<Vector<2>, Vector<2>>> corner2 =
449 finder_.Find(blob_filt_.FilterBlobs(frame2.blob_list));
450
451 Vector<2> cent1;
452 Vector<2> cent2;
453 SelectTargets(corner1, corner2, &cent1, &cent2);
454
455 /*
456 int target_count_;
457 if (cent1 == Vector<2>(0, 0) && cent2 == Vector<2>(0, 0)) {
458 missed_count_ += std::min(skipped.first, skipped.second);
459 if (missed_count_ > 15) {
460 seeking_target_ = true;
461 DrawSuperSpeed();
462 SetTime(aos::vision::MsTime(1));
463 if (line_break_) {
464 printf("_-_-_-%d_-_-_-_\n", target_count_);
465 target_count_++;
466 line_break_ = false;
467 }
468 if (continue_to_next_target) {
469 continue_to_next_target = false;
470 }
471 continue;
472 }
473 } else {
474 missed_count_ = 0;
475 }
476 */
477
478 if (seeking_target_) {
479 if (play_forward) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700480 // Go back to the last time we didn't see a target and play from
481 // there.
Parker Schuhd7db83d2017-02-08 20:49:15 -0800482 TickBackFrame(nano_step);
483 seeking_target_ = false;
484 } else if (seeking_target_) {
485 TickFrame(nano_step);
486 seeking_target_ = false;
487 }
488 continue;
489 }
490
491 // comment out to turn off full blob drawing
492 view_.DrawBlobList(frame1.blob_list, {0, 0, 255});
493 view_.DrawSecondBlobList(frame2.blob_list, {0, 255, 0}, {0, 255, 255});
494
495 DrawCross(overlay_, Vector<2>(fmt_.w / 2.0, fmt_.h / 2.0), {255, 0, 0});
496
497 double timeFromEpoch =
498 1e-9 * ((double)frame1.timestamp + (double)frame2.timestamp) / 2;
499 printf("timestamp: %g skew: %g\n", timeFromEpoch,
500 1e-9 * ((double)frame1.timestamp - (double)frame2.timestamp));
501 /*
502 if (cent1 == Vector<2>(0, 0) && cent2 == Vector<2>(0, 0)) {
503 } else {
504 DrawCross(overlay_, cent1, {255, 255, 255});
505 DrawCross(overlay_, cent2, {255, 255, 255});
506 double x = (cent1.x() + cent2.x()) / 2.0;
507 DrawCross(overlay_, Vector<2>(x, fmt_.h / 2.0), {255, 255, 255});
508 SetTime(aos::vision::MsTime(100));
509 if (pause_on_next_target && !continue_to_next_target) {
510 paused = true;
511 pause_on_next_target = false;
512 }
513 line_break_ = true;
514 missed_count_ = 0;
515 }
516 fflush(stdout);
517 */
518 view_.view()->Redraw();
519 break;
520 }
521 }
522
523 void DrawCross(PixelLinesOverlay &overlay, Vector<2> center, PixelRef color) {
Parker Schuh24ee58d2017-03-11 16:13:23 -0800524 overlay.AddLine(Vector<2>(center.x() - 25, center.y()),
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700525 Vector<2>(center.x() + 25, center.y()), color);
Parker Schuh24ee58d2017-03-11 16:13:23 -0800526 overlay.AddLine(Vector<2>(center.x(), center.y() - 25),
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700527 Vector<2>(center.x(), center.y() + 25), color);
Parker Schuhd7db83d2017-02-08 20:49:15 -0800528 }
529
530 void AddTo(aos::events::EpollLoop *loop) {
531 Done();
532 loop->AddWait(this);
533 }
534
535 std::unique_ptr<PixelRef[]> outbuf;
536 ImagePtr ptr;
537
538 BlobStreamViewer view_;
539
540 private:
541 int ms_event_delta_ = 200;
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700542
Parker Schuhd7db83d2017-02-08 20:49:15 -0800543 public:
544 // basic image size
545 ImageFormat fmt_;
546
547 // where we darw for debugging
548 PixelLinesOverlay overlay_;
549
550 // Where we draw text on the screen.
551 LambdaOverlay text_overlay_;
552 // container for viewer
553 std::vector<OverlayBase *> overlays_;
554
555 InputFile ifs1_;
556 InputFile ifs2_;
557
558 // our blob processing object
559 HistogramBlobFilter blob_filt_;
560
561 // corner finder to align aiming
562 CornerFinder finder_;
563
564 // indicates we have lost a target
565 bool line_break_ = false;
566
567 // indicates we are looking for the next target
568 bool seeking_target_ = false;
569
570 int frame_count_ = 0;
571
572 // count how many frames we miss in a row.
573 int missed_count_ = 16;
574};
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800575} // namespace y2016::vision
Parker Schuhd7db83d2017-02-08 20:49:15 -0800576
577int main(int argc, char *argv[]) {
578 using namespace y2016::vision;
579 aos::events::EpollLoop loop;
580 gtk_init(&argc, &argv);
581
582 if (argc != 3) {
583 printf("Wrong number of arguments. Got (%d) expected 3.\n", argc);
584 printf(
585 " arguments are debug level as {0, 1, 2} and then filename without the "
586 "{_0.dat,_1.dat} suffixes\n");
587 }
588
589 int dbg = std::stoi(argv[1]);
590
591 std::string file(argv[2]);
592 aos::vision::ImageFormat fmt = {640 * 2, 480 * 2};
593
594 printf("file (%s) dbg_lvl (%d)\n", file.c_str(), dbg);
595
596 std::string fname_path = file;
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700597 NetworkForwardingImageStream strm1(fmt, dbg, fname_path + "_0.dat",
598 fname_path + "_1.dat");
Parker Schuhd7db83d2017-02-08 20:49:15 -0800599 fprintf(stderr, "staring main\n");
600 strm1.AddTo(&loop);
601
602 fprintf(stderr, "staring main\n");
603 loop.RunWithGtkMain();
604}