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 serial.tools.list_ports
import threading import threading
import time import time
import asyncio
from colorama import Fore from colorama import Fore
from config import EyeTrackConfig from config import EyeTrackConfig
from enum import Enum from enum import Enum
import concurrent.futures
WAIT_TIME = 0.1 WAIT_TIME = 0.1
# Serial communication protocol: # Serial communication protocol:
@ -48,8 +48,7 @@ class Camera:
self.cancellation_event = cancellation_event self.cancellation_event = cancellation_event
self.current_capture_source = config.capture_source self.current_capture_source = config.capture_source
self.cv2_camera: "cv2.VideoCapture" = None 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.serial_connection = None
self.last_frame_time = time.time() self.last_frame_time = time.time()
self.frame_number = 0 self.frame_number = 0
@ -71,33 +70,14 @@ class Camera:
def set_output_queue(self, camera_output_outgoing: "queue.Queue"): def set_output_queue(self, camera_output_outgoing: "queue.Queue"):
self.camera_output_outgoing = camera_output_outgoing 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): def run(self):
OPENCV_PARAMS = [
cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 5000,
cv2.CAP_PROP_READ_TIMEOUT_MSEC, 5000,
]
while True: 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}") print(f"{Fore.CYAN}[INFO] Exiting Capture thread{Fore.RESET}")
self.done_callback("stop")
# print('close')
return return
should_push = True should_push = True
# If things aren't open, retry until they are. Don't let read requests come in any earlier # 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 ( if (
self.config.capture_source != None and self.config.capture_source != "" 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 "COM" in str(self.current_capture_source):
if ( if (
self.serial_connection is None self.serial_connection is None
@ -120,19 +99,21 @@ class Camera:
if ( if (
self.cv2_camera is None self.cv2_camera is None
or not self.cv2_camera.isOpened() 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 or self.config.capture_source != self.current_capture_source
): ):
print(self.error_message.format(self.config.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 # This requires a wait, otherwise we can error and possible screw up the camera
# firmware. Fickle things. # firmware. Fickle things.
if self.cancellation_event.wait(WAIT_TIME): if self.cancellation_event.wait(WAIT_TIME):
return return
self.current_capture_source = self.config.capture_source self.current_capture_source = self.config.capture_source
self.init_camera() # self.cv2_camera = cv2.VideoCapture(self.current_capture_source)
self.camera_status = CameraState.CONNECTED
#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 should_push = False
else: else:
# We don't have a capture source to try yet, wait for one to show up in the GUI. # 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 not should_push:
# if we get all the way down here, consider ourselves connected # if we get all the way down here, consider ourselves connected
self.camera_status = CameraState.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): def get_cv2_camera_picture(self, should_push):
try: try:
ret, image = self.cv2_camera.read() ret, image = self.cv2_camera.read()
if not ret: if not ret:
self.cv2_camera.set(cv2.CAP_PROP_POS_FRAMES, 0) self.cv2_camera.set(cv2.CAP_PROP_POS_FRAMES, 0)
raise RuntimeError("Problem while getting frame") raise RuntimeError("Problem while getting frame")
self.newft = time.time()
frame_number = self.cv2_camera.get(cv2.CAP_PROP_POS_FRAMES) frame_number = self.cv2_camera.get(cv2.CAP_PROP_POS_FRAMES)
# Calculate the fps. # Calculate the fps.
current_frame_time = time.time() current_frame_time = time.time()
@ -172,7 +149,7 @@ class Camera:
self.bps = len(image) / delta_time self.bps = len(image) / delta_time
self.frame_number = self.frame_number + 1 self.frame_number = self.frame_number + 1
self.fps = (self.fps + self.pf_fps) / 2 self.fps = (self.fps + self.pf_fps) / 2
if self.newft != self.prevft: self.newft = time.time()
self.fps = 1 / (self.newft - self.prevft) self.fps = 1 / (self.newft - self.prevft)
self.prevft = self.newft self.prevft = self.newft
self.fps = int(self.fps) self.fps = int(self.fps)
@ -182,8 +159,6 @@ class Camera:
self.fl.pop(0) self.fl.pop(0)
self.fl.append(self.fps) self.fl.append(self.fps)
self.fps = sum(self.fl) / len(self.fl) self.fps = sum(self.fl) / len(self.fl)
else:
self.fps = 69
#self.bps = image.nbytes #self.bps = image.nbytes
if should_push: if should_push:
self.push_image_to_queue(image, frame_number, self.fps) self.push_image_to_queue(image, frame_number, self.fps)

View File

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

View File

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