Skip to content

Commit

Permalink
add improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
VanDavv committed Jan 14, 2022
1 parent 288f1c8 commit 1c5ca47
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 120 deletions.
8 changes: 4 additions & 4 deletions depthai_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def setup(self, conf: ConfigManager):
zooName=self._conf.getModelName(),
progressFunc=self.showDownloadProgress
)
self._nnManager = NNetManager(inputSize=self._conf.inputSize, bufferSize=10 if self._conf.args.syncPreviews else 0)
self._nnManager = NNetManager(inputSize=self._conf.inputSize, bufferSize=10 if self._conf.args.sync else 0)

if self._conf.getModelDir() is not None:
configPath = self._conf.getModelDir() / Path(self._conf.getModelName()).with_suffix(f".json")
Expand Down Expand Up @@ -217,7 +217,7 @@ def setup(self, conf: ConfigManager):
self._fps = FPSHandler() if self._conf.useCamera else FPSHandler(self._cap)

if self._conf.useCamera:
pvClass = SyncedPreviewManager if self._conf.args.syncPreviews else PreviewManager
pvClass = SyncedPreviewManager if self._conf.args.sync else PreviewManager
self._pv = pvClass(display=self._conf.args.show, nnSource=self._conf.getModelSource(), colorMap=self._conf.getColorMap(),
dispMultiplier=self._conf.dispMultiplier, mouseTracker=True, decode=self._conf.lowBandwidth and not self._conf.lowCapabilities,
fpsHandler=self._fps, createWindows=self._displayFrames, depthConfig=self._pm._depthConfig)
Expand Down Expand Up @@ -866,8 +866,8 @@ def guiOnStaticticsConsent(self, value):
pass
self.worker.signals.setDataSignal.emit(["restartRequired", True])

def guiOnToggleSyncPreview(self, value):
self.updateArg("syncPreviews", value)
def guiOnToggleSync(self, value):
self.updateArg("sync", value)

def guiOnToggleColorEncoding(self, enabled, fps):
oldConfig = self.confManager.args.encode or {}
Expand Down
2 changes: 1 addition & 1 deletion depthai_helpers/arg_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,5 @@ def parseArgs():
parser.add_argument("--cameraSharpness", type=_comaSeparated("all", int), nargs="+", help="Specify image sharpness")
parser.add_argument('--skipVersionCheck', action="store_true", help="Disable libraries version check")
parser.add_argument('--noSupervisor', action="store_true", help="Disable supervisor check")
parser.add_argument('--syncPreviews', action="store_true", help="Enable frame synchronization. If enabled, all frames will be synced before preview (same sequence number)")
parser.add_argument('--sync', action="store_true", help="Enable frame and NN synchronization. If enabled, all frames and NN results will be synced before preview (same sequence number)")
return parser.parse_args()
22 changes: 7 additions & 15 deletions depthai_sdk/src/depthai_sdk/managers/preview_manager.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import math
from datetime import timedelta
from queue import Queue

import cv2
import depthai as dai
from depthai_sdk import DelayQueue

from ..previews import Previews, MouseClickTracker
import numpy as np
Expand Down Expand Up @@ -251,29 +251,21 @@ def prepareFrames(self, blocking=False, callback=None):
self._lastSeqs[queue.getName()] = seq

if len(packets) == len(self.outputQueues):
self._packetsQ = DelayQueue(maxsize=100)
prevTimestamp = None
prevDelay = timedelta()
self._packetsQ = Queue(maxsize=100)
unsyncedSeq = sorted(list(filter(lambda itemSeq: itemSeq < seq, self._seqPackets.keys())))
for seqKey in unsyncedSeq:
unsynced = {
synced_name: self.__get_next_seq_packet(seqKey, synced_name, synced_packet)
for synced_name, synced_packet in packets.items()
}
ts = next(iter(unsynced.values())).getTimestamp()
if prevTimestamp is None:
delay = timedelta()
else:
delta = ts - prevTimestamp
delay = delta + prevDelay
prevDelay += delta

prevTimestamp = ts
self._packetsQ.put(unsynced, delay.microseconds)
self._packetsQ.put(unsynced)
del self._seqPackets[seqKey]

if self._packetsQ is not None:
packets = self._packetsQ.get()
try:
packets = self._packetsQ.get_nowait()
except:
packets = None
if packets is not None:
self.nnSyncSeq = min(map(lambda packet: packet.getSequenceNum(), packets.values()))
for name, packet in packets.items():
Expand Down
90 changes: 0 additions & 90 deletions depthai_sdk/src/depthai_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,93 +291,3 @@ def createBlankFrame(width, height, rgb_color=(0, 0, 0)):
image[:] = color

return image


"""
.. Copyright (c) 2016 Marshall Farrier
license http://opensource.org/licenses/MIT
Synchronized delay queue.
Notes
-----
`DelayQueue` dispenses with the block and timeout
features available in the `queue` library. Otherwise,
`DelayQueue` is built in a similar manner to `queue.PriorityQueue`.
The client can track retries by wrapping each item
with a parameter that counts retries:
>>> queue.put([n_retries, item])
"""


class DelayQueue(object):
class Empty(Exception):
# raised by `get()` if queue is empty
pass


class NotReady(Exception):
# raised by `get()` if queue is not empty, but delay for head
# of queue has not yet expired
pass


class Full(Exception):
# raised by `put()` if queue is full
pass

def __init__(self, maxsize=0):
self.maxsize = maxsize
self.queue = []
self.mutex = threading.Lock()
self.not_empty = threading.Condition(self.mutex)
self.not_full = threading.Condition(self.mutex)
self.ready = threading.Condition(self.mutex)

def ask(self):
"""
Return the wait time in seconds required to retrieve the
item currently at the head of the queue.
Note that there is no guarantee that a call to `get()` will
succeed even if `ask()` returns 0. By the time the calling
thread reacts, other threads may have caused a different
item to be at the head of the queue.
"""
with self.mutex:
if not len(self.queue):
raise self.Empty
utcnow = dt.datetime.utcnow()
if self.queue[0][0] <= utcnow:
self.ready.notify()
return 0
return (self.queue[0][0] - utcnow).total_seconds()

def put(self, item, delay=0):
if delay < 0:
raise ValueError("'delay' must be a non-negative number")
with self.not_full:
if len(self.queue) >= self.maxsize > 0:
raise self.Full
heappush(self.queue, (dt.datetime.utcnow() + dt.timedelta(seconds=delay), item))
self.not_empty.notify()
if not delay:
self.ready.notify()

def get(self):
with self.ready:
if not len(self.queue):
return None
utcnow = dt.datetime.utcnow()
if utcnow < self.queue[0][0]:
return None
item = heappop(self.queue)[1]
self.not_full.notify()
return item

def qsize(self):
"""
Return the approximate size of the queue.
The answer will not be reliable, as producers and consumers
can change the queue size before the result can be used.
"""
with self.mutex:
return len(self.queue)
9 changes: 3 additions & 6 deletions gui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def toggleStatisticsConsent(self, value):
instance.guiOnStaticticsConsent(value)

@pyqtSlot(bool)
def toggleSyncPreview(self, value):
instance.guiOnToggleSyncPreview(value)
def toggleSync(self, value):
instance.guiOnToggleSync(value)

@pyqtSlot(str)
def runApp(self, appName):
Expand Down Expand Up @@ -324,10 +324,7 @@ def createProgressFrame(self, donePercentage=None):
w, h = int(self.writer.width()), int(self.writer.height())
if self.progressFrame is None:
self.progressFrame = createBlankFrame(w, h)
if confManager is None:
downloadText = "Downloading model blob..."
else:
downloadText = f"Downloading {confManager.getModelName()} blob..."
downloadText = "Downloading model blob..."
textsize = cv2.getTextSize(downloadText, cv2.FONT_HERSHEY_TRIPLEX, 0.5, 4)[0][0]
offset = int((w - textsize) / 2)
cv2.putText(self.progressFrame, downloadText, (offset, 250), cv2.FONT_HERSHEY_TRIPLEX, 0.5, (255, 255, 255), 4, cv2.LINE_AA)
Expand Down
2 changes: 1 addition & 1 deletion gui/views/AIProperties.qml
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ ListView {
y: 375
width: 250
height: 48
text: qsTr("Spatial Bounding Boxes")
text: qsTr("<font color=\"white\">Spatial Bounding Boxes</font>")
font.family: "Courier"
autoExclusive: false
transformOrigin: Item.Center
Expand Down
6 changes: 3 additions & 3 deletions gui/views/CameraProperties.qml
Original file line number Diff line number Diff line change
Expand Up @@ -582,14 +582,14 @@ ListView {
}

Switch {
id: syncPreviewsSwitch
id: syncSwitch
x: 203
y: 158
width: 164
height: 28
text: qsTr("<font color=\"white\">Sync Previews</font>")
text: qsTr("<font color=\"white\">Enable sync</font>")
onToggled: {
appBridge.toggleSyncPreview(syncPreviewsSwitch.checked)
appBridge.toggleSync(syncSwitch.checked)
}
}
}
Expand Down

0 comments on commit 1c5ca47

Please sign in to comment.