pyledriver/camera.py

83 lines
2.3 KiB
Python

import cv2, time
from threading import RLock
from sharedLogging import SlaveLogger
from auxilary import freeBusyPath
class Camera:
def __init__(self, queue):
self._lock = RLock()
self._index = 0
self._logger = SlaveLogger(__name__, 'DEBUG', queue)
freeBusyPath('/dev/video{}'.format(self._index), self._logger)
# NOTE: we use 0-255 on forms instead of floats because they look nicer
logitechProperties = {
'FPS': 25, # integer from 10 to 30 in multiples of 5
'BRIGHTNESS': 127/255, # float from 0 to 1
'CONTRAST': 32/255, # float from 0 to 1
'SATURATION': 32/255, # float from 0 to 1
'GAIN': 64/255, # float from 0 to 1
}
self._properties = {}
self.setProps(**logitechProperties)
def getProps(self, *args):
return {prop: self._video.get(getattr(cv2, 'CAP_PROP_' + prop)) for prop in args}
def setProps(self, *args, **kwargs):
# silly hack, need to reset the videoCapture object every time
# we change settings (they can only be changed once apparently)
self._lock.acquire()
try:
if hasattr(self, '_video'):
self._video.release()
self._video = cv2.VideoCapture(self._index)
for prop, val in kwargs.items():
self._properties[prop] = val
self._video.set(getattr(cv2, 'CAP_PROP_' + prop), val)
self._logger.debug('set %s to %s', prop, val)
finally:
self._lock.release()
# the reset code here could be put in seperate thread to accellarate
def getFrame(self):
frame = None
self._lock.acquire()
try:
# will try 3 attempts to grab frame, will reset on failure
i = 3
while i > 0:
if self._video.isOpened():
success, image = self._video.read()
ret, jpeg = cv2.imencode('.jpg', image)
frame = jpeg.tobytes()
break
else:
time.sleep(5)
self.reset()
i -= 1
# after 3 fails return the dummy frame
if not frame:
with open('noimage.jpg', 'rb') as f:
time.sleep(1)
frame = f.read()
finally:
self._lock.release()
return frame
def reset(self):
self.setProps(**self._properties)
self._logger.debug('camera reset')
def __del__(self):
try:
self._video.release()
self._logger.debug('Release camera at index %s', self._index)
except AttributeError:
self._logger.debug('Failed to release camera at index %s', self._index)