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