removed multi-processing

added low-latnecy mode and an argument for it
added target brightness argument
This commit is contained in:
Cowwan 2024-02-10 11:46:07 -05:00
parent f288689960
commit b2324c539b
2 changed files with 34 additions and 33 deletions

View file

@ -26,8 +26,12 @@ parser.add_argument("--model", type=int, help="This can be used to select the tr
parser.add_argument("--preview", type=int, help="Preview the frames sent to the tracker", default=0)
parser.add_argument("--feature-type", type=int, help="Sets which version of feature extraction is used. 0 is my new version that works well for me and allows for some customization, 1 is EmilianaVT's version aka, normal OpenSeeFace operation", default=0, choices=[0, 1])
parser.add_argument("--numpy-threads", type=int, help="Numer of threads Numpy can use, doesn't seem to effect much", default=1)
parser.add_argument("-T","--threads", type=int, help="Numer of threads used for landmark detection. Default is 1 (~15ms per frame on my computer), 2 gets slightly faster frames (~10ms on my computer), more than 2 doesn't seem to help much", default=2)
parser.add_argument("-T","--threads", type=int, help="Numer of threads used for landmark detection. Default is 1 (~15ms per frame on my computer), 2 gets slightly faster frames (~10ms on my computer), more than 2 doesn't seem to help much", default=1)
parser.add_argument("-v", "--visualize", type=int, help="Set this to 1 to visualize the tracking", default=0)
parser.add_argument("--low-latency", type=int, help="Low latency mode. Lowers latency, at the cost of inconsistent timings", default = 0)
parser.add_argument("--target-brightness", type=float, help="range 0.25-0.75, Target brightness of the brightness adjustment. Defaults to 0.55", default = 0.55)
args = parser.parse_args()
@ -42,20 +46,25 @@ previewFlag = (args.preview == 1)
mirror_input = args.mirror_input
featureType = args.feature_type
visualizeFlag = (args.visualize == 1)
lowLatency = (args.low_latency == 1)
threads = args.threads
target_duration = 1. / fps
targetBrightness = 0.55
targetBrightness = min(max(args.target_brightness, 0.25), 0.75)
silent = (args.silent == 1)
#creating queues
if height > 480:
if lowLatency:
target_duration = 0.75 / fps
frameQueueSize = 1
elif height > 480:
target_duration = 1 / fps
frameQueueSize = 2
else:
frameQueueSize = 2
frameQueueSize = 1
target_duration = 1 / fps
frameQueue = multiprocessing.Queue(maxsize=frameQueueSize)
faceQueue = multiprocessing.Queue(maxsize=1)
frameQueue = queue.Queue(maxsize=frameQueueSize)
faceQueue = queue.Queue(maxsize=1)
packetQueue = queue.Queue()
#I want to decouple the requests so they don't block anything else if they're slow
@ -64,18 +73,16 @@ packetSenderThread = threading.Thread(target = VTS.packetSender, args = [],)
packetSenderThread.daemon = True
packetSenderThread.start()
#creating processes
webcamProcess = multiprocessing.Process(target=webcam.startProcess,args = (frameQueue, faceQueue, fps, targetBrightness, width, height, mirror_input, ))
webcamProcess.daemon = True
webcamProcess.start()
webcamThread = threading.Thread(target=webcam.startProcess,args = (frameQueue, faceQueue, fps, targetBrightness, width, height, mirror_input, ))
webcamThread.daemon = True
webcamThread.start()
#This is it's own process because it's super weird performance wise
if previewFlag or visualizeFlag:
previewFrameQueue = multiprocessing.Queue(maxsize=1)
previewProcess = multiprocessing.Process(target=preview.startProcess, args = (previewFrameQueue, target_duration,))
previewProcess.daemon = True
previewProcess.start()
previewFrameQueue = queue.Queue(maxsize=1)
previewThread = threading.Thread(target=preview.startProcess, args = (previewFrameQueue, target_duration,))
previewThread.daemon = True
previewThread.start()
frame_count = 0
peak_frame_time=0.0
@ -94,9 +101,9 @@ totalTotalLatency = 0.0
tracker = Tracker(width, height, featureType, threads, threshold=args.threshold, silent=silent, model_type=args.model, detection_threshold=args.detection_threshold)
#don't start until the webcam is ready, then give it a little more time to fill it's buffer
while frameQueue.qsize() < 1:
time.sleep(0.1)
frameQueue.get()
time.sleep(0.1)
face = None
totalFrameLatency = 0
try:
@ -126,14 +133,12 @@ try:
if visualizeFlag:
preview.visualize(frame, faceInfo, previewFrameQueue, face_center, face_radius)
duration = time.perf_counter() - frame_get
total_active_time += duration
peak_frame_time = max(peak_frame_time, duration)
if duration < target_duration:
time.sleep(target_duration - duration)
else:
#all caps because if this is consistently happening it's an issue
messageQueue.put("CANNOT MAINTAIN FRAMERATE!")
frameTime = time.perf_counter() - frame_get
total_active_time += frameTime
peak_frame_time = max(peak_frame_time, frameTime)
duration = time.perf_counter() - frame_start
time.sleep(max(0, target_duration - duration))
peak_time_between = max(peak_time_between, time.perf_counter() -frame_start)
total_run_time += time.perf_counter() -frame_start
@ -171,7 +176,4 @@ print(f"Peak frame time: {(peak_frame_time*1000):.3f}ms")
print(f"Average frame time: { ((total_active_time)*1000/(frame_count)):.3f}ms")
print(f"Run time (seconds): {total_run_time:.2f} s\nFrames: {frame_count}")
webcamProcess.terminate()
if previewFlag:
previewProcess.terminate()
os._exit(0)

View file

@ -42,7 +42,7 @@ class Webcam():
self.cap.set(3, width)
self.cap.set(4, height)
self.cap.set(cv2.CAP_PROP_FPS, fps)
self.targetFrameTime = 1. / fps
self.targetFrameTime = 1. / (fps - 0.001)
self.gamma = 0.7
self.mirror = mirrorInput
self.frameQueue = frameQueue #outgoing frames from the webcam
@ -101,7 +101,6 @@ class Webcam():
self.frame = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2RGB)
#calculate the ideal gamma based on the brightness of the user's face
#kind of winging it with the math, but it's a lot better than calculating based on the whole frame
def updateGamma(self):