blob: d3c527ca5438d56065f0956e5000329ad41b2016 [file] [log] [blame]
Parker Schuhd7db83d2017-02-08 20:49:15 -08001#include <stdio.h>
2#include <stdlib.h>
3#include <netdb.h>
4#include <unistd.h>
5
6#include <vector>
7#include <memory>
8
9#include <gtk/gtk.h>
10#include "aos/vision/image/image_types.h"
11#include "aos/vision/image/jpeg_routines.h"
12#include "aos/vision/events/socket_types.h"
13#include "aos/vision/events/tcp_client.h"
14#include "aos/vision/events/epoll_events.h"
Parker Schuhd7db83d2017-02-08 20:49:15 -080015#include "aos/vision/blob/range_image.h"
16#include "aos/vision/blob/codec.h"
17#include "aos/vision/blob/stream_view.h"
18
19#include "y2016/vision/vision_data.pb.h"
20#include "y2016/vision/stereo_geometry.h"
21#include "y2016/vision/blob_filters.h"
22
23using namespace aos::vision;
24
25class StereoViewer {
26 public:
27 StereoViewer(int width, int height)
28 : blob_filt_(ImageFormat(width, height), 40, 100, 250000) {
29 overlays_.push_back(&overlay_);
30 view_.view()->SetOverlays(&overlays_);
31
32 // Uncomment to enable blob_filt_ overlay.
33 // blob_filt_.EnableOverlay(&overlay_);
34 finder_.EnableOverlay(&overlay_);
35 }
36
37 virtual ~StereoViewer() {}
38
39 void SetBlob(int camera_index, BlobList &blobl) {
40 if (camera_index == 0) {
41 left_blobs.swap(blobl);
42 new_left = true;
43 } else {
44 right_blobs.swap(blobl);
45 new_right = true;
46 }
47 }
48
49 void Process(ImageFormat fmt) {
50 if (new_left && new_right) {
51 overlay_.Reset();
52 DrawCross(overlay_, Vector<2>(fmt.w / 2.0, fmt.h / 2.0), {0, 255, 0});
53
54 view_.SetFormatAndClear(fmt);
55 printf("right (%d) left (%d)\n", (int)left_blobs.size(),
56 (int)right_blobs.size());
57 std::vector<std::pair<Vector<2>, Vector<2>>> cornersA =
58 finder_.Find(blob_filt_.FilterBlobs(left_blobs));
59 std::vector<std::pair<Vector<2>, Vector<2>>> cornersB =
60 finder_.Find(blob_filt_.FilterBlobs(right_blobs));
61 view_.DrawBlobList(left_blobs, {255, 0, 0});
62 view_.DrawSecondBlobList(right_blobs, {0, 255, 0}, {0, 0, 255});
63 view_.view()->Redraw();
64 new_left = false;
65 new_right = false;
66 }
67 }
68
69 private:
70 void DrawCross(PixelLinesOverlay &overlay, Vector<2> center, PixelRef color) {
Parker Schuh24ee58d2017-03-11 16:13:23 -080071 overlay.AddLine(Vector<2>(center.x() - 50, center.y()),
Parker Schuhd7db83d2017-02-08 20:49:15 -080072 Vector<2>(center.x() + 50, center.y()), color);
Parker Schuh24ee58d2017-03-11 16:13:23 -080073 overlay.AddLine(Vector<2>(center.x(), center.y() - 50),
Parker Schuhd7db83d2017-02-08 20:49:15 -080074 Vector<2>(center.x(), center.y() + 50), color);
75 }
76
77 // where we darw for debugging
78 PixelLinesOverlay overlay_;
79
80 // container for viewer
81 std::vector<OverlayBase *> overlays_;
82 BlobStreamViewer view_;
83
84 bool new_left = false;
85 BlobList left_blobs;
86 bool new_right = false;
87 BlobList right_blobs;
88
89 // our blob processing object
90 HistogramBlobFilter blob_filt_;
91
92 // corner finder to align aiming
93 CornerFinder finder_;
94};
95
96class BufferedLengthDelimReader {
97 public:
98 union data_len {
99 uint32_t len;
100 char buf[4];
101 };
102 BufferedLengthDelimReader() {
103 num_read_ = 0;
104 img_read_ = -1;
105 }
106 template <typename Lamb>
107 void up(int fd, Lamb lam) {
108 ssize_t count;
109 if (img_read_ < 0) {
110 count = read(fd, &len_.buf[num_read_], sizeof(len_.buf) - num_read_);
111 if (count < 0) return;
112 num_read_ += count;
113 if (num_read_ < 4) return;
114 num_read_ = 0;
115 img_read_ = 0;
116 data_.clear();
117 if (len_.len > 200000) {
118 printf("bad size: %d\n", len_.len);
119 exit(-1);
120 }
121 data_.resize(len_.len);
122 } else {
123 count = read(fd, &data_[img_read_], len_.len - img_read_);
124 if (count < 0) return;
125 img_read_ += count;
126 if (img_read_ < (int)len_.len) return;
127 lam(DataRef{&data_[0], len_.len});
128 img_read_ = -1;
129 }
130 }
131 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}