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