shvtr159

proj source file

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 +
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 +}