tiny_yolo.cpp
Go to the documentation of this file.
1 #include <chrono>
2 #include <iostream>
3 
4 // Includes common necessary includes for development using depthai library
5 #include "depthai/depthai.hpp"
6 
7 /*
8 The code is the same as for Tiny-yolo-V3, the only difference is the blob file.
9 The blob was compiled following this tutorial: https://github.com/TNTWEN/OpenVINO-YOLOV4
10 */
11 
12 static const std::vector<std::string> labelMap = {
13  "person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck", "boat",
14  "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse",
15  "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag",
16  "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove",
17  "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon",
18  "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza",
19  "donut", "cake", "chair", "sofa", "pottedplant", "bed", "diningtable", "toilet", "tvmonitor",
20  "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink",
21  "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"};
22 
23 static std::atomic<bool> syncNN{true};
24 
25 int main(int argc, char** argv) {
26  using namespace std;
27  using namespace std::chrono;
28  std::string nnPath(BLOB_PATH);
29 
30  // If path to blob specified, use that
31  if(argc > 1) {
32  nnPath = std::string(argv[1]);
33  }
34 
35  // Print which blob we are using
36  printf("Using blob at path: %s\n", nnPath.c_str());
37 
38  // Create pipeline
39  dai::Pipeline pipeline;
40 
41  // Define sources and outputs
42  auto camRgb = pipeline.create<dai::node::ColorCamera>();
43  auto detectionNetwork = pipeline.create<dai::node::YoloDetectionNetwork>();
44  auto xoutRgb = pipeline.create<dai::node::XLinkOut>();
45  auto nnOut = pipeline.create<dai::node::XLinkOut>();
46 
47  xoutRgb->setStreamName("rgb");
48  nnOut->setStreamName("detections");
49 
50  // Properties
51  camRgb->setPreviewSize(416, 416);
53  camRgb->setInterleaved(false);
54  camRgb->setColorOrder(dai::ColorCameraProperties::ColorOrder::BGR);
55  camRgb->setFps(40);
56 
57  // Network specific settings
58  detectionNetwork->setConfidenceThreshold(0.5f);
59  detectionNetwork->setNumClasses(80);
60  detectionNetwork->setCoordinateSize(4);
61  detectionNetwork->setAnchors({10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319});
62  detectionNetwork->setAnchorMasks({{"side26", {1, 2, 3}}, {"side13", {3, 4, 5}}});
63  detectionNetwork->setIouThreshold(0.5f);
64  detectionNetwork->setBlobPath(nnPath);
65  detectionNetwork->setNumInferenceThreads(2);
66  detectionNetwork->input.setBlocking(false);
67 
68  // Linking
69  camRgb->preview.link(detectionNetwork->input);
70  if(syncNN) {
71  detectionNetwork->passthrough.link(xoutRgb->input);
72  } else {
73  camRgb->preview.link(xoutRgb->input);
74  }
75 
76  detectionNetwork->out.link(nnOut->input);
77 
78  // Connect to device and start pipeline
79  dai::Device device(pipeline);
80 
81  // Output queues will be used to get the rgb frames and nn data from the outputs defined above
82  auto qRgb = device.getOutputQueue("rgb", 4, false);
83  auto qDet = device.getOutputQueue("detections", 4, false);
84 
85  cv::Mat frame;
86  std::vector<dai::ImgDetection> detections;
87  auto startTime = steady_clock::now();
88  int counter = 0;
89  float fps = 0;
90  auto color2 = cv::Scalar(255, 255, 255);
91 
92  // Add bounding boxes and text to the frame and show it to the user
93  auto displayFrame = [](std::string name, cv::Mat frame, std::vector<dai::ImgDetection>& detections) {
94  auto color = cv::Scalar(255, 0, 0);
95  // nn data, being the bounding box locations, are in <0..1> range - they need to be normalized with frame width/height
96  for(auto& detection : detections) {
97  int x1 = detection.xmin * frame.cols;
98  int y1 = detection.ymin * frame.rows;
99  int x2 = detection.xmax * frame.cols;
100  int y2 = detection.ymax * frame.rows;
101 
102  uint32_t labelIndex = detection.label;
103  std::string labelStr = to_string(labelIndex);
104  if(labelIndex < labelMap.size()) {
105  labelStr = labelMap[labelIndex];
106  }
107  cv::putText(frame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
108  std::stringstream confStr;
109  confStr << std::fixed << std::setprecision(2) << detection.confidence * 100;
110  cv::putText(frame, confStr.str(), cv::Point(x1 + 10, y1 + 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
111  cv::rectangle(frame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
112  }
113  // Show the frame
114  cv::imshow(name, frame);
115  };
116 
117  while(true) {
118  std::shared_ptr<dai::ImgFrame> inRgb;
119  std::shared_ptr<dai::ImgDetections> inDet;
120 
121  if(syncNN) {
122  inRgb = qRgb->get<dai::ImgFrame>();
123  inDet = qDet->get<dai::ImgDetections>();
124  } else {
125  inRgb = qRgb->tryGet<dai::ImgFrame>();
126  inDet = qDet->tryGet<dai::ImgDetections>();
127  }
128 
129  counter++;
130  auto currentTime = steady_clock::now();
131  auto elapsed = duration_cast<duration<float>>(currentTime - startTime);
132  if(elapsed > seconds(1)) {
133  fps = counter / elapsed.count();
134  counter = 0;
135  startTime = currentTime;
136  }
137 
138  if(inRgb) {
139  frame = inRgb->getCvFrame();
140  std::stringstream fpsStr;
141  fpsStr << "NN fps: " << std::fixed << std::setprecision(2) << fps;
142  cv::putText(frame, fpsStr.str(), cv::Point(2, inRgb->getHeight() - 4), cv::FONT_HERSHEY_TRIPLEX, 0.4, color2);
143  }
144 
145  if(inDet) {
146  detections = inDet->detections;
147  }
148 
149  if(!frame.empty()) {
150  displayFrame("rgb", frame, detections);
151  }
152 
153  int key = cv::waitKey(1);
154  if(key == 'q' || key == 'Q') {
155  return 0;
156  }
157  }
158  return 0;
159 }
dai::node::XLinkOut
XLinkOut node. Sends messages over XLink.
Definition: XLinkOut.hpp:14
dai::Pipeline
Represents the pipeline, set of nodes and connections between them.
Definition: Pipeline.hpp:100
fps
static constexpr int fps
Definition: rgb_depth_aligned.cpp:12
dai::node::ColorCamera
ColorCamera node. For use with color sensors.
Definition: ColorCamera.hpp:16
dai::Device::getOutputQueue
std::shared_ptr< DataOutputQueue > getOutputQueue(const std::string &name)
Definition: Device.cpp:86
dai::node::YoloDetectionNetwork
YoloDetectionNetwork node. Parses Yolo results.
Definition: DetectionNetwork.hpp:65
main
int main(int argc, char **argv)
Definition: tiny_yolo.cpp:25
dai::node::XLinkOut::input
Input input
Definition: XLinkOut.hpp:27
depthai.hpp
dai::Pipeline::create
std::shared_ptr< N > create()
Definition: Pipeline.hpp:145
dai::ColorCameraProperties::ColorOrder::BGR
@ BGR
dai::ImgFrame
Definition: ImgFrame.hpp:25
nanorpc::core::exception::to_string
std::string to_string(std::exception const &e)
Definition: exception.h:46
labelMap
static const std::vector< std::string > labelMap
Definition: tiny_yolo.cpp:12
dai::ColorCameraProperties::SensorResolution::THE_1080_P
@ THE_1080_P
1920 × 1080
dai::Device
Definition: Device.hpp:21
dai::node::ColorCamera::preview
Output preview
Definition: ColorCamera.hpp:69
std
Definition: Node.hpp:366
dai::Node::Output::link
void link(const Input &in)
Definition: Node.cpp:84
dai::node::XLinkOut::setStreamName
void setStreamName(const std::string &name)
Definition: XLinkOut.cpp:13
dai::ImgDetections
Definition: ImgDetections.hpp:14
syncNN
static std::atomic< bool > syncNN
Definition: tiny_yolo.cpp:23


depthai
Author(s): Martin Peterlin
autogenerated on Sat Mar 22 2025 02:58:19