def __init__(self, media):
     self.writer = None
     self.media = media
     self.config = Configuration()
     self.file_name = None
     self.index = 0
     self.compress = 0
class Image_recorder:
    def __init__(self, media):
        self.writer = None
        self.media = media
        self.config = Configuration()
        self.file_name = None
        self.index = 0

    def start(self, shape, path=None, fps=30):
        # TODO manage multiple record
        # manage only one record at time
        if self.writer:
            self.stop()

        if not path:
            path = "%s" % (self.config.get_path_save_record())
            if not path:
                path = "./"
        elif "/" not in path:
            path = "%s%s" % (self.config.get_path_save_record(), path)

        if os.path.isfile(path):
            log.print_function(logger.error, "File already exist %s" % path)
            return False

        if not os.path.isdir(path):
            try:
                os.makedirs(path)
            except:
                pass

        self.file_name = path
        logger.info("Start record on path: %s", path)

        self.media.add_observer(self.write)
        self.writer = self.write
        return True

    def next_filename(self):
        path = os.path.join(self.file_name, str(self.index).zfill(10) + '.png')
        self.index += 1
        return path

    def write(self, image):
        cv2.imwrite(self.next_filename(), image)

    def get_file_name(self):
        if not self.file_name:
            return ""
        return self.file_name

    def stop(self):
        logger.info("Close record on path: %s", self.file_name)
        self.file_name = None
        if not self.writer:
            return False
        self.media.remove_observer(self.write)
        self.writer = None
        return True
 def __init__(self, media):
     self.writer = None
     self.media = media
     self.config = Configuration()
     self.file_name = None
     self.process = None
     # create a semaphore to protect when closing ffmpeg
     self.sem = Semaphore(1)
Exemple #4
0
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(ImageGenerator, self).__init__()
        self.media_name = config.name
        self.run = True
        self._is_opened = True

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
Exemple #5
0
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self._is_opened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
Exemple #6
0
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(PygameCam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        self.thread_image = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self._is_opened = True
        self.image = None
Exemple #7
0
    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(Firewire, self).__init__()
        self.config = Configuration()
        self.camera = None
        self.is_streaming = False
        self.loop_try_open_camera = False
        self.call_stop = False
        self.sem_closed = threading.Semaphore()

        self.cam_guid = config.guid
        self.cam_no = config.no
        # the id is guid or no, writing into open_camera
        self.id = ""
        self.key_auto_param = "-auto"
        self.reference_param = {"power": self._power,
                                "transmission": self._transmission}

        fps = 15
        self.sleep_time = 1 / 15.0
        self.media_name = config.name
        self.last_timestamp = -1
        self.actual_timestamp = -1
        self.count_not_receive = 0
        self.max_not_receive = fps * 2
        self.buffer_last_timestamp = False
        self.own_config = config
        self.is_rgb = config.is_rgb
        self.is_mono = config.is_mono
        self.is_format_7 = config.is_format7
        self.is_yuv = config.is_yuv
        self.actual_image = None
        self.shape = (800, 600)
        self.count_no_image = 0
        self.max_no_image = 120

        self.lst_param_shutter = []
        self.lst_param_whitebalance = []

        if not self.try_open_camera(repeat_loop=3, sleep_time=1):
            return

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
        self.update_all_property()
Exemple #8
0
    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(IPC, self).__init__()
        self.config = Configuration()
        self.own_config = config
        self.media_name = config.name
        if config.device:
            self.device_name = config.device
        else:
            self.device_name = "/tmp/seagoatvision_media.ipc"
        self._is_opened = True
        self.run = True
        self.video = None

        self.context = zmq.Context()
        self.subscriber = None
        self.message = None

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(ImageGenerator, self).__init__()
        self.media_name = config.name
        self.run = True
        self._is_opened = True

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Pygame_cam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self.isOpened = True
        self.image = None
Exemple #11
0
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self._is_opened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(Firewire, self).__init__()
        self.config = Configuration()
        self.camera = None
        self.is_streaming = False
        self.loop_try_open_camera = False
        self.dct_params = {}
        self.call_stop = False
        # TODO: this is an hack that cause memory leak
        self.lst_garbage_camera = []

        self.cam_guid = config.guid
        self.cam_no = config.no
        # the id is guid or no, writing into open_camera
        self.id = ""
        self.key_auto_param = "-auto"

        fps = 15
        self.sleep_time = 1 / 15.0
        self.media_name = config.name
        self.last_timestamp = -1
        self.actual_timestamp = -1
        self.count_not_receive = 0
        self.max_not_receive = fps * 2
        self.buffer_last_timestamp = False
        self.own_config = config
        self.is_rgb = config.is_rgb
        self.is_mono = config.is_mono
        self.is_format_7 = config.is_format7
        self.is_yuv = config.is_yuv
        self.actual_image = None
        self.shape = (800, 600)
        self.count_no_image = 0
        self.max_no_image = 60

        if not self.try_open_camera(repeat_loop=3, sleep_time=1):
            return

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
        self.update_all_property()
class ImageRecorder:

    def __init__(self, media):
        self.writer = None
        self.media = media
        self.config = Configuration()
        self.file_name = None
        self.index = 0
        self.compress = 0

    def start(self, shape, path=None, fps=30, compress=0):
        # TODO manage multiple record
        # manage only one record at time
        if self.writer:
            self.stop()

        if not path:
            path = "%s" % (self.config.get_path_save_record())
            if not path:
                path = "./"
        elif "/" not in path:
            path = "%s%s" % (self.config.get_path_save_record(), path)

        if os.path.isfile(path):
            log.print_function(logger.error, "File already exist %s" % path)
            return False

        self.compress = compress

        if not os.path.isdir(path):
            try:
                os.makedirs(path)
            except:
                pass

        self.file_name = path
        logger.info("Start record on path: %s", path)

        self.media.add_observer(self.write)
        self.writer = self.write
        return True

    def next_filename(self):
        path = os.path.join(self.file_name, str(self.index).zfill(10) + '.png')
        self.index += 1
        return path

    def write(self, image):
        compress = int(self.compress * 0.09)
        params = [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, compress]
        cv2.imwrite(self.next_filename(), image, params)

    def get_file_name(self):
        if not self.file_name:
            return ""
        return self.file_name

    def stop(self):
        logger.info("Close record on path: %s", self.file_name)
        self.file_name = None
        if not self.writer:
            return False
        self.media.remove_observer(self.write)
        self.writer = None
        return True
#! /usr/bin/env python

#    Copyright (C) 2012  Octets - octets.etsmtl.ca
#
#    This filename is part of SeaGoatVision.
#
#    SeaGoatVision is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

from SeaGoatVision.server.core.configuration import Configuration
config = Configuration()

if config.get_is_show_public_filter():
    from public import *
from private import *
Exemple #15
0
class Webcam(MediaStreaming):
    """Return images from the webcam."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self._is_opened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        self.dct_params = {}

        default_resolution_name = "800x600"
        self.dct_resolution = {default_resolution_name: (800, 600),
                               "320x240": (320, 240),
                               "640x480": (640, 480),
                               "1024x768": (1024, 768),
                               "1280x960": (1280, 960),
                               "1280x1024": (1280, 1024)}
        self.param_resolution = Param(
            "resolution",
            default_resolution_name,
            lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps", default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]

            # TODO check argument video capture
            self.video = cv2.VideoCapture(self.own_config.no)
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, shape[0])
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, shape[1])
            self.video.set(cv2.cv.CV_CAP_PROP_FPS, fps)
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" %
                (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def next(self):
        run, image = self.video.read()
        if not run:
            raise StopIteration
        return image

    def close(self):
        MediaStreaming.close(self)
        if self.video:
            self.video.release()
        self._is_opened = False
        return True
Exemple #16
0
class PygameCam(MediaStreaming):
    """Return images from the webcam."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(PygameCam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        self.thread_image = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self._is_opened = True
        self.image = None

    def _create_params(self):
        default_resolution_name = "800x600"
        self.dct_resolution = {default_resolution_name: (800, 600),
                               "320x240": (320, 240),
                               "640x480": (640, 480),
                               "1024x768": (1024, 768),
                               "1280x960": (1280, 960),
                               "1280x1024": (1280, 1024)}
        self.param_resolution = Param(
            "resolution",
            default_resolution_name,
            lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps", default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[
                self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]
            self.video = pygame.camera.Camera(self.own_config.path, shape)
            self.video.start()
            self.thread_image = True
            thread.start_new_thread(self.update_image, ())
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" %
                (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def update_image(self):
        while self.thread_image:
            image_surface = self.video.get_image()
            image = pygame.surfarray.pixels3d(image_surface)
            image = np.rot90(image, 3)
            copy_image = np.zeros(image.shape, np.float32)
            copy_image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB, copy_image)
            self.image = copy_image

    def next(self):
        return self.image

    def close(self):
        MediaStreaming.close(self)
        self.thread_image = False
        # TODO add semaphore?
        self.video.stop()
        self._is_opened = False
        return True
Exemple #17
0
class IPC(MediaStreaming):
    """
    Return image from IPC socket with ZeroMQ
    This media is a subscriber of ZeroMQ
    """
    key_ipc_name = "ipc name"

    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(IPC, self).__init__()
        self.config = Configuration()
        self.own_config = config
        self.media_name = config.name
        if config.device:
            self.device_name = config.device
        else:
            self.device_name = "/tmp/seagoatvision_media.ipc"
        self._is_opened = True
        self.run = True
        self.video = None

        self.context = zmq.Context()
        self.subscriber = None
        self.message = None

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        default_ipc_name = "ipc://%s" % self.device_name
        self.param_ipc_name = Param(self.key_ipc_name, default_ipc_name)
        self.param_ipc_name.add_notify(self.reload)

    def open(self):
        self.subscriber = self.context.socket(zmq.SUB)
        self.subscriber.setsockopt(zmq.SUBSCRIBE, b'')
        device_name = self.param_ipc_name.get()
        logger.info("Open media device %s" % device_name)
        self.subscriber.connect(device_name)
        thread.start_new_thread(self.fill_message, tuple())
        # call open when video is ready
        return MediaStreaming.open(self)

    def next(self):
        if not self.subscriber or not self.message:
            return
        image = None
        message = self.message[:]
        self.message = None
        lst_pixel = list(bytearray(message))
        # the first 2 bytes is width of image
        len_message = len(lst_pixel) - 2
        if len_message:
            width = (lst_pixel[0] << 8) + lst_pixel[1]
            if not width:
                return
            image = np.array(lst_pixel[2:])
            # check if missing pixel and replace by zero
            diff = len_message % width
            if diff:
                image += [0] * (width - diff)
            image = image.reshape((-1, width))
        shape = image.shape
        if len(shape) < 3 or 3 > shape[2]:
            # convert in 3 depth, bgr picture
            image_float = np.array(image, dtype=np.float32)
            vis2 = cv2.cvtColor(image_float, cv2.COLOR_GRAY2BGR)
            image = np.array(vis2, dtype=np.uint8)
        return image

    def close(self):
        MediaStreaming.close(self)
        # TODO need to debug, closing socket create errors and \
        # context.term freeze
        # self.subscriber.close()
        # self.context.term()
        self.subscriber = None
        return True

    def fill_message(self):
        try:
            while self.subscriber:
                self.message = self.subscriber.recv()
        except zmq.ContextTerminated:
            pass
        finally:
            self.message = None
class Pygame_cam(Media_streaming):
    """Return images from the webcam."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Pygame_cam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self.isOpened = True
        self.image = None

    def _create_params(self):
        self.dct_params = {}

        default_resolution_name = "800x600"
        self.dct_resolution = {default_resolution_name:(800, 600),
                               "320x240":(320, 240),
                               "640x480":(640, 480),
                               "1024x768":(1024, 768),
                               "1280x960":(1280, 960)}
        param = Param("resolution", default_resolution_name, lst_value=self.dct_resolution.keys())
        param.add_notify_reset(self.reset_property_param)
        self.dct_params["resolution"] = param

        default_fps_name = "30"
        self.dct_fps = {default_fps_name:30, "15":15, "7.5":7.5}
        param = Param("fps", default_fps_name, lst_value=self.dct_fps.keys())
        param.add_notify_reset(self.reset_property_param)
        self.dct_params["fps"] = param

    def serialize(self):
        return {"resolution":self.dct_params.get("resolution").get(), "fps":self.dct_params.get("fps").get()}

    def deserialize(self, data):
        if not data:
            return False
        if type(data) is not dict:
            log.print_function(logger.error, "Wrong format data, suppose to be dict into camera %s" % self.get_name())
            return False
        res = data.get("resolution", None)
        if res:
            self.dct_params.get("resolution").set(res)
        res = data.get("fps", None)
        if res:
            self.dct_params.get("fps").set(res)
        return True

    def open(self):
        try:
            shape = self.dct_resolution[self.dct_params.get("resolution").get()]
            fps = self.dct_fps[self.dct_params.get("fps").get()]
            self.video = pygame.camera.Camera(self.own_config.path, shape)
            self.video.start()
            self.thread_image = True
            thread.start_new_thread(self.update_image, ())
        except Exception as e:
            log.printerror_stacktrace(logger, "Open camera %s: %s" % (self.get_name(), e))
            return False
        # call open when video is ready
        return Media_streaming.open(self)

    def update_image(self):
        while self.thread_image:
            image_surface = self.video.get_image()
            image = pygame.surfarray.pixels3d(image_surface)
            image = np.rot90(image, 3)
            copy_image = np.zeros(image.shape, np.float32)
            copy_image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB, copy_image)
            self.image = copy_image

    def next(self):
        return self.image

    def close(self):
        Media_streaming.close(self)
        self.thread_image = False
        # TODO add semaphore?
        self.video.stop()
        self.isOpened = False
        return True

    def get_properties_param(self):
        return self.dct_params.values()

    def update_property_param(self, param_name, value):
        param = self.dct_params.get(param_name, None)
        if not param:
            return False
        param_value = param.get()
        if value == param_value:
            return True
        param.set(value)
        self.reload()
        return True

    def reset_property_param(self, param_name, value):
        self.reload()
        return True
Exemple #19
0
#! /usr/bin/env python

#    Copyright (C) 2012-2014  Octets - octets.etsmtl.ca
#
#    This file is part of SeaGoatVision.
#
#    SeaGoatVision is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

from SeaGoatVision.server.core.configuration import Configuration
config = Configuration()

if config.get_is_show_public_filter():
    from public import *
if config.get_is_show_private_filter():
    from private import *
from SeaGoatVision.commons import log
from SeaGoatVision.server.core.filter import Filter
from SeaGoatVision.server.core.configuration import Configuration
from cpp_code import *
import numpy as np
from python_code import *
import scipy.weave.ext_tools as ext_tools

# import sys
logger = log.get_logger(__name__)

BUILD_DIR = 'build'
RELOAD_DIR = os.path.join('build', 'reload')
has_configure = False
has_destroy = False
config = Configuration()


def import_all_cpp_filter(cppfiles,
                          cpptimestamps,
                          module,
                          file,
                          extra_link_arg=[],
                          extra_compile_arg=[]):
    """
    This method finds and compile every c++ filters
    If a c++ file changed, the file must be recompiled in a new .so file
    """
    # param :
    # module like sys.modules[__name__]
    # file is __file__ from __init__.py
Exemple #21
0
class Webcam(MediaStreaming):
    """Return images from the webcam."""
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self._is_opened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        self.dct_params = {}

        default_resolution_name = "800x600"
        self.dct_resolution = {
            default_resolution_name: (800, 600),
            "320x240": (320, 240),
            "640x480": (640, 480),
            "1024x768": (1024, 768),
            "1280x960": (1280, 960),
            "1280x1024": (1280, 1024)
        }
        self.param_resolution = Param("resolution",
                                      default_resolution_name,
                                      lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps",
                               default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]

            # TODO check argument video capture
            self.video = cv2.VideoCapture(self.own_config.no)
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, shape[0])
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, shape[1])
            self.video.set(cv2.cv.CV_CAP_PROP_FPS, fps)
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" % (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def next(self):
        run, image = self.video.read()
        if not run:
            raise StopIteration
        return image

    def close(self):
        MediaStreaming.close(self)
        if self.video:
            self.video.release()
        self._is_opened = False
        return True
Exemple #22
0
class PygameCam(MediaStreaming):
    """Return images from the webcam."""
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(PygameCam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        self.thread_image = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self._is_opened = True
        self.image = None

    def _create_params(self):
        default_resolution_name = "800x600"
        self.dct_resolution = {
            default_resolution_name: (800, 600),
            "320x240": (320, 240),
            "640x480": (640, 480),
            "1024x768": (1024, 768),
            "1280x960": (1280, 960),
            "1280x1024": (1280, 1024)
        }
        self.param_resolution = Param("resolution",
                                      default_resolution_name,
                                      lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps",
                               default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]
            self.video = pygame.camera.Camera(self.own_config.path, shape)
            self.video.start()
            self.thread_image = True
            thread.start_new_thread(self.update_image, ())
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" % (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def update_image(self):
        while self.thread_image:
            image_surface = self.video.get_image()
            image = pygame.surfarray.pixels3d(image_surface)
            image = np.rot90(image, 3)
            copy_image = np.zeros(image.shape, np.float32)
            copy_image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB, copy_image)
            self.image = copy_image

    def next(self):
        return self.image

    def close(self):
        MediaStreaming.close(self)
        self.thread_image = False
        # TODO add semaphore?
        self.video.stop()
        self._is_opened = False
        return True
class VideoRecorder:
    def __init__(self, media):
        self.writer = None
        self.media = media
        self.config = Configuration()
        self.file_name = None
        self.process = None
        # create a semaphore to protect when closing ffmpeg
        self.sem = Semaphore(1)

    def start(self, shape, path=None, fps=30, compress=0):
        # TODO manage multiple record
        # manage only one record at time
        if self.process:
            self.stop()
        add_format_name = False
        if path:
            # exception, if not contain /, maybe it's just a filename
            if "/" not in path:
                name = "%s%s.avi" % (self.config.get_path_save_record(), path)
            else:
                # TODO need to add extension when giving all path with
                # filename?
                name = path
                if os.path.isdir(path):
                    add_format_name = True
        else:
            add_format_name = True
            # TODO mkdir if directory
            name = self.config.get_path_save_record()
        if add_format_name:
            name += "%s.avi" % time.strftime(
                "%Y_%m_%d_%H_%M_%S",
                time.gmtime())

        if os.path.isfile(name):
            log.print_function(logger.error, "File already exist %s" % name)
            return False

        self.file_name = name
        logger.info("Start record on path: %s", name)

        # 1 is best quality, 36 is worse
        qscale = compress * 0.35 + 1
        self.process = Popen(
            ['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r',
             '24',
             '-i', '-', '-vcodec', 'mpeg4', '-qscale', "%s" % qscale, '-r',
             '24', name], stdin=PIPE)
        self.media.add_observer(self.add_image)
        return True

    def add_image(self, image):
        # take sem with blocking
        self.sem.acquire(True)
        # check if process is active after the sem
        if self.process is None:
            self.sem.release()
            return
        # convert image to rgb in image2
        image2 = np.asarray(image, dtype="uint8")
        cv2.cvtColor(image, cv.CV_BGR2RGB, image2)
        # convert in PIL image
        img = Image.fromarray(image2, 'RGB')
        # Save it in ffmpeg process
        img.save(self.process.stdin, 'JPEG')
        self.sem.release()

    def get_file_name(self):
        return self.file_name if self.file_name else ""

    def stop(self):
        logger.info("Close record on path: %s", self.file_name)
        self.file_name = None
        if not self.process:
            return False
        self.media.remove_observer(self.add_image)
        self.sem.acquire(True)
        self.process.stdin.close()
        self.process.wait()
        self.process = None
        self.sem.release()
        return True
class Firewire(Media_streaming):
    """Return images from a Firewire device."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(Firewire, self).__init__()
        self.config = Configuration()
        self.camera = None
        self.is_streaming = False
        self.loop_try_open_camera = False
        self.dct_params = {}
        self.call_stop = False
        # TODO: this is an hack that cause memory leak
        self.lst_garbage_camera = []

        self.cam_guid = config.guid
        self.cam_no = config.no
        # the id is guid or no, writing into open_camera
        self.id = ""
        self.key_auto_param = "-auto"

        fps = 15
        self.sleep_time = 1 / 15.0
        self.media_name = config.name
        self.last_timestamp = -1
        self.actual_timestamp = -1
        self.count_not_receive = 0
        self.max_not_receive = fps * 2
        self.buffer_last_timestamp = False
        self.own_config = config
        self.is_rgb = config.is_rgb
        self.is_mono = config.is_mono
        self.is_format_7 = config.is_format7
        self.is_yuv = config.is_yuv
        self.actual_image = None
        self.shape = (800, 600)
        self.count_no_image = 0
        self.max_no_image = 60

        if not self.try_open_camera(repeat_loop=3, sleep_time=1):
            return

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
        self.update_all_property()

    def _create_params(self):
        self.dct_params = {}
        if not self.camera:
            return
        lst_ignore_prop = ["Trigger"]
        dct_prop = self.camera.get_dict_available_features()
        for name, value in dct_prop.items():
            if name in lst_ignore_prop:
                continue
            try:
                if name == "White Balance":
                    param = Param("%s%s" % (name, self.key_auto_param), False)
                    param.add_notify_reset(self.update_property_param)
                    self.dct_params[param.get_name()] = param
                    param = Param("%s-red" % name, value["RV_value"], min_v=value["min"], max_v=value["max"])
                    param.add_notify_reset(self.update_property_param)
                    self.dct_params[param.get_name()] = param
                    param = Param("%s-blue" % name, value["BU_value"], min_v=value["min"], max_v=value["max"])
                    param.add_notify_reset(self.update_property_param)
                    self.dct_params[param.get_name()] = param
                    continue
                elif name == "Shutter" or name == "Gain":
                    param = Param("%s%s" % (name, self.key_auto_param), False)
                    param.add_notify_reset(self.update_property_param)
                    self.dct_params[param.get_name()] = param
                param = Param(name, value["value"], min_v=value["min"], max_v=value["max"])
                param.add_notify_reset(self.update_property_param)
                self.dct_params[param.get_name()] = param
            except Exception as e:
                log.printerror_stacktrace(logger, "%s - name: %s, value: %s" % (e, name, value))

    def serialize(self):
        return [param.serialize() for param in self.get_properties_param()]

    def is_opened(self):
        return self.camera is not None

    def deserialize(self, data):
        if not data:
            return False
        for uno_data in data:
            if not uno_data:
                continue
            try:
                param = Param(None, None, serialize=uno_data)
                own_param = self.dct_params.get(param.get_name(), None)
                if own_param:
                    own_param.merge(param)
            except Exception as e:
                log.printerror_stacktrace(logger, e)
                return False
        return True

    def initialize(self):
        logger.debug("initialize camera %s" % self.get_name())
        if not self.camera:
            return False
        try:
            self.camera.initialize(reset_bus=True,
                               mode=self.own_config.mode,
                               framerate=self.own_config.framerate,
                               iso_speed=self.own_config.iso_speed,
                               operation_mode=self.own_config.operation_mode
                               )
        except:
            return False
        return True

    def try_open_camera(self, open_streaming=False, repeat_loop= -1, sleep_time=1):
        # param :
        # int repeat_loop - if -1, it's an infinite loop, else it's the number loop
        # bool open_streaming - if true, try to start the streaming of seagoat and the firewire
        # can be use in threading or in init

        self.loop_try_open_camera = True
        while self.loop_try_open_camera:
            # need to wait 1 second if camera just shutdown, else it's crash
            time.sleep(sleep_time)
            if self.call_stop:
                return False
            # check if can access to the camera
            if self.open_camera():
                if self.initialize():
                    if open_streaming:
                        if self.open():
                            logger.debug("Open with success %s" % self.get_name())
                            self.loop_try_open_camera = False
                            return True
                    else:
                        logger.debug("Finish with initialize")
                        self.loop_try_open_camera = False
                        return True
            # check if need to continue the loop
            if not repeat_loop:
                self.loop_try_open_camera = False
                return False
            if repeat_loop > 0:
                repeat_loop -= 1
            log.print_function(logger.error, "Cannot open the camera %s" % self.get_name())

    def open_camera(self):
        logger.debug("open camera %s" % self.get_name())
        try:
            ctx = video1394.DC1394Context()
        except:
            log.print_function(logger.error, "Libdc1394 is not supported.")
            return False

        if self.cam_guid:
            self.camera = ctx.createCamera(guid=self.cam_guid)
            self.id = "guid %s" % str(self.cam_guid)
        else:
            self.camera = ctx.createCamera(cid=self.cam_no)
            self.id = "no %s" % str(self.cam_no)

        if self.camera is not None:
            return True
        else:
            log.print_function(logger.warning, "No Firewire camera detected - %s." % self.id)
        return False

    def open(self):
        logger.debug("open firewire %s" % self.get_name())
        self.call_stop = False
        if not self.camera:
            # try to open the camera
            # caution, can cause an infinite loop
            return self.try_open_camera(repeat_loop=3, open_streaming=True, sleep_time=1)

        self.camera.initEvent.addObserver(self.camera_init)
        self.camera.grabEvent.addObserver(self.camera_observer)
        self.camera.stopEvent.addObserver(self.camera_close)
        try:
            logger.debug("camera %s start." % self.get_name())
            self.camera.start(force_rgb8=True)
            logger.debug("camera %s start terminated." % self.get_name())
        except:
            self.camera.stop()
            self.lst_garbage_camera.append(self.camera)
            # something crash, restart the camera
            return self.try_open_camera(repeat_loop=1, open_streaming=True, sleep_time=1)
        return True

    def camera_init(self):
        Media_streaming.open(self)
        self.is_streaming = True

    def camera_observer(self, im, timestamp):
        if self.is_rgb or not self.is_mono:
            image = Image.fromarray(im, "RGB")
            image2 = np.asarray(image, dtype="uint8")
            # transform it to BGR
            cv2.cvtColor(np.copy(image), cv.CV_BGR2RGB, image2)
        elif self.is_mono:
            image2 = im
        self.actual_image = image2
        self.last_timestamp = timestamp

    def camera_close(self):
        if not self.camera or not self.is_streaming:
            # we already close the camera
            return
        # anormal close, do something!
        logger.error("Receive events camera close %s, retry to reopen it." % (self.id))
        # clean camera
        self.camera.grabEvent.removeObserver(self.camera_observer)
        self.camera.stopEvent.removeObserver(self.camera_close)
        # TODO: hack, always keep a reference to the camera
        self.lst_garbage_camera.append(self.camera)
        self.camera = None
        self.actual_image = None
        self.is_streaming = False
        # reopen the camera
        kwargs = {"open_streaming" : True}
        # TODO how using kwargs???
        thread.start_new_thread(self.try_open_camera, (True,))

    def get_properties_param(self):
        return self.dct_params.values()

    def update_all_property(self):
        # If property is auto, don't apply manual parameter
        lst_auto = [value[:-(len(self.key_auto_param))]
                    for value in self.dct_params.keys()
                    if self.key_auto_param in value]
        lst_active_auto = [value for value in lst_auto
                           if self.dct_params["%s%s" % (value, self.key_auto_param)].get()]

        for key, value in self.dct_params.items():
            contain_auto_variable = False
            # search active auto
            for active_key in lst_active_auto:
                if active_key in key:
                    contain_auto_variable = True
                    if self.key_auto_param in key:
                        self.update_property_param(key, value.get(), update_object_param=False)
            if contain_auto_variable:
                continue
            # find auto key disable and cancel it
            if self.key_auto_param in key:
                continue
            self.update_property_param(key, value.get(), update_object_param=False)

    def update_property_param(self, param_name, value, update_object_param=True):
        if not self.camera:
            return False

        if update_object_param:
            self.dct_params[param_name].set(value)

        logger.debug("Camera %s param_name %s and value %s", self.get_name(), param_name, value)
        if self.key_auto_param in param_name:
            new_param_name = param_name[:-len(self.key_auto_param)]
            self.camera.set_property_auto(new_param_name, value)
        elif "White Balance" in param_name:
            if "red" in param_name:
                self.camera.set_whitebalance(RV_value=value)
            elif "blue" in param_name:
                self.camera.set_whitebalance(BU_value=value)
            else:
                log.print_function(logger.error, "Can define the right color %s" % param_name)
                return False
        else:
            self.camera.set_property(param_name, value)
        return True

    def next(self):
        if not self.camera or not self.is_streaming:
            return None

        diff_time = self.last_timestamp - self.actual_timestamp
        # logger.debug("actual time %s, last time %s, diff %s" % (self.actual_timestamp, self.last_timestamp, diff_time))
        self.actual_timestamp = self.last_timestamp
        if self.last_timestamp == -1:
            if not self.buffer_last_timestamp:
                self.buffer_last_timestamp = True
                return None
            log.print_function(logger.warning, "No image receive from %s" % (self.get_name()))
            self.count_no_image += 1
            if self.count_no_image > self.max_no_image:
                self.count_no_image = 0
                self.camera_close()
            return None
        if not diff_time:
            self.count_not_receive += 1
            if self.count_not_receive >= self.max_not_receive:
                # logger.error("Didn't receive since %d images. Restart the camera %s??" % (self.count_not_receive, self.id))
                logger.error("Didn't receive since %d images on camera %s" % (self.count_not_receive, self.get_name()))
                self.actual_timestamp = self.last_timestamp = -1
                self.count_not_receive = 0
            # ignore if only missing one image
            if not self.buffer_last_timestamp:
                self.buffer_last_timestamp = True
                return self.actual_image
            else:
                logger.warning("Receive no more image from %s, timestamp %d" % (self.get_name(), self.actual_timestamp))
                return None
        # reinitilize all protection
        self.buffer_last_timestamp = False
        self.count_no_image = 0
        self.count_not_receive = 0
        return self.actual_image

    def close(self):
        # Only the manager can call this close or the reload on media.py
        Media_streaming.close(self)
        self.call_stop = True
        self.loop_try_open_camera = False
        self.is_streaming = False
        if self.camera:
            self.camera.stop()
            self.camera.initEvent.removeObserver(self.camera_init)
            self.camera.grabEvent.removeObserver(self.camera_observer)
            self.camera.stopEvent.removeObserver(self.camera_close)
            # TODO: hack, always keep a reference to the camera
            self.lst_garbage_camera.append(self.camera)
            self.camera = None
            return True
        else:
            logger.warning("Camera %s already close." % self.get_name())
        return False
Exemple #25
0
class ImageGenerator(MediaStreaming):
    """Return a generate image."""
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(ImageGenerator, self).__init__()
        self.media_name = config.name
        self.run = True
        self._is_opened = True

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        default_width = 800
        self.param_width = Param("width", default_width, min_v=1, max_v=1200)
        self.param_width.add_group("Resolution")
        self.param_width.set_description("Change width resolution.")

        default_height = 600
        self.param_height = Param("height",
                                  default_height,
                                  min_v=1,
                                  max_v=1200)
        self.param_height.add_group("Resolution")
        self.param_height.set_description("Change height resolution.")

        default_fps = 30
        self.param_fps = Param("fps", default_fps, min_v=1, max_v=100)
        self.param_fps.set_description("Change frame per second.")

        self.param_color_r = Param("color_r", 0, min_v=0, max_v=255)
        self.param_color_r.add_group("Color")
        self.param_color_r.set_description("Change red color.")

        self.param_color_g = Param("color_g", 0, min_v=0, max_v=255)
        self.param_color_g.add_group("Color")
        self.param_color_g.set_description("Change green color.")

        self.param_color_b = Param("color_b", 0, min_v=0, max_v=255)
        self.param_color_b.add_group("Color")
        self.param_color_b.set_description("Change blue color.")

        self.param_auto_color = Param("auto-change-color", False)
        self.param_auto_color.set_description(
            "Change the color automatically.")
        self.param_auto_color.add_group("Color")

        self.param_random_green = Param("pooling_green_random", False)
        self.param_random_green.set_description(
            "Active pooling update of green color with random value.")
        self.param_random_green.add_notify(self._active_green_pooling)
        self.param_random_green.add_group("Color")

        self.param_transpose_r_color = Param("Transpose red color", None)
        self.param_transpose_r_color.set_description(
            "Copy the red color on others color.")
        self.param_transpose_r_color.add_notify(self._transpose_red_color)
        self.param_transpose_r_color.add_group("Color")

        self.param_freeze = Param("freeze", False)
        self.param_freeze.set_description("Freeze the stream.")

    def next(self):
        if self.param_freeze.get():
            return

        width = self.param_width.get()
        height = self.param_height.get()
        color_r = self.param_color_r.get()
        color_g = self.param_color_g.get()
        color_b = self.param_color_b.get()

        if self.param_auto_color.get():
            color_r += 1
            if color_r > 255:
                color_r = 0
            color_g += 2
            if color_g > 255:
                color_g = 0
            color_b += 3
            if color_b > 255:
                color_b = 0

            self.param_color_r.set(color_r)
            self.param_color_r.set_lock(True)
            self.param_color_g.set(color_g)
            self.param_color_g.set_lock(True)
            self.param_color_b.set(color_b)
            self.param_color_b.set_lock(True)
        else:
            self.param_color_r.set_lock(False)
            self.param_color_g.set_lock(False)
            self.param_color_b.set_lock(False)

        image = np.zeros((height, width, 3), dtype=np.uint8)

        image[:, :, 0] += color_b
        image[:, :, 1] += color_g
        image[:, :, 2] += color_r
        return image

    def _transpose_red_color(self, param):
        color_r = self.param_color_r.get()
        self.param_color_g.set(color_r)
        self.param_color_b.set(color_r)

    def _active_green_pooling(self, param):
        if param.get():
            self.param_color_g.start_pooling(self._pool_random_green)
        else:
            self.param_color_g.stop_pooling()

    def _pool_random_green(self, param):
        return randrange(255)
class Video_recorder:
    def __init__(self, media):
        self.writer = None
        self.media = media
        self.config = Configuration()
        self.file_name = None

    def start(self, shape, path=None, fps=30):
        # TODO manage multiple record
        # manage only one record at time
        if self.writer:
            self.stop()
        add_format_name = False
        if path:
            # exception, if not contain /, maybe it's just a filename
            if "/" not in path:
                name = "%s%s.avi" % (self.config.get_path_save_record(), path)
            else:
                # TODO need to add extension when giving all path with filename?
                name = path
                if os.path.isdir(path):
                    add_format_name = True
        else:
            add_format_name = True
            # TODO mkdir if directory
            name =  self.config.get_path_save_record()
        if add_format_name:
            name += "%s.avi" % time.strftime("%Y_%m_%d_%H_%M_%S", time.gmtime())

        if os.path.isfile(name):
            log.print_function(logger.error, "File already exist %s" % name)
            return False

        self.file_name = name
        logger.info("Start record on path: %s", name)

        fps = 8
        # fourcc = cv.CV_FOURCC('D','I','V','X')
        # fourcc = cv.CV_FOURCC('F', 'L', 'V', '1')
        # fourcc = cv.CV_FOURCC('V', 'P', '8', '0') # not work
        # fourcc = cv.CV_FOURCC('M', 'J', 'P', 'G')
        # fourcc = cv.CV_FOURCC('D', 'I', 'B', ' ')  # Uncompressed RGB, 24 or 32 bit  - not working linux
        fourcc = cv.CV_FOURCC('I', 'Y', 'U', 'V')  # Uncompressed YUV, 4:2:0 chroma subsampled , same of 'I420'
        self.writer = cv2.VideoWriter(filename=name, fourcc=fourcc, fps=fps, frameSize=shape, isColor=1)
        self.writer.open(name, fourcc, fps, shape, 1)
        self.media.add_observer(self.writer.write)
        return True

    def get_file_name(self):
        if not self.file_name:
            return ""
        return self.file_name

    def stop(self):
        logger.info("Close record on path: %s", self.file_name)
        self.file_name = None
        if not self.writer:
            return False
        self.media.remove_observer(self.writer.write)
        del self.writer
        self.writer = None
        return True
class Webcam(Media_streaming):
    """Return images from the webcam."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self.isOpened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        self.dct_params = {}

        default_resolution_name = "800x600"
        self.dct_resolution = {default_resolution_name:(800, 600),
                               "320x240":(320, 240),
                               "640x480":(640, 480),
                               "1024x768":(1024, 768),
                               "1280x960":(1280, 960)}
        param = Param("resolution", default_resolution_name, lst_value=self.dct_resolution.keys())
        param.add_notify_reset(self.reset_property_param)
        self.dct_params["resolution"] = param

        default_fps_name = "30"
        self.dct_fps = {default_fps_name:30, "15":15, "7.5":7.5}
        param = Param("fps", default_fps_name, lst_value=self.dct_fps.keys())
        param.add_notify_reset(self.reset_property_param)
        self.dct_params["fps"] = param

    def serialize(self):
        return {"resolution":self.dct_params.get("resolution").get(), "fps":self.dct_params.get("fps").get()}

    def deserialize(self, data):
        if not data:
            return False
        if type(data) is not dict:
            log.print_function(logger.error, "Wrong format data, suppose to be dict into camera %s" % self.get_name())
            return False
        res = data.get("resolution", None)
        if res:
            self.dct_params.get("resolution").set(res)
        res = data.get("fps", None)
        if res:
            self.dct_params.get("fps").set(res)
        return True

    def open(self):
        try:
            shape = self.dct_resolution[self.dct_params.get("resolution").get()]
            fps = self.dct_fps[self.dct_params.get("fps").get()]

            self.video = cv2.VideoCapture(self.own_config.no)
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, shape[0])
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, shape[1])
            self.video.set(cv2.cv.CV_CAP_PROP_FPS, fps)
        except Exception as e:
            log.printerror_stacktrace(logger, "Open camera %s: %s" % (self.get_name(), e))
            return False
        # call open when video is ready
        return Media_streaming.open(self)

    def next(self):
        run, image = self.video.read()
        if run == False:
            raise StopIteration
        return image

    def close(self):
        Media_streaming.close(self)
        self.video.release()
        self.isOpened = False
        return True

    def get_properties_param(self):
        return self.dct_params.values()

    def update_property_param(self, param_name, value):
        param = self.dct_params.get(param_name, None)
        if not param:
            return False
        param_value = param.get()
        if value == param_value:
            return True
        param.set(value)
        self.reload()
        return True

    def reset_property_param(self, param_name, value):
        self.reload()
        return True
class ImageGenerator(MediaStreaming):
    """Return a generate image."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(ImageGenerator, self).__init__()
        self.media_name = config.name
        self.run = True
        self._is_opened = True

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        default_width = 800
        self.param_width = Param("width", default_width, min_v=1, max_v=1200)
        self.param_width.add_group("Resolution")
        self.param_width.set_description("Change width resolution.")

        default_height = 600
        self.param_height = Param("height", default_height, min_v=1,
                                  max_v=1200)
        self.param_height.add_group("Resolution")
        self.param_height.set_description("Change height resolution.")

        default_fps = 30
        self.param_fps = Param("fps", default_fps, min_v=1, max_v=100)
        self.param_fps.set_description("Change frame per second.")

        self.param_color_r = Param("color_r", 0, min_v=0, max_v=255)
        self.param_color_r.add_group("Color")
        self.param_color_r.set_description("Change red color.")

        self.param_color_g = Param("color_g", 0, min_v=0, max_v=255)
        self.param_color_g.add_group("Color")
        self.param_color_g.set_description("Change green color.")

        self.param_color_b = Param("color_b", 0, min_v=0, max_v=255)
        self.param_color_b.add_group("Color")
        self.param_color_b.set_description("Change blue color.")

        self.param_auto_color = Param("auto-change-color", False)
        self.param_auto_color.set_description(
            "Change the color automatically.")
        self.param_auto_color.add_group("Color")

        self.param_random_green = Param("pooling_green_random", False)
        self.param_random_green.set_description(
            "Active pooling update of green color with random value.")
        self.param_random_green.add_notify(self._active_green_pooling)
        self.param_random_green.add_group("Color")

        self.param_transpose_r_color = Param("Transpose red color", None)
        self.param_transpose_r_color.set_description(
            "Copy the red color on others color.")
        self.param_transpose_r_color.add_notify(self._transpose_red_color)
        self.param_transpose_r_color.add_group("Color")

        self.param_freeze = Param("freeze", False)
        self.param_freeze.set_description("Freeze the stream.")

    def next(self):
        if self.param_freeze.get():
            return

        width = self.param_width.get()
        height = self.param_height.get()
        color_r = self.param_color_r.get()
        color_g = self.param_color_g.get()
        color_b = self.param_color_b.get()

        if self.param_auto_color.get():
            color_r += 1
            if color_r > 255:
                color_r = 0
            color_g += 2
            if color_g > 255:
                color_g = 0
            color_b += 3
            if color_b > 255:
                color_b = 0

            self.param_color_r.set(color_r)
            self.param_color_r.set_lock(True)
            self.param_color_g.set(color_g)
            self.param_color_g.set_lock(True)
            self.param_color_b.set(color_b)
            self.param_color_b.set_lock(True)
        else:
            self.param_color_r.set_lock(False)
            self.param_color_g.set_lock(False)
            self.param_color_b.set_lock(False)

        image = np.zeros((height, width, 3), dtype=np.uint8)

        image[:, :, 0] += color_b
        image[:, :, 1] += color_g
        image[:, :, 2] += color_r
        return image

    def _transpose_red_color(self, param):
        color_r = self.param_color_r.get()
        self.param_color_g.set(color_r)
        self.param_color_b.set(color_r)

    def _active_green_pooling(self, param):
        if param.get():
            self.param_color_g.start_pooling(self._pool_random_green)
        else:
            self.param_color_g.stop_pooling()

    def _pool_random_green(self, param):
        return randrange(255)
Exemple #29
0
class Firewire(MediaStreaming):
    """Return images from a Firewire device."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(Firewire, self).__init__()
        self.config = Configuration()
        self.camera = None
        self.is_streaming = False
        self.loop_try_open_camera = False
        self.call_stop = False
        self.sem_closed = threading.Semaphore()

        self.cam_guid = config.guid
        self.cam_no = config.no
        # the id is guid or no, writing into open_camera
        self.id = ""
        self.key_auto_param = "-auto"
        self.reference_param = {"power": self._power,
                                "transmission": self._transmission}

        fps = 15
        self.sleep_time = 1 / 15.0
        self.media_name = config.name
        self.last_timestamp = -1
        self.actual_timestamp = -1
        self.count_not_receive = 0
        self.max_not_receive = fps * 2
        self.buffer_last_timestamp = False
        self.own_config = config
        self.is_rgb = config.is_rgb
        self.is_mono = config.is_mono
        self.is_format_7 = config.is_format7
        self.is_yuv = config.is_yuv
        self.actual_image = None
        self.shape = (800, 600)
        self.count_no_image = 0
        self.max_no_image = 120

        self.lst_param_shutter = []
        self.lst_param_whitebalance = []

        if not self.try_open_camera(repeat_loop=3, sleep_time=1):
            return

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))
        self.update_all_property()

    def is_opened(self):
        return self.camera is not None

    def initialize(self):
        logger.debug("initialize camera %s" % self.get_name())
        if not self.camera:
            return False
        try:
            init = self.camera.initialize
            init(reset_bus=True, mode=self.own_config.mode,
                 framerate=self.own_config.framerate,
                 iso_speed=self.own_config.iso_speed,
                 operation_mode=self.own_config.operation_mode)
        except:
            return False
        return True

    def try_open_camera(
            self, open_streaming=False, repeat_loop=-1, sleep_time=1):
        # param :
        # int repeat_loop - if -1, it's an infinite loop, \
        # else it's the number loop
        # bool open_streaming - if true, try to start the streaming \
        # of seagoat and the firewire
        # can be use in threading or in init

        self.loop_try_open_camera = True
        while self.loop_try_open_camera:
            # need to wait 1 second if camera just shutdown, else it's crash
            time.sleep(sleep_time)
            if self.call_stop:
                return False
            # check if can access to the camera
            if self.open_camera():
                time.sleep(2)
                if self.initialize():
                    time.sleep(2)
                    if open_streaming:
                        time.sleep(2)
                        if self.open():
                            logger.debug(
                                "Open with success %s" %
                                self.get_name())
                            self.loop_try_open_camera = False
                            return True
                    else:
                        logger.debug("Finish with initialize")
                        self.loop_try_open_camera = False
                        return True
            # check if need to continue the loop
            if not repeat_loop:
                self.loop_try_open_camera = False
                return False
            if repeat_loop > 0:
                repeat_loop -= 1
            log.print_function(
                logger.error, "Cannot open the camera %s" %
                self.get_name())

    def open_camera(self):
        logger.debug("open camera %s" % self.get_name())
        try:
            ctx = video1394.DC1394Context()
        except:
            log.print_function(logger.error, "Libdc1394 is not supported.")
            return False

        if self.cam_guid:
            self.camera = ctx.createCamera(guid=self.cam_guid)
            self.id = "guid %s" % str(self.cam_guid)
        else:
            self.camera = ctx.createCamera(cid=self.cam_no)
            self.id = "no %s" % str(self.cam_no)

        if self.camera is not None:
            return True
        else:
            log.print_function(
                logger.warning,
                "No Firewire camera detected - %s." %
                self.id)
        return False

    def open(self):
        logger.debug("open firewire %s" % self.get_name())
        self.call_stop = False
        if not self.camera:
            # try to open the camera
            # caution, can cause an infinite loop
            return self.try_open_camera(repeat_loop=3, open_streaming=True,
                                        sleep_time=1)

        self.camera.initEvent.addObserver(self.camera_init)
        self.camera.grabEvent.addObserver(self.camera_observer)
        # self.camera.stopEvent.addObserver(self.camera_closed)
        try:
            logger.debug("camera %s start." % self.get_name())
            self.camera.start(force_rgb8=True)
            self.param_transmission.set(True)
            logger.debug("camera %s start terminated." % self.get_name())
        except BaseException as e:
            logger.error(e)
            self.camera.stop()
            # something crash, restart the camera
            return self.try_open_camera(repeat_loop=1, open_streaming=True,
                                        sleep_time=1)
        return True

    def camera_init(self):
        MediaStreaming.open(self)
        self.is_streaming = True

    def camera_observer(self, im, timestamp):
        if self.is_rgb or not self.is_mono:
            image = Image.fromarray(im, "RGB")
            image2 = np.asarray(image, dtype="uint8")
            # transform it to BGR
            cv2.cvtColor(np.copy(image), cv.CV_BGR2RGB, image2)
        elif self.is_mono:
            image2 = im
        self.actual_image = image2
        self.last_timestamp = timestamp

    def camera_closed(self):
        self.sem_closed.acquire()
        if not self.camera or not self.is_streaming:
            # we already close the camera
            return
        # anormal close, do something!
        logger.error(
            "Receive events camera close %s, retry to reopen it." % self.id)
        # clean camera
        self.camera.grabEvent.removeObserver(self.camera_observer)
        # self.camera.stopEvent.removeObserver(self.camera_closed)
        self.actual_image = None
        # self.camera.safe_clean(free_camera=False)
        self.camera = None
        self.is_streaming = False
        # reopen the camera
        kwargs = {"open_streaming": True}
        # TODO how using kwargs???
        if not self.call_stop:
            thread.start_new_thread(self.try_open_camera, (True,))
            time.sleep(2)
        self.sem_closed.release()

    def next(self):
        if not self.camera or not self.is_streaming:
            return

        diff_time = self.last_timestamp - self.actual_timestamp
        # logger.debug("actual time %s, last time %s, diff %s" %
        # (self.actual_timestamp, self.last_timestamp, diff_time))
        self.actual_timestamp = self.last_timestamp
        if self.last_timestamp == -1:
            if not self.buffer_last_timestamp:
                self.buffer_last_timestamp = True
                return
                log.print_function(
                    logger.warning,
                    "No image receive from %s" % self.get_name())
            self.count_no_image += 1
            if self.count_no_image > self.max_no_image:
                self.count_no_image = 0
                self.camera_closed()
            return
        if not diff_time:
            self.count_not_receive += 1
            if self.count_not_receive >= self.max_not_receive:
                # logger.error("Didn't receive since %d images. Restart the
                # camera %s??" % (self.count_not_receive, self.id))
                logger.error(
                    "Didn't receive since %d images on camera %s" %
                    (self.count_not_receive, self.get_name()))
                self.actual_timestamp = self.last_timestamp = -1
                self.count_not_receive = 0
            # ignore if only missing one image
            if not self.buffer_last_timestamp:
                self.buffer_last_timestamp = True
                return self.actual_image
            else:
                # logger.warning(
                #    "Receive no more image from %s, timestamp %d" %
                #    (self.get_name(), self.actual_timestamp))
                return
        # reinitilize all protection
        self.buffer_last_timestamp = False
        self.count_no_image = 0
        self.count_not_receive = 0
        return self.actual_image

    def close(self):
        # Only the manager can call this close or the reload on media.py
        MediaStreaming.close(self)
        self.call_stop = True
        self.loop_try_open_camera = False
        self.is_streaming = False
        if self.camera:
            self.param_transmission.set(False)
            self.camera.stop()
            self.camera.initEvent.removeObserver(self.camera_init)
            self.camera.grabEvent.removeObserver(self.camera_observer)
            # self.camera.stopEvent.removeObserver(self.camera_closed)
            self.camera.safe_clean()
            self.camera = None
            return True
        else:
            logger.warning("Camera %s already close." % self.get_name())
        return False

    # PARAMS

    def _create_params(self):
        if not self.camera:
            return
        group_name_color = "Color"
        group_name_shutter = "Shutter"
        lst_ignore_prop = ["Trigger"]
        dct_prop = self.camera.get_dict_available_features()
        for name, value in dct_prop.items():
            if name in lst_ignore_prop:
                continue
            try:
                if name == "White Balance":
                    # add auto white balance
                    param = Param("%s%s" % (name, self.key_auto_param), False)
                    param.add_notify(self.update_property_param)
                    param.add_group(group_name_color)
                    param.add_notify(self._trig_auto_whitebalance)
                    self.add_param(param)
                    # add specific color of white balance
                    param = Param(
                        "RV_value",
                        value["RV_value"],
                        min_v=value["min"],
                        max_v=value["max"])
                    param.set_description("%s-red" % name)
                    param.add_notify(self.update_property_param)
                    param.add_group(group_name_color)
                    self.lst_param_whitebalance.append(param)
                    self.add_param(param)

                    param = Param(
                        "BU_value",
                        value["BU_value"],
                        min_v=value["min"],
                        max_v=value["max"])
                    param.set_description("%s-blue" % name)
                    param.add_notify(self.update_property_param)
                    self.lst_param_whitebalance.append(param)
                    param.add_group(group_name_color)
                    self.add_param(param)
                    continue

                param = Param(
                    name,
                    value["value"],
                    min_v=value["min"],
                    max_v=value["max"])
                param.add_notify(self.update_property_param)
                self.add_param(param)

                if name == "Shutter":
                    self.lst_param_shutter.append(param)
                    param.add_group(group_name_shutter)
                    # add auto param
                    param = Param("%s%s" % (name, self.key_auto_param), False)
                    param.add_notify(self._trig_auto_shutter)
                    param.add_notify(self.update_property_param)
                    param.add_group(group_name_shutter)
                    self.add_param(param)
            except BaseException as e:
                log.printerror_stacktrace(
                    logger, "%s - name: %s, value: %s" % (e, name, value))

        # add operational param
        group_operation = "operation"
        self.param_power = Param("Power", True)
        self.param_power.add_notify(self._power)
        self.param_power.add_group(group_operation)

        self.param_transmission = Param("Transmission", False)
        self.param_transmission.add_notify(self._transmission)
        self.param_transmission.add_group(group_operation)

        self.sync_params()

    def _trig_auto(self, param, lst_param, cb):
        if not self.camera:
            return False
        is_active = bool(param.get())
        for param in lst_param:
            # lock/unlock and start/stop pooling
            param.set_lock(is_active)
            if is_active:
                param.start_pooling(cb)
            else:
                param.stop_pooling()
        return True

    def _trig_auto_shutter(self, param):
        return self._trig_auto(param, self.lst_param_shutter, self._get_cam_property)

    def _trig_auto_whitebalance(self, param):
        return self._trig_auto(param, self.lst_param_whitebalance, self._get_cam_whitebalance_property)

    def _get_cam_property(self, param):
        return self.camera.get_property(param.get_name())

    def _get_cam_whitebalance_property(self, param):
        blue, red = self.camera.get_whitebalance()
        if "RV" in param.get_name():
            return red
        return blue

    def update_all_property(self):
        # If property is auto, don't apply manual parameter
        lst_auto = [value[:-(len(self.key_auto_param))]
                    for value in self.get_params().keys()
                    if self.key_auto_param in value]
        lst_auto = [value for value in lst_auto
                    if self.get_params("%s%s" %
                                       (value, self.key_auto_param)).get()]

        for key, param in self.get_params().items():
            contain_auto_variable = False
            # search active auto
            for active_key in lst_auto:
                if active_key in key:
                    contain_auto_variable = True
                    if self.key_auto_param in key:
                        self.update_property_param(param,
                                                   update_object_param=False)
            if contain_auto_variable:
                continue
            # find auto key disable and cancel it
            if self.key_auto_param in key:
                continue
            self.update_property_param(param, update_object_param=False)

    def update_property_param(self, param, update_object_param=True):
        if not self.camera or param.get_is_lock():
            return False
        param_name = param.get_name()
        value = param.get()

        if update_object_param:
            param.set(value)

        logger.debug(
            "Camera %s param_name %s and value %s",
            self.get_name(),
            param_name,
            value)
        if param_name.lower() in self.reference_param.keys():
            self.reference_param[param_name.lower()](param)
            return True

        if self.key_auto_param in param_name:
            new_param_name = param_name[:-len(self.key_auto_param)]
            self.camera.set_property_auto(new_param_name, value)
        elif "RV" in param_name:
            self.camera.set_whitebalance(RV_value=value)
        elif "BU" in param_name:
            self.camera.set_whitebalance(BU_value=value)
        else:
            self.camera.set_property(param_name, value)
        return True

    def _power(self, param):
        value = param.get()
        self.camera.power = int(bool(value))

    def _transmission(self, param):
        value = param.get()
        self.camera.transmission = int(bool(value))