- Edited
Hey guys, how are you doing? I have this code, and how can I run it in standalone mode? I have both OAK-1 PoE and OAK-D PoE cameras, I want to run it in standalone mode to get the maximum performance as possible. Is there any step-by-step documentation or tutorial on how to convert into a standalone mode? I read the official website, But couldn't understand well exactly how to do it. I'll leave the code below, hope you will help me thanks
from pathlib import Path
import cv2
import depthai as dai
import time
from environs import Env
env = Env()
env.read_env()
MxID = env('MxID')
# Set custom ROI coordinates (x, y, width, height)
custom_roi = (350/640, 250/640, 640/640, 640/640)
# Coordinates of the counting line
line_start = (320, 0)
line_end = (320, 640)
# tiny yolo v4 label texts
labelMap = ["person",]
nnPath = str((Path(__file__).parent / Path('model/yolov6n_coco_640x640_openvino_2022.1_6shave.blob')).resolve().absolute())
# Creating pipeline
pipeline = dai.Pipeline()
# Sources and outputs
camRgb = pipeline.create(dai.node.ColorCamera)
detectionNetwork = pipeline.create(dai.node.YoloDetectionNetwork)
objectTracker = pipeline.create(dai.node.ObjectTracker)
xlinkOut = pipeline.create(dai.node.XLinkOut)
trackerOut = pipeline.create(dai.node.XLinkOut)
fullFrame = pipeline.create(dai.node.XLinkOut) # creating new pipline for full_frame
xlinkOut.setStreamName("preview")
trackerOut.setStreamName("tracklets")
fullFrame.setStreamName("full_frame") # To get Full Frame
# Creating Manip node
manip = pipeline.create(dai.node.ImageManip)
# Setting CropRect for the Region of Interest
# manip.initialConfig.setCropRect(*custom_roi)
# Setting Resize for the neural network input size
manip.initialConfig.setResize(640, 640)
# Setting maximum output frame size based on the desired output dimensions
max_output_width = 640
max_output_height = 640
max_output_frame_size = 3 * max_output_width * max_output_height # Assuming 3 channels for BGR image
manip.setMaxOutputFrameSize(max_output_frame_size)
# Properties
if MxID == "14442C10C1AD3FD700":
camRgb.setImageOrientation(dai.CameraImageOrientation.HORIZONTAL_MIRROR)
camRgb.setPreviewSize(640, 640)
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
camRgb.setInterleaved(False)
camRgb.setColorOrder(dai.ColorCameraProperties.ColorOrder.BGR)
camRgb.setFps(40)
# Network specific settings
detectionNetwork.setConfidenceThreshold(0.5)
detectionNetwork.setNumClasses(80)
detectionNetwork.setCoordinateSize(4)
# detectionNetwork.setAnchors([10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319]) #for YOLOv4
# detectionNetwork.setAnchorMasks({"side26": [1, 2, 3], "side13": [3, 4, 5]})
detectionNetwork.setAnchors([10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326]) #for YOLOv5
detectionNetwork.setAnchorMasks({"side52": [0,1,2], "side26": [3,4,5], "side13": [6,7,8]})
detectionNetwork.setIouThreshold(0.5)
detectionNetwork.setBlobPath(nnPath)
detectionNetwork.setNumInferenceThreads(2)
detectionNetwork.input.setBlocking(False)
objectTracker.setDetectionLabelsToTrack([0]) # track only person
# possible tracking types: ZERO_TERM_COLOR_HISTOGRAM, ZERO_TERM_IMAGELESS, SHORT_TERM_IMAGELESS, SHORT_TERM_KCF
objectTracker.setTrackerType(dai.TrackerType.ZERO_TERM_COLOR_HISTOGRAM)
# take the smallest ID when new object is tracked, possible options: SMALLEST_ID, UNIQUE_ID
objectTracker.setTrackerIdAssignmentPolicy(dai.TrackerIdAssignmentPolicy.UNIQUE_ID)
#Linking
# Connecting Manip node to ColorCamera
camRgb.preview.link(manip.inputImage)
camRgb.preview.link(fullFrame.input)
# Connecting Manip node to YoloDetectionNetwork
manip.out.link(detectionNetwork.input)
# camRgb.preview.link(detectionNetwork.input)
objectTracker.passthroughTrackerFrame.link(xlinkOut.input)
detectionNetwork.passthrough.link(objectTracker.inputTrackerFrame)
detectionNetwork.passthrough.link(objectTracker.inputDetectionFrame)
detectionNetwork.out.link(objectTracker.inputDetections)
objectTracker.out.link(trackerOut.input)
device = dai.DeviceInfo(MxID)
# Connecting to device and starting pipeline
with dai.Device(pipeline, device) as device:
preview = device.getOutputQueue("preview", 4, False)
tracklets = device.getOutputQueue("tracklets", 4, False)
previewFull = device.getOutputQueue("full_frame", 4, False)
startTime = time.monotonic()
counter = 0
fps = 0
frame = None
h_line = 320
pos = {}
going_in = 0
going_out = 0
obj_counter = [0, 0, 0, 0] # left, right, up, down
while(True):
imgFrame = preview.get()
track = tracklets.get()
imgFull = previewFull.get()
counter+=1
current_time = time.monotonic()
if (current_time - startTime) > 1 :
fps = counter / (current_time - startTime)
counter = 0
startTime = current_time
color = (255, 0, 0)
text_color = (0, 0, 255)
rectangle = (111, 147, 26)
frame = imgFrame.getCvFrame()
trackletsData = track.tracklets
# Draw the counting line on the frame
cv2.line(frame, line_start, line_end, (0, 255, 0), 2)
for t in trackletsData:
if t.status.name == "TRACKED":
roi = t.roi.denormalize(frame.shape[1], frame.shape[0])
x1 = int(roi.topLeft().x)
y1 = int(roi.topLeft().y)
x2 = int(roi.bottomRight().x)
y2 = int(roi.bottomRight().y)
# Calculate centroid
centroid = (int((x2-x1)/2+x1), int((y2-y1)/2+y1))
# Calculate the buffer zone boundaries
right_boundary = h_line + 15
left_boundary = h_line - 15
try:
if not (left_boundary <= centroid[0] <= right_boundary):
pos[t.id] = {
'previous': pos[t.id]['current'],
'current': centroid[0] }
if pos[t.id]['current'] > right_boundary and pos[t.id]['previous'] < right_boundary:
obj_counter[1] += 1 #Right side
going_in += 1
if pos[t.id]['current'] < left_boundary and pos[t.id]['previous'] > left_boundary:
obj_counter[0] += 1 #Left side
going_out += 1
except:
pos[t.id] = {'current': centroid[0]}
try:
label = labelMap[t.label]
except:
label = t.label
cv2.putText(frame, str(label), (x1 + 10, y1 + 20), cv2.FONT_HERSHEY_TRIPLEX, 0.5, text_color)
cv2.putText(frame, f"ID: {[t.id]}", (x1 + 10, y1 + 45), cv2.FONT_HERSHEY_TRIPLEX, 0.5, text_color)
cv2.putText(frame, t.status.name, (x1 + 10, y1 + 70), cv2.FONT_HERSHEY_TRIPLEX, 0.5, text_color)
cv2.rectangle(frame, (x1, y1), (x2, y2), rectangle, cv2.FONT_HERSHEY_SIMPLEX)
cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1)
cv2.putText(frame, f'Left: {obj_counter[0]}; Right: {obj_counter[1]}', (10, 35), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0xFF), 2, cv2.FONT_HERSHEY_SIMPLEX)
cv2.putText(frame, "FPS: {:.2f}".format(fps), (2, frame.shape[0] - 4), cv2.FONT_HERSHEY_TRIPLEX, 0.6, text_color)
# Displaying full frame
frameFull = imgFull.getCvFrame()
cv2.imshow("full_frame", frameFull)
# Displaying cropped frame with tracked objects
cv2.imshow("tracker", frame)
if cv2.waitKey(1) == ord('q'):
break`