Esempio n. 1
0
 def action_about(self, info):
     dialog = AboutDialog(image=find_icon('camera-video', size=64))
     dialog.additions = [
         'Beams 0.1',
         u'© 2010, 2011, 2012 P. F. Chimento',
         'MIT License'
     ]
     dialog.open()
Esempio n. 2
0
 def action_about(self, info):
     dialog = AboutDialog(image=find_icon("camera-video", size=64))
     dialog.additions = ["Beams 0.1", u"© 2010, 2011, 2012 P. F. Chimento", "MIT License"]
     dialog.open()
Esempio n. 3
0
class MainWindow(HasTraits):
    '''The main window for the Beams application.'''

    # Current folder for file dialog
    _current_folder = None

    camera = Instance(Camera)
    id_string = DelegatesTo('camera')
    resolution = DelegatesTo('camera')
    status = Str()
    screen = Instance(CameraImage, args=())
    cmap = DelegatesTo('screen')
    display_frame_rate = Range(1, 60, 15)
    transform_plugins = List(Instance(TransformPlugin))
    display_plugins = List(Instance(DisplayPlugin))
    acquisition_thread = Instance(AcquisitionThread)  # default: None
    processing_thread = Instance(ProcessingThread)  # default: None
    processing_queue = Instance(queue.Queue, kw={'maxsize': MAX_QUEUE_SIZE})
    cameras_dialog = Instance(CameraDialog, args=())

    # Actions
    about = Action(name='&About...',
                   tooltip='About Beams',
                   image=find_icon('about'),
                   action='action_about')
    save = Action(name='&Save Image',
                  accelerator='Ctrl+S',
                  tooltip='Save the current image to a file',
                  image=find_icon('save'),
                  action='action_save')
    quit = Action(name='&Quit',
                  accelerator='Ctrl+Q',
                  tooltip='Exit the application',
                  image=find_icon('quit'),
                  action='_on_close')
    choose_camera = Action(name='Choose &Camera...',
                           tooltip='Choose from a number of camera plugins',
                           action='action_choose_camera')
    take_video = Action(name='Take &Video',
                        style='toggle',
                        tooltip='Start viewing the video feed from the camera',
                        image=find_icon('camera-video'),
                        action='action_take_video')
    take_photo = Action(name='Take &Photo',
                        tooltip='Take one snapshot from the camera',
                        image=find_icon('camera-photo'),
                        action='action_take_photo',
                        enabled_when='self.take_video.checked == False')

    find_resolution = Button()
    view = View(
        VGroup(
            HSplit(
                Tabbed(
                    VGroup(Item('id_string', style='readonly', label='Camera'),
                           Item('resolution',
                                style='readonly',
                                format_str=u'%i \N{multiplication sign} %i'),
                           Group(Item('camera',
                                      show_label=False,
                                      style='custom'),
                                 label='Camera properties',
                                 show_border=True),
                           label='Camera'),
                    VGroup(Item('cmap',
                                label='Color scale',
                                editor=EnumEditor(
                                    values={
                                        None: '0:None (image default)',
                                        gray: '1:Grayscale',
                                        bone: '2:Bone',
                                        pink: '3:Copper',
                                        jet: '4:Rainbow (considered harmful)',
                                        isoluminant: '5:Isoluminant',
                                        awesome: '6:Low-intensity contrast'
                                    })),
                           Item('screen',
                                show_label=False,
                                editor=ColorMapEditor(width=256)),
                           Item('display_frame_rate'),
                           label='Video'),
                    # FIXME: mutable=False means the items can't be deleted,
                    # added, or rearranged, but we do actually want them to
                    # be rearranged.
                    VGroup(Item('transform_plugins',
                                show_label=False,
                                editor=ListEditor(style='custom',
                                                  mutable=False)),
                           label='Transform'),
                    VGroup(Item('display_plugins',
                                show_label=False,
                                editor=ListEditor(style='custom',
                                                  mutable=False)),
                           label='Math')),
                Item('screen',
                     show_label=False,
                     width=640,
                     height=480,
                     style='custom')),
            Item('status', style='readonly', show_label=False)),
        menubar=MenuBar(
            # vertical bar is undocumented but it seems to keep the menu
            # items in the order they were specified in
            Menu('|', save, '_', quit, name='&File'),
            Menu(name='&Edit'),
            Menu(name='&View'),
            Menu('|',
                 choose_camera,
                 '_',
                 take_photo,
                 take_video,
                 name='&Camera'),
            Menu(name='&Math'),
            Menu(about, name='&Help')),
        toolbar=ToolBar('|', save, '_', take_photo, take_video),
        title='Beams',
        resizable=True,
        handler=MainHandler)

    def _find_resolution_fired(self):
        return self.view.handler.action_find_resolution(None)

    def _display_frame_rate_changed(self, value):
        self.processing_thread.update_frequency = value

    def _transform_plugins_default(self):
        plugins = []
        for name in ['Rotator', 'BackgroundSubtract']:
            module = __import__(name, globals(), locals(), [name])
            plugins.append(getattr(module, name)())
        return plugins

    def _display_plugins_default(self):
        plugins = []
        for name in [
                'BeamProfiler', 'MinMaxDisplay', 'DeltaDetector', 'Centroid'
        ]:
            module = __import__(name, globals(), locals(), [name])
            plugins.append(getattr(module, name)(screen=self.screen))
        return plugins

    def __init__(self, **traits):
        super(MainWindow, self).__init__(**traits)

        # Build the camera selection dialog box
        self.cameras_dialog.on_trait_change(self.on_cameras_response, 'closed')
        self.on_cameras_response()

        self.processing_thread = ProcessingThread(self, self.processing_queue,
                                                  self.display_frame_rate)
        self.processing_thread.start()

    def on_cameras_response(self):
        plugin_obj = self.cameras_dialog.get_plugin_object()
        try:
            self.select_plugin(plugin_obj)
        except ImportError:
            # some module was not available, select the dummy
            error(
                None, 'Loading the {} camera plugin failed. '
                'Taking you back to the dummy plugin.'.format(
                    plugin_obj['name']))
            self.cameras_dialog.select_fallback()
            info = self.cameras_dialog.get_plugin_info()
            self.select_plugin(*info)

    # Select camera plugin
    def select_plugin(self, plugin_obj):
        # Set up image capturing
        self.camera = plugin_obj()
        try:
            self.camera.open()
        except CameraError:
            error(None,
                  'No camera was detected. Did you forget to plug it in?')
            sys.exit()
Esempio n. 4
0
class CameraDialog(HasTraits):
    """Dialog for selecting the camera plugin."""

    cameras = List(Tuple(Str, Str, Str))
    camera_selection = Int()
    closed = Event()

    # UI
    about_plugin = Action(name='About',
        action='on_about_plugin',
        icon=find_icon('about'))
    view = View(
        Item('cameras',
            show_label=False,
            editor=ListStrEditor(
                adapter=_CameraDescriptionAdapter(),
                selected_index='camera_selection',
                editable=False,
                multi_select=False)),
        buttons=[about_plugin, CloseAction],
        title='Available Camera Plugins',
        resizable=True,
        width=400,
        height=200,
        handler=_CameraDialogHandler())

    # Public

    def get_plugin_object(self):
        """For the selected plugin, returns a tuple of the module name to
        import and the class name to construct in order to get a Camera
        object."""

        # Find the selected plugin
        plugin_id = self.cameras[self.camera_selection][0]
        # This should not fail, because only plugins which have all the requred
        # dependencies installed should be able to be selected
        try:
            return self.plugins[plugin_id].load()
        except ImportError:
            assert 0, ("A plugin was selected that didn't have all its " +
                "dependencies installed. This should not happen.")

    def __init__(self, **traits):
        super(CameraDialog, self).__init__(**traits)

        # Load the plugins
        self.plugins = pkg_resources.get_entry_map('beams', 'camera_plugins')

        if 'dummy' not in self.plugins.keys():
            raise IOError("Plugin directory isn't configured properly")

        # Try to select the webcam
        try:
            self._select_plugin_by_name('webcam')
        except ValueError:
            self.select_fallback()

    def _cameras_default(self):
        # Construct list store of plugins
        retval = []
        for plugin in self.plugins.keys():
            try:
                info = self.plugins[plugin].load().plugin_info
            except ImportError:
                # A required module was not found for that plugin, ignore it
                continue
            retval += [(plugin, info['name'], info['description'])]
        return retval

    def _select_plugin_by_name(self, name):
        """Select a plugin by name"""
        for ix, cam in enumerate(self.cameras):
            if cam[0] == name:
                self.camera_selection = ix
                return
        raise ValueError('Plugin {} not in list'.format(name))

    def select_fallback(self):
        """Select the dummy plugin as a fallback"""
        try:
            self._select_plugin_by_name('dummy')
        except ValueError:
            assert 0, 'Dummy plugin was not in list. Should not happen.'