revert camera thread, util opencv bug fix instead

This commit is contained in:
Prohurtz 2023-07-12 09:38:34 -05:00
parent d5462e09fe
commit 0cd0ad6334
3 changed files with 29 additions and 65 deletions

View File

@ -5,11 +5,11 @@ import serial
import serial.tools.list_ports
import threading
import time
import asyncio
from colorama import Fore
from config import EyeTrackConfig
from enum import Enum
import concurrent.futures
WAIT_TIME = 0.1
# Serial communication protocol:
@ -48,8 +48,7 @@ class Camera:
self.cancellation_event = cancellation_event
self.current_capture_source = config.capture_source
self.cv2_camera: "cv2.VideoCapture" = None
self.timeout = 5 # Timeout in seconds
self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
self.serial_connection = None
self.last_frame_time = time.time()
self.frame_number = 0
@ -71,33 +70,14 @@ class Camera:
def set_output_queue(self, camera_output_outgoing: "queue.Queue"):
self.camera_output_outgoing = camera_output_outgoing
def init_camera(self):
if self.cv2_camera == None:
# time.sleep(0.5) # Very important wait
def init():
return cv2.VideoCapture(self.current_capture_source)
future = self.executor.submit(init)
future.add_done_callback(self.done_callback)
else:
pass
def done_callback(self, future):
try:
time.sleep(0.5) # Very important wait
self.cv2_camera = future.result()
except Exception:
# Set cv2_camera to None if an exception occurred
self.cv2_camera = None
if future == "stop":
# Release the camera resource
if self.cv2_camera is not None:
self.cv2_camera.release()
def run(self):
OPENCV_PARAMS = [
cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 5000,
cv2.CAP_PROP_READ_TIMEOUT_MSEC, 5000,
]
while True:
if self.cancellation_event.is_set(): #TODO: fix stall when app closes and cam not found
if self.cancellation_event.is_set():
print(f"{Fore.CYAN}[INFO] Exiting Capture thread{Fore.RESET}")
self.done_callback("stop")
# print('close')
return
should_push = True
# If things aren't open, retry until they are. Don't let read requests come in any earlier
@ -105,8 +85,7 @@ class Camera:
if (
self.config.capture_source != None and self.config.capture_source != ""
):
# if self.cv2_camera is not None:
# print(self.cv2_camera, self.cv2_camera.isOpened(),self.camera_status)
if "COM" in str(self.current_capture_source):
if (
self.serial_connection is None
@ -120,19 +99,21 @@ class Camera:
if (
self.cv2_camera is None
or not self.cv2_camera.isOpened()
# or self.camera_status == CameraState.DISCONNECTED
or self.camera_status == CameraState.DISCONNECTED
or self.config.capture_source != self.current_capture_source
):
print(self.error_message.format(self.config.capture_source))
# This requires a wait, otherwise we can error and possible screw up the camera
# firmware. Fickle things.
if self.cancellation_event.wait(WAIT_TIME):
return
self.current_capture_source = self.config.capture_source
self.init_camera()
self.camera_status = CameraState.CONNECTED
#self.cv2_camera = cv2.VideoCapture(self.current_capture_source)
# self.cv2_camera = cv2.VideoCapture(self.current_capture_source)
self.cv2_camera = cv2.VideoCapture()
self.cv2_camera.setExceptionMode(True)
# https://github.com/opencv/opencv/blob/4.8.0/modules/videoio/include/opencv2/videoio.hpp#L803
self.cv2_camera.open(self.current_capture_source, cv2.CAP_FFMPEG, params=OPENCV_PARAMS)
should_push = False
else:
# We don't have a capture source to try yet, wait for one to show up in the GUI.
@ -152,17 +133,13 @@ class Camera:
if not should_push:
# if we get all the way down here, consider ourselves connected
self.camera_status = CameraState.CONNECTED
if self.cancellation_event.is_set(): #TODO: fix stall when app closes and cam not found
print(f"{Fore.CYAN}[INFO] Exiting Capture thread{Fore.RESET}")
# self.done_callback("stop")
# print('close')
def get_cv2_camera_picture(self, should_push):
try:
ret, image = self.cv2_camera.read()
if not ret:
self.cv2_camera.set(cv2.CAP_PROP_POS_FRAMES, 0)
raise RuntimeError("Problem while getting frame")
self.newft = time.time()
frame_number = self.cv2_camera.get(cv2.CAP_PROP_POS_FRAMES)
# Calculate the fps.
current_frame_time = time.time()
@ -172,18 +149,16 @@ class Camera:
self.bps = len(image) / delta_time
self.frame_number = self.frame_number + 1
self.fps = (self.fps + self.pf_fps) / 2
if self.newft != self.prevft:
self.fps = 1 / (self.newft - self.prevft)
self.prevft = self.newft
self.fps = int(self.fps)
if len(self.fl) < 60:
self.fl.append(self.fps)
else:
self.fl.pop(0)
self.fl.append(self.fps)
self.fps = sum(self.fl) / len(self.fl)
self.newft = time.time()
self.fps = 1 / (self.newft - self.prevft)
self.prevft = self.newft
self.fps = int(self.fps)
if len(self.fl) < 60:
self.fl.append(self.fps)
else:
self.fps = 69
self.fl.pop(0)
self.fl.append(self.fps)
self.fps = sum(self.fl) / len(self.fl)
#self.bps = image.nbytes
if should_push:
self.push_image_to_queue(image, frame_number, self.fps)
@ -293,4 +268,4 @@ class Camera:
print(
f"{Fore.YELLOW}[WARN] CAPTURE QUEUE BACKPRESSURE OF {qsize}. CHECK FOR CRASH OR TIMING ISSUES IN ALGORITHM.{Fore.RESET}")
self.camera_output_outgoing.put((image, frame_number, fps))
self.capture_event.clear()
self.capture_event.clear()

View File

@ -282,7 +282,6 @@ class EyeProcessor:
self.eyeopen = 0.0
else:
self.eyeopen = ibo
print(self.eyeopen)
self.output_images_and_update(
self.thresh,
EyeInfo(self.current_algo, self.out_x, self.out_y, 0, self.eyeopen),
@ -293,7 +292,7 @@ class EyeProcessor:
def LEAPM(self):
self.thresh = self.current_image_gray.copy()
self.current_image_gray, self.rawx, self.rawy, self.eyeopen = self.er_leap.run(self.current_image_gray, True)
self.current_image_gray, self.rawx, self.rawy, self.eyeopen = self.er_leap.run(self.current_image_gray)
self.thresh = self.current_image_gray.copy()
self.out_x, self.out_y = cal.cal_osc(self, self.rawx, self.rawy)
self.current_algorithm = EyeInfoOrigin.LEAP

View File

@ -124,8 +124,6 @@ class LEAP_C(object):
self.openlist = []
self.x = 0
self.y = 0
self.frame_lim_count = 0
self.last_lid = 0.7
self.ort_session1 = onnxruntime.InferenceSession(
@ -151,13 +149,6 @@ class LEAP_C(object):
break
def leap_run(self):
if self.lid_only == True:
if self.frame_lim_count > 0:
self.frame_lim_count = 0
return self.current_image_gray, float(0), float(0), self.last_lid,
else:
self.frame_lim_count += 1
pass
img = self.current_image_gray.copy()
img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
@ -216,8 +207,7 @@ class External_Run_LEAP(object):
def __init__(self):
self.algo = LEAP_C()
def run(self, current_image_gray, trackmode):
self.algo.lid_only = trackmode
def run(self, current_image_gray):
self.algo.current_image_gray = current_image_gray
img, x, y, per = self.algo.leap_run()
return img, x, y, per