83 lines
2.3 KiB
Python
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)
|