Showing
2 changed files
with
873 additions
and
0 deletions
Proj/yolo+matching+socket/main.cc
0 → 100644
1 | +/* | ||
2 | +-- (c) Copyright 2018 Xilinx, Inc. All rights reserved. | ||
3 | +-- | ||
4 | +-- This file contains confidential and proprietary information | ||
5 | +-- of Xilinx, Inc. and is protected under U.S. and | ||
6 | +-- international copyright and other intellectual property | ||
7 | +-- laws. | ||
8 | +-- | ||
9 | +-- DISCLAIMER | ||
10 | +-- This disclaimer is not a license and does not grant any | ||
11 | +-- rights to the materials distributed herewith. Except as | ||
12 | +-- otherwise provided in a valid license issued to you by | ||
13 | +-- Xilinx, and to the maximum extent permitted by applicable | ||
14 | +-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND | ||
15 | +-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES | ||
16 | +-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING | ||
17 | +-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- | ||
18 | +-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and | ||
19 | +-- (2) Xilinx shall not be liable (whether in contract or tort, | ||
20 | +-- including negligence, or under any other theory of | ||
21 | +-- liability) for any loss or damage of any kind or nature | ||
22 | +-- related to, arising under or in connection with these | ||
23 | +-- materials, including for any direct, or any indirect, | ||
24 | +-- special, incidental, or consequential loss or damage | ||
25 | +-- (including loss of data, profits, goodwill, or any type of | ||
26 | +-- loss or damage suffered as a result of any action brought | ||
27 | +-- by a third party) even if such damage or loss was | ||
28 | +-- reasonably foreseeable or Xilinx had been advised of the | ||
29 | +-- possibility of the same. | ||
30 | +-- | ||
31 | +-- CRITICAL APPLICATIONS | ||
32 | +-- Xilinx products are not designed or intended to be fail- | ||
33 | +-- safe, or for use in any application requiring fail-safe | ||
34 | +-- performance, such as life-support or safety devices or | ||
35 | +-- systems, Class III medical devices, nuclear facilities, | ||
36 | +-- applications related to the deployment of airbags, or any | ||
37 | +-- other applications that could lead to death, personal | ||
38 | +-- injury, or severe property or environmental damage | ||
39 | +-- (individually and collectively, "Critical | ||
40 | +-- Applications"). Customer assumes the sole risk and | ||
41 | +-- liability of any use of Xilinx products in Critical | ||
42 | +-- Applications, subject only to applicable laws and | ||
43 | +-- regulations governing limitations on product liability. | ||
44 | +-- | ||
45 | +-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS | ||
46 | +-- PART OF THIS FILE AT ALL TIMES. | ||
47 | +*/ | ||
48 | + | ||
49 | +#include <algorithm> | ||
50 | +#include <vector> | ||
51 | +#include <atomic> | ||
52 | +#include <queue> | ||
53 | +#include <string> | ||
54 | +#include <iostream> | ||
55 | +#include <fstream> | ||
56 | +#include <iomanip> | ||
57 | +#include <chrono> | ||
58 | +#include <mutex> | ||
59 | +#include <zconf.h> | ||
60 | +#include <thread> | ||
61 | +#include <sys/stat.h> | ||
62 | +#include <dirent.h> | ||
63 | + | ||
64 | +#include <dnndk/dnndk.h> | ||
65 | + | ||
66 | +#include "utils.h" | ||
67 | + | ||
68 | +#include <stdio.h> | ||
69 | +#include <sys/types.h> | ||
70 | +#include <sys/socket.h> | ||
71 | +#include <netinet/in.h> | ||
72 | +#include <arpa/inet.h> | ||
73 | +#include <stdlib.h> | ||
74 | +#include <unistd.h> | ||
75 | +#include <signal.h> | ||
76 | +#include <stdlib.h> | ||
77 | + | ||
78 | +#define Port_host 12300 | ||
79 | +#define Port_dcam 12400 | ||
80 | +#define host_addr "192.168.2.1" | ||
81 | +#define BUF_SIZE 1024 | ||
82 | + | ||
83 | + | ||
84 | +using namespace std; | ||
85 | +using namespace cv; | ||
86 | +using namespace std::chrono; | ||
87 | + | ||
88 | + | ||
89 | +#define INPUT_NODE "layer0_conv" | ||
90 | + | ||
91 | +chrono::system_clock::time_point start_time; | ||
92 | + | ||
93 | +int Mutexnum = 0, Mutexdget = 0, Yolonum = 0; | ||
94 | +int index_yolo = 0, index_co = 1; // file index | ||
95 | +VideoCapture cam(cv::CAP_V4L); | ||
96 | +int Sockfd_host, Sockfd_dcam, newSock_host, newSock_dcam; // socket | ||
97 | + | ||
98 | + | ||
99 | +typedef pair<int, Mat> imagePair; | ||
100 | +class paircomp { | ||
101 | +public: | ||
102 | + bool operator()(const imagePair& n1, const imagePair& n2) const { | ||
103 | + if (n1.first == n2.first) { | ||
104 | + return (n1.first > n2.first); | ||
105 | + } | ||
106 | + | ||
107 | + return n1.first > n2.first; | ||
108 | + } | ||
109 | +}; | ||
110 | + | ||
111 | +// 3d yolo result struct | ||
112 | +typedef struct { | ||
113 | + char number[10]; | ||
114 | + float x; | ||
115 | + float y; | ||
116 | + float w; | ||
117 | + float l; | ||
118 | + float yaw; | ||
119 | + float conf; | ||
120 | + float cls_conf; | ||
121 | + float cls_pred; | ||
122 | +} dinfo; | ||
123 | + | ||
124 | +// socket function | ||
125 | +void send_result() { | ||
126 | + static int ind = 0; | ||
127 | + int now_size = 0, read_size; | ||
128 | + char file_name[256], msg_buf[BUF_SIZE], sync = '\0'; | ||
129 | + FILE* image; | ||
130 | + unsigned int fsize; | ||
131 | + | ||
132 | + sprintf(file_name, "img_%03d_result.jpg", ind); // save file name | ||
133 | + | ||
134 | + image = fopen(file_name, "w"); | ||
135 | + | ||
136 | + // recv file size | ||
137 | + if ((fsize = read(Sockfd_host, (char*)&msg_buf, sizeof(msg_buf) - 1)) < 0) { | ||
138 | + perror("read"); | ||
139 | + exit(1); | ||
140 | + } | ||
141 | + msg_buf[fsize] = '\0'; | ||
142 | + fsize = atoi(msg_buf); | ||
143 | + printf("%d\n", fsize); | ||
144 | + | ||
145 | + // recv image file | ||
146 | + while (1) { | ||
147 | + memset(msg_buf, 0, BUF_SIZE); | ||
148 | + read_size = read(Sockfd_host, (char*)&msg_buf, BUF_SIZE); // get image from socket | ||
149 | + fwrite(msg_buf, 1, read_size, image); // write image | ||
150 | + now_size += read_size; | ||
151 | + if (now_size == fsize) | ||
152 | + break; | ||
153 | + else if (now_size > fsize) { | ||
154 | + printf("file error\n"); | ||
155 | + exit(1); | ||
156 | + } | ||
157 | + write(Sockfd_host, (char*)&sync, sizeof(sync)); // for sync | ||
158 | + } | ||
159 | + | ||
160 | + printf("Receive done : %s\n", file_name); | ||
161 | + | ||
162 | + if (write(Sockfd_host, (char*)&file_name, sizeof(file_name)) < 0) { // 종료 전송 | ||
163 | + perror("write"); | ||
164 | + exit(1); | ||
165 | + } | ||
166 | + | ||
167 | + fclose(image); | ||
168 | + ind++; | ||
169 | + if (ind == 999) ind = 0; // max 1000 file | ||
170 | +} | ||
171 | + | ||
172 | +// input frames queue | ||
173 | +queue<pair<int, Mat>> queueInput; | ||
174 | + | ||
175 | +/** | ||
176 | + * @brief Feed input frame into DPU for process | ||
177 | + * | ||
178 | + * @param task - pointer to DPU Task for YOLO-v3 network | ||
179 | + * @param frame - pointer to input frame | ||
180 | + * @param mean - mean value for YOLO-v3 network | ||
181 | + * | ||
182 | + * @return none | ||
183 | + */ | ||
184 | +void setInputImageForYOLO(DPUTask* task, const Mat& frame, float* mean) { | ||
185 | + Mat img_copy; | ||
186 | + int height = dpuGetInputTensorHeight(task, INPUT_NODE); | ||
187 | + int width = dpuGetInputTensorWidth(task, INPUT_NODE); | ||
188 | + int size = dpuGetInputTensorSize(task, INPUT_NODE); | ||
189 | + int8_t* data = dpuGetInputTensorAddress(task, INPUT_NODE); | ||
190 | + | ||
191 | + image img_new = load_image_cv(frame); | ||
192 | + image img_yolo = letterbox_image(img_new, width, height); | ||
193 | + | ||
194 | + vector<float> bb(size); | ||
195 | + for (int b = 0; b < height; ++b) { | ||
196 | + for (int c = 0; c < width; ++c) { | ||
197 | + for (int a = 0; a < 3; ++a) { | ||
198 | + bb[b * width * 3 + c * 3 + a] = img_yolo.data[a * height * width + b * width + c]; | ||
199 | + } | ||
200 | + } | ||
201 | + } | ||
202 | + | ||
203 | + float scale = dpuGetInputTensorScale(task, INPUT_NODE); | ||
204 | + | ||
205 | + for (int i = 0; i < size; ++i) { | ||
206 | + data[i] = int(bb.data()[i] * scale); | ||
207 | + if (data[i] < 0) data[i] = 127; | ||
208 | + } | ||
209 | + | ||
210 | + free_image(img_new); | ||
211 | + free_image(img_yolo); | ||
212 | +} | ||
213 | + | ||
214 | +void co_detect(DPUTask* task, Mat& frame1, int sWidth, int sHeight, VideoCapture& cam) { // in postProcess function | ||
215 | + | ||
216 | + /*output nodes of YOLO-v3 */ | ||
217 | + const vector<string> outputs_node = { "layer81_conv", "layer93_conv", "layer105_conv" }; | ||
218 | + | ||
219 | + vector<vector<float>> boxes; | ||
220 | + for (size_t i = 0; i < outputs_node.size(); i++) { | ||
221 | + string output_node = outputs_node[i]; | ||
222 | + int channel = dpuGetOutputTensorChannel(task, output_node.c_str()); | ||
223 | + int width = dpuGetOutputTensorWidth(task, output_node.c_str()); | ||
224 | + int height = dpuGetOutputTensorHeight(task, output_node.c_str()); | ||
225 | + | ||
226 | + int sizeOut = dpuGetOutputTensorSize(task, output_node.c_str()); | ||
227 | + int8_t* dpuOut = dpuGetOutputTensorAddress(task, output_node.c_str()); | ||
228 | + float scale = dpuGetOutputTensorScale(task, output_node.c_str()); | ||
229 | + vector<float> result(sizeOut); | ||
230 | + boxes.reserve(sizeOut); | ||
231 | + | ||
232 | + /* Store every output node results */ | ||
233 | + get_output(dpuOut, sizeOut, scale, channel, height, width, result); | ||
234 | + | ||
235 | + /* Store the object detection frames as coordinate information */ | ||
236 | + detect(boxes, result, channel, height, width, i, sHeight, sWidth); | ||
237 | + } | ||
238 | + | ||
239 | + /* Restore the correct coordinate frame of the original image */ | ||
240 | + correct_region_boxes(boxes, boxes.size(), frame1.cols, frame1.rows, sWidth, sHeight); | ||
241 | + | ||
242 | + /* Apply the computation for NMS */ | ||
243 | + cout << "boxes size: " << boxes.size() << endl; | ||
244 | + vector<vector<float>> res = applyNMS(boxes, classificationCnt, NMS_THRESHOLD); | ||
245 | + | ||
246 | + float h = frame1.rows; | ||
247 | + float w = frame1.cols; | ||
248 | + Mat frame2; | ||
249 | + for (int i = 0; i < 3; i++) | ||
250 | + cam.grab(); | ||
251 | + cam.read(frame2); | ||
252 | + | ||
253 | + // for socket variable | ||
254 | + char matchinfo[1024] = "", match_inframe_info[1024], match_n[10]; | ||
255 | + int hostAddrlen, countnum; | ||
256 | + struct sockaddr_in hostAddr; | ||
257 | + hostAddrlen = sizeof(hostAddr); | ||
258 | + char tmpinfo[1024], count[5]; | ||
259 | + char* receive_info = new char[1024]; | ||
260 | + dinfo depthinfo; | ||
261 | + | ||
262 | + // read 3dyolo result from udp socket | ||
263 | + while (Mutexdget == 1) | ||
264 | + usleep(10); | ||
265 | + Mutexdget = 1; // lock | ||
266 | + // get result count in image | ||
267 | + if (recvfrom(Sockfd_dcam, &count, sizeof(count), 0, (struct sockaddr*)&hostAddr, (socklen_t*)&hostAddrlen) < 0) { | ||
268 | + perror("recvfrom"); | ||
269 | + exit(1); | ||
270 | + } // receive depth camera info | ||
271 | + countnum = atoi(count); | ||
272 | + for (int i = 0; i < countnum; i++) { | ||
273 | + if (recvfrom(Sockfd_dcam, &depthinfo, sizeof(depthinfo), 0, (struct sockaddr*)&hostAddr, (socklen_t*)&hostAddrlen) < 0) { | ||
274 | + perror("recvfrom"); | ||
275 | + exit(1); | ||
276 | + } // receive depth camera info | ||
277 | + sprintf(receive_info, "%s %f %f %f %f %f %f %f %f \n", depthinfo.number, depthinfo.x, depthinfo.y, depthinfo.w, depthinfo.l, depthinfo.yaw, depthinfo.conf, depthinfo.cls_conf, depthinfo.cls_pred); | ||
278 | + strcat(tmpinfo, receive_info); | ||
279 | + } | ||
280 | + Mutexdget = 0; // unlock | ||
281 | + | ||
282 | + for (size_t i = 0; i < res.size(); ++i) { | ||
283 | + float xmin = (res[i][0] - res[i][2] / 2.0) * w + 1.0; | ||
284 | + float ymin = (res[i][1] - res[i][3] / 2.0) * h + 1.0; | ||
285 | + float xmax = (res[i][0] + res[i][2] / 2.0) * w + 1.0; | ||
286 | + float ymax = (res[i][1] + res[i][3] / 2.0) * h + 1.0; | ||
287 | + | ||
288 | + //cout<<xmin<<" "<<ymin<<" "<<xmax<<" "<<ymax<<endl; | ||
289 | + | ||
290 | + Mat compare_part = frame1(Range((2 * ymin + 1 * ymax) / 3, (1 * ymin + 2 * ymax) / 3), Range((2 * xmin + 1 * xmax) / 3, (1 * xmin + 2 * xmax) / 3)); | ||
291 | + | ||
292 | + unsigned nextx, nexty; | ||
293 | + double min = 100000000, error; | ||
294 | + for (int x = (2 * xmin + 1 * xmax) / 3; x < (1 * xmin + 2 * xmax) / 3; x += 2) { | ||
295 | + if (((xmax - xmin) > h / 2) || ((ymax - ymin) > w / 2)) | ||
296 | + break; // too large object reject | ||
297 | + for (int y = (2 * ymin + 1 * ymax) / 3; y < (1 * ymin + 2 * ymax) / 3; y += 2) { | ||
298 | + error = 0; | ||
299 | + for (int k = -(int)(xmax - xmin) / 6; k < (int)(xmax - xmin) / 6; k++) { | ||
300 | + for (int u = -(int)(ymax - ymin) / 6; u < (int)(ymax - ymin) / 6; u++) { | ||
301 | + uchar b1 = compare_part.ptr<uchar>(u + (int)(ymax - ymin) / 6)[(k + (int)(xmax - xmin) / 6) * 3 + 0]; | ||
302 | + uchar g1 = compare_part.ptr<uchar>(u + (int)(ymax - ymin) / 6)[(k + (int)(xmax - xmin) / 6) * 3 + 1]; | ||
303 | + uchar r1 = compare_part.ptr<uchar>(u + (int)(ymax - ymin) / 6)[(k + (int)(xmax - xmin) / 6) * 3 + 2]; | ||
304 | + int yu = y + u; | ||
305 | + int xk = x + k; | ||
306 | + if (y + u < 0 || x + k < 0 || y + u > w || x + k > h) { // for padding | ||
307 | + if (y + u < 0) yu = 0; | ||
308 | + if (x + k < 0) xk = 0; | ||
309 | + if (y + u > w) yu = w; | ||
310 | + if (x + k > h) xk = h; | ||
311 | + } | ||
312 | + uchar b2 = frame2.ptr<uchar>(yu)[(xk) * 3 + 0]; | ||
313 | + uchar g2 = frame2.ptr<uchar>(yu)[(xk) * 3 + 1]; | ||
314 | + uchar r2 = frame2.ptr<uchar>(yu)[(xk) * 3 + 2]; | ||
315 | + error += (pow(b1 - b2, 2) + pow(g1 - g2, 2) + pow(r1 - r2, 2)); | ||
316 | + } | ||
317 | + } | ||
318 | + if (min > error) { | ||
319 | + min = error; | ||
320 | + nextx = x; | ||
321 | + nexty = y; | ||
322 | + } | ||
323 | + } | ||
324 | + } | ||
325 | + // create result string | ||
326 | + sprintf(match_n, "MC%d-%d", index_co, i); | ||
327 | + sprintf(match_inframe_info, "%s %f %f %f %f\n", match_n, nextx - (xmax - xmin) / 2, nexty - (ymax - ymin) / 2, nextx + (xmax - xmin) / 2, nexty + (ymax - ymin) / 2); | ||
328 | + strcat(matchinfo, match_inframe_info); | ||
329 | + | ||
330 | + rectangle(frame2, Rect(Point((2 * xmin + 1 * xmax) / 3, (2 * ymin + 1 * ymax) / 3), Point((1 * xmin + 2 * xmax) / 3, (1 * ymin + 2 * ymax) / 3)), (0, 255, 0), 1); | ||
331 | + rectangle(frame2, Rect(Point(nextx - (xmax - xmin) / 2, nexty - (ymax - ymin) / 2), Point(nextx + (xmax - xmin) / 2, nexty + (ymax - ymin) / 2)), (0, 0, 255), 1); | ||
332 | + } | ||
333 | + // write tcp socket. to host | ||
334 | + strcat(matchinfo, tmpinfo); | ||
335 | + printf("%s\n", matchinfo); | ||
336 | + if (write(newSock_host, (char*)&matchinfo, sizeof(matchinfo)) < 0) { | ||
337 | + perror("write"); | ||
338 | + exit(1); | ||
339 | + } | ||
340 | + | ||
341 | + string file_ind = "result_" + to_string(index_co) + ".jpg"; | ||
342 | + imwrite(file_ind, frame2); | ||
343 | + cout << "co_detect1 : " << file_ind << endl; | ||
344 | + index_co += 2; | ||
345 | + imshow("Xilinx DPU", frame2); | ||
346 | + //if(waitKey(30) == 27) break; | ||
347 | + Yolonum++; // mutex update*/ | ||
348 | +} | ||
349 | + | ||
350 | +void co_detect2(DPUTask* task, Mat& frame1, int sWidth, int sHeight, VideoCapture& cam) { // in postProcess function | ||
351 | + | ||
352 | + /*output nodes of YOLO-v3 */ | ||
353 | + const vector<string> outputs_node = { "layer81_conv", "layer93_conv", "layer105_conv" }; | ||
354 | + | ||
355 | + vector<vector<float>> boxes; | ||
356 | + for (size_t i = 0; i < outputs_node.size(); i++) { | ||
357 | + string output_node = outputs_node[i]; | ||
358 | + int channel = dpuGetOutputTensorChannel(task, output_node.c_str()); | ||
359 | + int width = dpuGetOutputTensorWidth(task, output_node.c_str()); | ||
360 | + int height = dpuGetOutputTensorHeight(task, output_node.c_str()); | ||
361 | + | ||
362 | + int sizeOut = dpuGetOutputTensorSize(task, output_node.c_str()); | ||
363 | + int8_t* dpuOut = dpuGetOutputTensorAddress(task, output_node.c_str()); | ||
364 | + float scale = dpuGetOutputTensorScale(task, output_node.c_str()); | ||
365 | + vector<float> result(sizeOut); | ||
366 | + boxes.reserve(sizeOut); | ||
367 | + | ||
368 | + /* Store every output node results */ | ||
369 | + get_output(dpuOut, sizeOut, scale, channel, height, width, result); | ||
370 | + | ||
371 | + /* Store the object detection frames as coordinate information */ | ||
372 | + detect(boxes, result, channel, height, width, i, sHeight, sWidth); | ||
373 | + } | ||
374 | + | ||
375 | + /* Restore the correct coordinate frame of the original image */ | ||
376 | + correct_region_boxes(boxes, boxes.size(), frame1.cols, frame1.rows, sWidth, sHeight); | ||
377 | + | ||
378 | + /* Apply the computation for NMS */ | ||
379 | + cout << "boxes size: " << boxes.size() << endl; | ||
380 | + vector<vector<float>> res = applyNMS(boxes, classificationCnt, NMS_THRESHOLD); | ||
381 | + | ||
382 | + float h = frame1.rows; | ||
383 | + float w = frame1.cols; | ||
384 | + Mat frame2; | ||
385 | + for (int i = 0; i < 3; i++) | ||
386 | + cam.grab(); | ||
387 | + cam.read(frame2); | ||
388 | + char matchinfo[1024] = "", match_inframe_info[1024], match_n[10]; | ||
389 | + | ||
390 | + int hostAddrlen, countnum; | ||
391 | + struct sockaddr_in hostAddr; | ||
392 | + hostAddrlen = sizeof(hostAddr); | ||
393 | + char tmpinfo[1024], count[5]; | ||
394 | + char* receive_info = new char[1024]; | ||
395 | + dinfo depthinfo; | ||
396 | + | ||
397 | + while (Mutexdget == 1) | ||
398 | + usleep(10); | ||
399 | + Mutexdget = 1; // lock | ||
400 | + if (recvfrom(Sockfd_dcam, &count, sizeof(count), 0, (struct sockaddr*)&hostAddr, (socklen_t*)&hostAddrlen) < 0) { | ||
401 | + perror("recvfrom"); | ||
402 | + exit(1); | ||
403 | + } // receive depth camera info | ||
404 | + countnum = atoi(count); | ||
405 | + for (int i = 0; i < countnum; i++) { | ||
406 | + if (recvfrom(Sockfd_dcam, &depthinfo, sizeof(depthinfo), 0, (struct sockaddr*)&hostAddr, (socklen_t*)&hostAddrlen) < 0) { | ||
407 | + perror("recvfrom"); | ||
408 | + exit(1); | ||
409 | + } // receive depth camera info | ||
410 | + sprintf(receive_info, "%s %f %f %f %f %f %f %f %f \n", depthinfo.number, depthinfo.x, depthinfo.y, depthinfo.w, depthinfo.l, depthinfo.yaw, depthinfo.conf, depthinfo.cls_conf, depthinfo.cls_pred); | ||
411 | + strcat(tmpinfo, receive_info); | ||
412 | + } | ||
413 | + Mutexdget = 0; // unlock | ||
414 | + | ||
415 | + for (size_t i = 0; i < res.size(); ++i) { | ||
416 | + float xmin = (res[i][0] - res[i][2] / 2.0) * w + 1.0; | ||
417 | + float ymin = (res[i][1] - res[i][3] / 2.0) * h + 1.0; | ||
418 | + float xmax = (res[i][0] + res[i][2] / 2.0) * w + 1.0; | ||
419 | + float ymax = (res[i][1] + res[i][3] / 2.0) * h + 1.0; | ||
420 | + | ||
421 | + //cout<<xmin<<" "<<ymin<<" "<<xmax<<" "<<ymax<<endl; | ||
422 | + | ||
423 | + Mat compare_part = frame1(Range((2 * ymin + 1 * ymax) / 3, (1 * ymin + 2 * ymax) / 3), Range((2 * xmin + 1 * xmax) / 3, (1 * xmin + 2 * xmax) / 3)); | ||
424 | + | ||
425 | + unsigned nextx, nexty; | ||
426 | + double min = 100000000, error; | ||
427 | + for (int x = (2 * xmin + 1 * xmax) / 3; x < (1 * xmin + 2 * xmax) / 3; x += 2) { // for padding | ||
428 | + if (((xmax - xmin) > h / 2) || ((ymax - ymin) > w / 2)) | ||
429 | + break; // too large object reject | ||
430 | + for (int y = (2 * ymin + 1 * ymax) / 3; y < (1 * ymin + 2 * ymax) / 3; y += 2) { | ||
431 | + error = 0; | ||
432 | + for (int k = -(int)(xmax - xmin) / 6; k < (int)(xmax - xmin) / 6; k++) { | ||
433 | + for (int u = -(int)(ymax - ymin) / 6; u < (int)(ymax - ymin) / 6; u++) { | ||
434 | + uchar b1 = compare_part.ptr<uchar>(u + (int)(ymax - ymin) / 6)[(k + (int)(xmax - xmin) / 6) * 3 + 0]; | ||
435 | + uchar g1 = compare_part.ptr<uchar>(u + (int)(ymax - ymin) / 6)[(k + (int)(xmax - xmin) / 6) * 3 + 1]; | ||
436 | + uchar r1 = compare_part.ptr<uchar>(u + (int)(ymax - ymin) / 6)[(k + (int)(xmax - xmin) / 6) * 3 + 2]; | ||
437 | + int yu = y + u; | ||
438 | + int xk = x + k; | ||
439 | + if (y + u < 0 || x + k < 0 || y + u > w || x + k > h) { | ||
440 | + if (y + u < 0) yu = 0; | ||
441 | + if (x + k < 0) xk = 0; | ||
442 | + if (y + u > w) yu = w; | ||
443 | + if (x + k > h) xk = h; | ||
444 | + } | ||
445 | + uchar b2 = frame2.ptr<uchar>(yu)[(xk) * 3 + 0]; | ||
446 | + uchar g2 = frame2.ptr<uchar>(yu)[(xk) * 3 + 1]; | ||
447 | + uchar r2 = frame2.ptr<uchar>(yu)[(xk) * 3 + 2]; | ||
448 | + error += (pow(b1 - b2, 2) + pow(g1 - g2, 2) + pow(r1 - r2, 2)); | ||
449 | + } | ||
450 | + } | ||
451 | + if (min > error) { | ||
452 | + min = error; | ||
453 | + nextx = x; | ||
454 | + nexty = y; | ||
455 | + } | ||
456 | + } | ||
457 | + } | ||
458 | + sprintf(match_n, "MC%d-%d", index_co, i); | ||
459 | + sprintf(match_inframe_info, "%s %f %f %f %f\n", match_n, nextx - (xmax - xmin) / 2, nexty - (ymax - ymin) / 2, nextx + (xmax - xmin) / 2, nexty + (ymax - ymin) / 2); | ||
460 | + strcat(matchinfo, match_inframe_info); | ||
461 | + | ||
462 | + rectangle(frame2, Rect(Point((2 * xmin + 1 * xmax) / 3, (2 * ymin + 1 * ymax) / 3), Point((1 * xmin + 2 * xmax) / 3, (1 * ymin + 2 * ymax) / 3)), (0, 0, 255), 1); | ||
463 | + rectangle(frame2, Rect(Point(nextx - (xmax - xmin) / 2, nexty - (ymax - ymin) / 2), Point(nextx + (xmax - xmin) / 2, nexty + (ymax - ymin) / 2)), (0, 0, 255), 1); | ||
464 | + } | ||
465 | + strcat(matchinfo, tmpinfo); | ||
466 | + printf("%s\n", matchinfo); | ||
467 | + if (write(newSock_host, (char*)&matchinfo, sizeof(matchinfo)) < 0) { | ||
468 | + perror("write"); | ||
469 | + exit(1); | ||
470 | + } | ||
471 | + | ||
472 | + string file_ind = "result_" + to_string(index_co) + ".jpg"; | ||
473 | + imwrite(file_ind, frame2); | ||
474 | + cout << "co_detect2 : " << file_ind << endl; | ||
475 | + index_co += 2; | ||
476 | + imshow("Xilinx DPU", frame2); | ||
477 | + //if(waitKey(30) == 27) break; | ||
478 | + delete receive_info; | ||
479 | + Yolonum++; // mutex update*/ | ||
480 | +} | ||
481 | + | ||
482 | +/** | ||
483 | + * @brief Post process after the runing of DPU for YOLO-v3 network | ||
484 | + * | ||
485 | + * @param task - pointer to DPU task for running YOLO-v3 | ||
486 | + * @param frame | ||
487 | + * @param sWidth | ||
488 | + * @param sHeight | ||
489 | + * | ||
490 | + * @return none | ||
491 | + */ | ||
492 | +void postProcess(DPUTask* task, Mat& frame, int sWidth, int sHeight) { | ||
493 | + | ||
494 | + /*output nodes of YOLO-v3 */ | ||
495 | + const vector<string> outputs_node = { "layer81_conv", "layer93_conv", "layer105_conv" }; | ||
496 | + | ||
497 | + vector<vector<float>> boxes; | ||
498 | + for (size_t i = 0; i < outputs_node.size(); i++) { | ||
499 | + string output_node = outputs_node[i]; | ||
500 | + int channel = dpuGetOutputTensorChannel(task, output_node.c_str()); | ||
501 | + int width = dpuGetOutputTensorWidth(task, output_node.c_str()); | ||
502 | + int height = dpuGetOutputTensorHeight(task, output_node.c_str()); | ||
503 | + | ||
504 | + int sizeOut = dpuGetOutputTensorSize(task, output_node.c_str()); | ||
505 | + int8_t* dpuOut = dpuGetOutputTensorAddress(task, output_node.c_str()); | ||
506 | + float scale = dpuGetOutputTensorScale(task, output_node.c_str()); | ||
507 | + vector<float> result(sizeOut); | ||
508 | + boxes.reserve(sizeOut); | ||
509 | + | ||
510 | + /* Store every output node results */ | ||
511 | + get_output(dpuOut, sizeOut, scale, channel, height, width, result); | ||
512 | + | ||
513 | + /* Store the object detection frames as coordinate information */ | ||
514 | + detect(boxes, result, channel, height, width, i, sHeight, sWidth); | ||
515 | + } | ||
516 | + | ||
517 | + /* Restore the correct coordinate frame of the original image */ | ||
518 | + correct_region_boxes(boxes, boxes.size(), frame.cols, frame.rows, sWidth, sHeight); | ||
519 | + | ||
520 | + /* Apply the computation for NMS */ | ||
521 | + cout << "boxes size: " << boxes.size() << endl; | ||
522 | + vector<vector<float>> res = applyNMS(boxes, classificationCnt, NMS_THRESHOLD); | ||
523 | + | ||
524 | + float h = frame.rows; | ||
525 | + float w = frame.cols; | ||
526 | + char yoloinfo[1024] = "YOLO-\n", yolo_inframe_info[1024], yolo_num[10]; | ||
527 | + for (size_t i = 0; i < res.size(); ++i) { | ||
528 | + | ||
529 | + float xmin = (res[i][0] - res[i][2] / 2.0) * w + 1.0; | ||
530 | + float ymin = (res[i][1] - res[i][3] / 2.0) * h + 1.0; | ||
531 | + float xmax = (res[i][0] + res[i][2] / 2.0) * w + 1.0; | ||
532 | + float ymax = (res[i][1] + res[i][3] / 2.0) * h + 1.0; | ||
533 | + | ||
534 | + //cout<<res[i][res[i][4] + 6]<<" "; | ||
535 | + //cout<<xmin<<" "<<ymin<<" "<<xmax<<" "<<ymax<<endl; | ||
536 | + | ||
537 | + // write yolo result | ||
538 | + sprintf(yolo_num, "YC%d-%d", index_yolo, i); | ||
539 | + sprintf(yolo_inframe_info, "%s %f %f %f %f\n", yolo_num, xmin, ymin, xmax, ymax); // yolo info | ||
540 | + strcat(yoloinfo, yolo_inframe_info); | ||
541 | + | ||
542 | + if (res[i][res[i][4] + 6] > CONF) { | ||
543 | + int type = res[i][4]; | ||
544 | + | ||
545 | + if (type == 0) { | ||
546 | + rectangle(frame, cvPoint(xmin, ymin), cvPoint(xmax, ymax), Scalar(0, 0, 255), 1, 1, 0); | ||
547 | + } | ||
548 | + else if (type == 1) { | ||
549 | + rectangle(frame, cvPoint(xmin, ymin), cvPoint(xmax, ymax), Scalar(255, 0, 0), 1, 1, 0); | ||
550 | + } | ||
551 | + else { | ||
552 | + rectangle(frame, cvPoint(xmin, ymin), cvPoint(xmax, ymax), Scalar(0, 255, 255), 1, 1, 0); | ||
553 | + } | ||
554 | + } | ||
555 | + } | ||
556 | + int hostAddrlen, countnum; | ||
557 | + struct sockaddr_in hostAddr; | ||
558 | + hostAddrlen = sizeof(hostAddr); | ||
559 | + char receive_info[1024], count[5]; | ||
560 | + dinfo depthinfo; | ||
561 | + | ||
562 | + while (Mutexdget == 1) | ||
563 | + usleep(10); | ||
564 | + Mutexdget = 1; // lock | ||
565 | + | ||
566 | + if (recvfrom(Sockfd_dcam, &count, sizeof(count), 0, (struct sockaddr*)&hostAddr, (socklen_t*)&hostAddrlen) < 0) { | ||
567 | + perror("recvfrom"); | ||
568 | + exit(1); | ||
569 | + } // receive depth camera info | ||
570 | + countnum = atoi(count); | ||
571 | + for (int i = 0; i < countnum; i++) { | ||
572 | + if (recvfrom(Sockfd_dcam, &depthinfo, sizeof(depthinfo), 0, (struct sockaddr*)&hostAddr, (socklen_t*)&hostAddrlen) < 0) { | ||
573 | + perror("recvfrom"); | ||
574 | + exit(1); | ||
575 | + } // receive depth camera info | ||
576 | + sprintf(receive_info, "%s %f %f %f %f %f %f %f %f \n", depthinfo.number, depthinfo.x, depthinfo.y, depthinfo.w, depthinfo.l, depthinfo.yaw, depthinfo.conf, depthinfo.cls_conf, depthinfo.cls_pred); | ||
577 | + strcat(yoloinfo, receive_info); | ||
578 | + } | ||
579 | + Mutexdget = 0; // unlock | ||
580 | + | ||
581 | + printf("%s\n", yoloinfo); | ||
582 | + if (write(newSock_host, (char*)&yoloinfo, sizeof(yoloinfo)) < 0) { | ||
583 | + perror("write"); | ||
584 | + exit(1); | ||
585 | + } | ||
586 | +} | ||
587 | + | ||
588 | +/** | ||
589 | + * @brief Thread entry for running YOLO-v3 network on DPU for acceleration | ||
590 | + * | ||
591 | + * @param task - pointer to DPU task for running YOLO-v3 | ||
592 | + * @param img | ||
593 | + * | ||
594 | + * @return none | ||
595 | + */ | ||
596 | +thread runYOLO(DPUTask* task, Mat& img, VideoCapture& cam) { | ||
597 | + /* mean values for YOLO-v3 */ | ||
598 | + float mean[3] = { 0.0f, 0.0f, 0.0f }; | ||
599 | + | ||
600 | + int height = dpuGetInputTensorHeight(task, INPUT_NODE); | ||
601 | + int width = dpuGetInputTensorWidth(task, INPUT_NODE); | ||
602 | + | ||
603 | + /* feed input frame into DPU Task with mean value */ | ||
604 | + setInputImageForYOLO(task, img, mean); | ||
605 | + | ||
606 | + /* invoke the running of DPU for YOLO-v3 */ | ||
607 | + dpuRunTask(task); | ||
608 | + thread t(co_detect, task, ref(img), width, height, ref(cam)); | ||
609 | + postProcess(task, img, width, height); | ||
610 | + Yolonum++; | ||
611 | + return t; | ||
612 | +} | ||
613 | +thread runYOLO2(DPUTask* task, Mat& img, VideoCapture& cam) { | ||
614 | + /* mean values for YOLO-v3 */ | ||
615 | + float mean[3] = { 0.0f, 0.0f, 0.0f }; | ||
616 | + | ||
617 | + int height = dpuGetInputTensorHeight(task, INPUT_NODE); | ||
618 | + int width = dpuGetInputTensorWidth(task, INPUT_NODE); | ||
619 | + | ||
620 | + /* feed input frame into DPU Task with mean value */ | ||
621 | + setInputImageForYOLO(task, img, mean); | ||
622 | + | ||
623 | + /* invoke the running of DPU for YOLO-v3 */ | ||
624 | + dpuRunTask(task); | ||
625 | + thread t(co_detect2, task, ref(img), width, height, ref(cam)); | ||
626 | + postProcess(task, img, width, height); | ||
627 | + Yolonum++; | ||
628 | + return t; | ||
629 | +} | ||
630 | + | ||
631 | +/** | ||
632 | + * @brief Entry for running YOLO-v3 neural network for ADAS object detection | ||
633 | + * | ||
634 | + */ | ||
635 | +void Close(int signo) | ||
636 | +{ | ||
637 | + close(Sockfd_host); | ||
638 | + close(Sockfd_dcam); | ||
639 | + printf("\ndone\n"); | ||
640 | + exit(0); | ||
641 | +} | ||
642 | +int main(const int argc, const char** argv) { | ||
643 | + int len; | ||
644 | + struct sockaddr_in Addr, dcamAddr, hostAddr; | ||
645 | + | ||
646 | + signal(SIGINT, Close); | ||
647 | + | ||
648 | + if (argc != 1) { | ||
649 | + cout << "Usage : ./yolo " << endl; | ||
650 | + return -1; | ||
651 | + } | ||
652 | + | ||
653 | + // get current path | ||
654 | + /*char cwd[256]; | ||
655 | + if(getcwd(cwd, 256) == NULL) { | ||
656 | + perror("getcwd"); | ||
657 | + exit(1); | ||
658 | + }*/ | ||
659 | + | ||
660 | + /* socket for host - tcp */ | ||
661 | + if ((Sockfd_host = socket(PF_INET, SOCK_STREAM, 0)) < 0) { | ||
662 | + perror("socket"); | ||
663 | + exit(1); | ||
664 | + } | ||
665 | + | ||
666 | + cout << "~~"; | ||
667 | + | ||
668 | + bzero((char*)&Addr, sizeof(Addr)); | ||
669 | + Addr.sin_family = PF_INET; | ||
670 | + Addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
671 | + Addr.sin_port = htons(Port_host); | ||
672 | + | ||
673 | + if (bind(Sockfd_host, (struct sockaddr*)&Addr, sizeof(Addr)) < 0) { | ||
674 | + perror("bind"); | ||
675 | + exit(1); | ||
676 | + } | ||
677 | + listen(Sockfd_host, 5); | ||
678 | + | ||
679 | + len = sizeof(hostAddr); | ||
680 | + newSock_host = accept(Sockfd_host, (struct sockaddr*)&hostAddr, (socklen_t*)&len); | ||
681 | + if (newSock_host < 0) { | ||
682 | + perror("accept"); | ||
683 | + exit(1); | ||
684 | + } | ||
685 | + | ||
686 | + /*socket for depth camera - udp*/ | ||
687 | + if ((Sockfd_dcam = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | ||
688 | + perror("socket"); | ||
689 | + exit(1); | ||
690 | + } | ||
691 | + | ||
692 | + bzero((char*)&dcamAddr, sizeof(dcamAddr)); | ||
693 | + dcamAddr.sin_family = PF_INET; | ||
694 | + dcamAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
695 | + dcamAddr.sin_port = htons(Port_dcam); | ||
696 | + | ||
697 | + if (bind(Sockfd_dcam, (struct sockaddr*)&dcamAddr, sizeof(dcamAddr)) < 0) { | ||
698 | + perror("bind"); | ||
699 | + exit(1); | ||
700 | + } | ||
701 | + | ||
702 | + /* | ||
703 | + if(write(Sockfd, (char*)&cwd, sizeof(cwd)) < 0) { // cwd 전송 | ||
704 | + perror("write"); | ||
705 | + exit(1); | ||
706 | + }*/ | ||
707 | + | ||
708 | + if (!cam.isOpened()) { | ||
709 | + cout << "Fail to open webcam" << endl; | ||
710 | + exit(-1); | ||
711 | + } | ||
712 | + string file_ind; | ||
713 | + | ||
714 | + // init Yolo2 before while | ||
715 | + dpuOpen(); | ||
716 | + DPUKernel* kernel = dpuLoadKernel("yolo"); | ||
717 | + DPUTask* task = dpuCreateTask(kernel, 0); | ||
718 | + Mat img; | ||
719 | + thread t1, t2; | ||
720 | + cam.read(img); | ||
721 | + t2 = runYOLO2(task, img, cam); | ||
722 | + file_ind = "result_" + to_string(index_yolo) + ".jpg"; | ||
723 | + imwrite(file_ind, img); | ||
724 | + cout << "Yolo2 : " << file_ind << endl; | ||
725 | + index_yolo += 2; | ||
726 | + while (1) { | ||
727 | + file_ind = "result_" + to_string(index_yolo) + ".jpg"; | ||
728 | + // run yolo1 | ||
729 | + for (int i = 0; i < 5; i++) // buffer claer | ||
730 | + cam.grab(); | ||
731 | + cam.read(img); | ||
732 | + t1 = runYOLO(task, img, cam); | ||
733 | + if (Mutexnum + 1 < Yolonum) // create mutex | ||
734 | + t2.join(); | ||
735 | + imwrite(file_ind, img); | ||
736 | + cout << "Yolo1 : " << file_ind << endl; | ||
737 | + index_yolo += 2; | ||
738 | + imshow("Xilinx DPU", img); | ||
739 | + if (waitKey(30) == 27) break; | ||
740 | + // run yolo2 | ||
741 | + for (int i = 0; i < 5; i++) // buffer claer | ||
742 | + cam.grab(); | ||
743 | + cam.read(img); | ||
744 | + t2 = runYOLO2(task, img, cam); | ||
745 | + if (Mutexnum + 1 < Yolonum) // create mutex | ||
746 | + t1.join(); | ||
747 | + file_ind = "result_" + to_string(index_yolo) + ".jpg"; | ||
748 | + imwrite(file_ind, img); | ||
749 | + cout << "Yolo2 : " << file_ind << endl; | ||
750 | + index_yolo += 2; | ||
751 | + imshow("Xilinx DPU", img); | ||
752 | + if (waitKey(30) == 27) break; | ||
753 | + } | ||
754 | + dpuDestroyTask(task); | ||
755 | + /* Destroy DPU Kernels & free resources */ | ||
756 | + dpuDestroyKernel(kernel); | ||
757 | + | ||
758 | + /* Dettach from DPU driver & free resources */ | ||
759 | + dpuClose(); | ||
760 | + return 0; | ||
761 | +} | ||
762 | + |
Proj/yolo+matching+socket/receive_result.c
0 → 100644
1 | +// 최종 결합된 data를 socket을 이용해 수신 | ||
2 | + | ||
3 | +#include <stdio.h> | ||
4 | +#include <sys/types.h> | ||
5 | +#include <sys/socket.h> | ||
6 | +#include <netinet/in.h> | ||
7 | +#include <arpa/inet.h> | ||
8 | +#include <stdlib.h> | ||
9 | +#include <string.h> | ||
10 | +#include <unistd.h> | ||
11 | +#include <signal.h> | ||
12 | + | ||
13 | +#define Port 12300 | ||
14 | +#define Board_addr "192.168.2.99" | ||
15 | +#define BUF_SIZE 1024 | ||
16 | + | ||
17 | +int Sockfd; | ||
18 | + | ||
19 | +void receive_result() { | ||
20 | + static int ind = 0; | ||
21 | + | ||
22 | + char info[2000]; | ||
23 | + strcpy(info, ""); | ||
24 | + if (read(Sockfd, (char*)&info, sizeof(info)) <= 0) { | ||
25 | + perror("read"); | ||
26 | + exit(1); | ||
27 | + } | ||
28 | + printf("%s\n", info); | ||
29 | + | ||
30 | + /*int now_size = 0, read_size; | ||
31 | + char file_name[256], msg_buf[BUF_SIZE], sync = '\0'; | ||
32 | + FILE* image; | ||
33 | + unsigned int fsize; | ||
34 | + | ||
35 | + sprintf(file_name, "img_%03d_result.jpg", ind); // save file name | ||
36 | + | ||
37 | + image = fopen(file_name, "w"); | ||
38 | + | ||
39 | + // recv file size | ||
40 | + msg_buf[fsize] = '\0'; | ||
41 | + fsize = atoi(msg_buf); | ||
42 | + printf("%d\n", fsize); | ||
43 | + | ||
44 | + // recv image file | ||
45 | + while(1) { | ||
46 | + memset(msg_buf, 0, BUF_SIZE); | ||
47 | + read_size = read(Sockfd, (char*)&msg_buf, BUF_SIZE); // get image from socket | ||
48 | + fwrite(msg_buf, 1, read_size, image); // write image | ||
49 | + now_size += read_size; | ||
50 | + if(now_size == fsize) | ||
51 | + break; | ||
52 | + else if(now_size > fsize) { | ||
53 | + printf("file error\n"); | ||
54 | + exit(1); | ||
55 | + } | ||
56 | + write(Sockfd, (char*)&sync, sizeof(sync)); // for sync | ||
57 | + } | ||
58 | + | ||
59 | + printf("Receive done : %s\n", file_name); | ||
60 | + | ||
61 | + if(write(Sockfd, (char*)&file_name, sizeof(file_name)) < 0) { // 종료 전송 | ||
62 | + perror("write"); | ||
63 | + exit(1); | ||
64 | + } | ||
65 | + | ||
66 | + fclose(image); | ||
67 | + ind++; | ||
68 | + if(ind == 999) ind = 0; // max 1000 file | ||
69 | +*/ | ||
70 | +} | ||
71 | + | ||
72 | +main(int argc, char *argv[]) | ||
73 | +{ | ||
74 | + int n, len; | ||
75 | + struct sockaddr_in boardAddr; | ||
76 | + char cwd[256]; | ||
77 | + | ||
78 | + if(getcwd(cwd, 256) == NULL) { | ||
79 | + perror("getcwd"); | ||
80 | + exit(1); | ||
81 | + } | ||
82 | + | ||
83 | + if ((Sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { | ||
84 | + perror("socket"); | ||
85 | + exit(1); | ||
86 | + } | ||
87 | + | ||
88 | + bzero((char *)&boardAddr, sizeof(boardAddr)); | ||
89 | + boardAddr.sin_family = PF_INET; | ||
90 | + boardAddr.sin_addr.s_addr = inet_addr(Board_addr); | ||
91 | + boardAddr.sin_port = htons(Port); | ||
92 | + | ||
93 | + if (connect(Sockfd, (struct sockaddr*)&boardAddr, sizeof(boardAddr)) < 0) { | ||
94 | + perror("connect"); | ||
95 | + exit(1); | ||
96 | + } | ||
97 | + | ||
98 | + printf("connect\n"); | ||
99 | + /* | ||
100 | + if(write(Sockfd, (char*)&cwd, sizeof(cwd)) < 0) { // cwd 전송 | ||
101 | + perror("write"); | ||
102 | + exit(1); | ||
103 | + } | ||
104 | + */ | ||
105 | + while(1) { | ||
106 | + printf("\n\n"); | ||
107 | + receive_result(); // 받은 파일이름 출력 | ||
108 | + } | ||
109 | + close(Sockfd); | ||
110 | + return 0; | ||
111 | +} |
-
Please register or login to post a comment