spatial_object_tracker.cpp
Go to the documentation of this file.
1 #include <chrono>
2 
3 #include "utility.hpp"
4 
5 // Includes common necessary includes for development using depthai library
6 #include "depthai/depthai.hpp"
7 
8 static const std::vector<std::string> labelMap = {"background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus",
9  "car", "cat", "chair", "cow", "diningtable", "dog", "horse",
10  "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"};
11 
12 static std::atomic<bool> fullFrameTracking{false};
13 
14 int main(int argc, char** argv) {
15  using namespace std;
16  using namespace std::chrono;
17  std::string nnPath(BLOB_PATH);
18 
19  // If path to blob specified, use that
20  if(argc > 1) {
21  nnPath = std::string(argv[1]);
22  }
23 
24  // Print which blob we are using
25  printf("Using blob at path: %s\n", nnPath.c_str());
26 
27  // Create pipeline
28  dai::Pipeline pipeline;
29 
30  // Define sources and outputs
31  auto camRgb = pipeline.create<dai::node::ColorCamera>();
32  auto spatialDetectionNetwork = pipeline.create<dai::node::MobileNetSpatialDetectionNetwork>();
33  auto monoLeft = pipeline.create<dai::node::MonoCamera>();
34  auto monoRight = pipeline.create<dai::node::MonoCamera>();
35  auto stereo = pipeline.create<dai::node::StereoDepth>();
36  auto objectTracker = pipeline.create<dai::node::ObjectTracker>();
37 
38  auto xoutRgb = pipeline.create<dai::node::XLinkOut>();
39  auto trackerOut = pipeline.create<dai::node::XLinkOut>();
40 
41  xoutRgb->setStreamName("preview");
42  trackerOut->setStreamName("tracklets");
43 
44  // Properties
45  camRgb->setPreviewSize(300, 300);
47  camRgb->setInterleaved(false);
48  camRgb->setColorOrder(dai::ColorCameraProperties::ColorOrder::BGR);
49 
51  monoLeft->setCamera("left");
53  monoRight->setCamera("right");
54 
55  // setting node configs
56  stereo->setDefaultProfilePreset(dai::node::StereoDepth::PresetMode::HIGH_DENSITY);
57  // Align depth map to the perspective of RGB camera, on which inference is done
58  stereo->setDepthAlign(dai::CameraBoardSocket::CAM_A);
59  stereo->setOutputSize(monoLeft->getResolutionWidth(), monoLeft->getResolutionHeight());
60 
61  spatialDetectionNetwork->setBlobPath(nnPath);
62  spatialDetectionNetwork->setConfidenceThreshold(0.5f);
63  spatialDetectionNetwork->input.setBlocking(false);
64  spatialDetectionNetwork->setBoundingBoxScaleFactor(0.5);
65  spatialDetectionNetwork->setDepthLowerThreshold(100);
66  spatialDetectionNetwork->setDepthUpperThreshold(5000);
67 
68  objectTracker->setDetectionLabelsToTrack({15}); // track only person
69  // possible tracking types: ZERO_TERM_COLOR_HISTOGRAM, ZERO_TERM_IMAGELESS, SHORT_TERM_IMAGELESS, SHORT_TERM_KCF
70  objectTracker->setTrackerType(dai::TrackerType::ZERO_TERM_COLOR_HISTOGRAM);
71  // take the smallest ID when new object is tracked, possible options: SMALLEST_ID, UNIQUE_ID
72  objectTracker->setTrackerIdAssignmentPolicy(dai::TrackerIdAssignmentPolicy::SMALLEST_ID);
73 
74  // Linking
75  monoLeft->out.link(stereo->left);
76  monoRight->out.link(stereo->right);
77 
78  camRgb->preview.link(spatialDetectionNetwork->input);
79  objectTracker->passthroughTrackerFrame.link(xoutRgb->input);
80  objectTracker->out.link(trackerOut->input);
81 
82  if(fullFrameTracking) {
83  camRgb->setPreviewKeepAspectRatio(false);
84  camRgb->video.link(objectTracker->inputTrackerFrame);
85  objectTracker->inputTrackerFrame.setBlocking(false);
86  // do not block the pipeline if it's too slow on full frame
87  objectTracker->inputTrackerFrame.setQueueSize(2);
88  } else {
89  spatialDetectionNetwork->passthrough.link(objectTracker->inputTrackerFrame);
90  }
91 
92  spatialDetectionNetwork->passthrough.link(objectTracker->inputDetectionFrame);
93  spatialDetectionNetwork->out.link(objectTracker->inputDetections);
94  stereo->depth.link(spatialDetectionNetwork->inputDepth);
95 
96  // Connect to device and start pipeline
97  dai::Device device(pipeline);
98 
99  auto preview = device.getOutputQueue("preview", 4, false);
100  auto tracklets = device.getOutputQueue("tracklets", 4, false);
101 
102  auto startTime = steady_clock::now();
103  int counter = 0;
104  float fps = 0;
105  auto color = cv::Scalar(255, 255, 255);
106 
107  while(true) {
108  auto imgFrame = preview->get<dai::ImgFrame>();
109  auto track = tracklets->get<dai::Tracklets>();
110 
111  counter++;
112  auto currentTime = steady_clock::now();
113  auto elapsed = duration_cast<duration<float>>(currentTime - startTime);
114  if(elapsed > seconds(1)) {
115  fps = counter / elapsed.count();
116  counter = 0;
117  startTime = currentTime;
118  }
119 
120  cv::Mat frame = imgFrame->getCvFrame();
121  auto trackletsData = track->tracklets;
122  for(auto& t : trackletsData) {
123  auto roi = t.roi.denormalize(frame.cols, frame.rows);
124  int x1 = roi.topLeft().x;
125  int y1 = roi.topLeft().y;
126  int x2 = roi.bottomRight().x;
127  int y2 = roi.bottomRight().y;
128 
129  uint32_t labelIndex = t.label;
130  std::string labelStr = to_string(labelIndex);
131  if(labelIndex < labelMap.size()) {
132  labelStr = labelMap[labelIndex];
133  }
134  cv::putText(frame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
135 
136  std::stringstream idStr;
137  idStr << "ID: " << t.id;
138  cv::putText(frame, idStr.str(), cv::Point(x1 + 10, y1 + 35), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
139  std::stringstream statusStr;
140  statusStr << "Status: " << t.status;
141  cv::putText(frame, statusStr.str(), cv::Point(x1 + 10, y1 + 50), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
142 
143  std::stringstream depthX;
144  depthX << "X: " << (int)t.spatialCoordinates.x << " mm";
145  cv::putText(frame, depthX.str(), cv::Point(x1 + 10, y1 + 65), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
146  std::stringstream depthY;
147  depthY << "Y: " << (int)t.spatialCoordinates.y << " mm";
148  cv::putText(frame, depthY.str(), cv::Point(x1 + 10, y1 + 80), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
149  std::stringstream depthZ;
150  depthZ << "Z: " << (int)t.spatialCoordinates.z << " mm";
151  cv::putText(frame, depthZ.str(), cv::Point(x1 + 10, y1 + 95), cv::FONT_HERSHEY_TRIPLEX, 0.5, 255);
152 
153  cv::rectangle(frame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
154  }
155 
156  std::stringstream fpsStr;
157  fpsStr << "NN fps: " << std::fixed << std::setprecision(2) << fps;
158  cv::putText(frame, fpsStr.str(), cv::Point(2, imgFrame->getHeight() - 4), cv::FONT_HERSHEY_TRIPLEX, 0.4, color);
159 
160  cv::imshow("tracker", frame);
161 
162  int key = cv::waitKey(1);
163  if(key == 'q') {
164  return 0;
165  }
166  }
167  return 0;
168 }
dai::node::MonoCamera::out
Output out
Definition: MonoCamera.hpp:47
dai::node::XLinkOut
XLinkOut node. Sends messages over XLink.
Definition: XLinkOut.hpp:14
dai::node::MonoCamera::setCamera
void setCamera(std::string name)
Definition: MonoCamera.cpp:36
dai::Pipeline
Represents the pipeline, set of nodes and connections between them.
Definition: Pipeline.hpp:100
dai::node::StereoDepth
StereoDepth node. Compute stereo disparity and depth from left-right image pair.
Definition: StereoDepth.hpp:15
fps
static constexpr int fps
Definition: rgb_depth_aligned.cpp:12
dai::CameraBoardSocket::CAM_A
@ CAM_A
dai::TrackerIdAssignmentPolicy::SMALLEST_ID
@ SMALLEST_ID
Take the smallest available ID.
dai::node::MonoCamera
MonoCamera node. For use with grayscale sensors.
Definition: MonoCamera.hpp:17
dai::node::ColorCamera
ColorCamera node. For use with color sensors.
Definition: ColorCamera.hpp:16
dai::Tracklets
Definition: Tracklets.hpp:15
dai::TrackerType::ZERO_TERM_COLOR_HISTOGRAM
@ ZERO_TERM_COLOR_HISTOGRAM
Tracking using image data too.
dai::Device::getOutputQueue
std::shared_ptr< DataOutputQueue > getOutputQueue(const std::string &name)
Definition: Device.cpp:86
dai::MonoCameraProperties::SensorResolution::THE_400_P
@ THE_400_P
fullFrameTracking
static std::atomic< bool > fullFrameTracking
Definition: spatial_object_tracker.cpp:12
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::node::ObjectTracker
ObjectTracker node. Performs object tracking using Kalman filter and hungarian algorithm.
Definition: ObjectTracker.hpp:19
dai::node::MonoCamera::setResolution
void setResolution(Properties::SensorResolution resolution)
Set sensor resolution.
Definition: MonoCamera.cpp:82
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
dai::node::MobileNetSpatialDetectionNetwork
Definition: SpatialDetectionNetwork.hpp:109
dai::ColorCameraProperties::SensorResolution::THE_1080_P
@ THE_1080_P
1920 × 1080
dai::node::StereoDepth::PresetMode::HIGH_DENSITY
@ HIGH_DENSITY
dai::Device
Definition: Device.hpp:21
labelMap
static const std::vector< std::string > labelMap
Definition: spatial_object_tracker.cpp:8
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
utility.hpp
main
int main(int argc, char **argv)
Definition: spatial_object_tracker.cpp:14


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