Ejemplo n.º 1
0
    def init(self):
        self.programs = check_programs_existence(programs=['mencoder'])

        for p in self.programs:
            self.info('Using %13s = %s' % (p, self.programs[p]))

        if not isinstance(self.config.file, str):
            raise BadConfig('This should be a string.', self, 'file')

        self.file = expand(self.config.file)

        if not os.path.exists(self.file):
            msg = 'File %r does not exist.' % self.file
            raise BadConfig(msg, self, 'file')

        timestamps_file = self.file + MPlayer.TIMESTAMPS_SUFFIX
        if os.path.exists(timestamps_file):
            self.info('Reading timestamps from %r.' % timestamps_file)
            self.timestamps = open(timestamps_file)
        else:
            self.timestamps = None
            #self.info('Will use fps for timestamps.')

        self.mencoder_started = False

        self.state.timestamp = None
        self.state.timestamp = self.get_next_timestamp()
        self.state.next_frame = None
        self.state.finished = False

        self.num_frames_read = 0
Ejemplo n.º 2
0
    def update(self):

        # TODO: add check
        if self.state.first_timestamp is None:
            self.state.first_timestamp = self.get_input_timestamp(0)
            self.state.frame = 0
        else:
            self.state.frame += 1
        # Add stats
        macros = {}
        macros['timestamp'] = self.get_input_timestamp(0)
        if self.state.first_timestamp == ETERNITY:
            macros['time'] = -1
        else:
            macros['time'] = \
                self.get_input_timestamp(0) - self.state.first_timestamp
        macros['frame'] = self.state.frame

        rgb = self.input.rgb
        im = Image_from_array(rgb)
        from . import ImageDraw
        draw = ImageDraw.Draw(im)

        # {string: "raw image", position: [10,30], halign: left, 
        # color: black, bg: white  }
        if not isinstance(self.config.texts, list):
            raise BadConfig('Expected list', self, 'texts')

        for text in self.config.texts:
            text = text.copy()
            if not 'string' in text:
                raise BadConfig('Missing field "string" in text spec %s.' % 
                                text.__repr__(), self, 'texts')

            try:
                text['string'] = Text.replace(text['string'], macros)
            except KeyError as e:
                msg = str(e) + '\nAvailable: %s.' % macros.keys()
                raise BadConfig(msg, self, 'texts')

            p = text['position']
            
            try:
                p[0] = get_ver_pos_value(p[0], height=rgb.shape[0])
                p[1] = get_hor_pos_value(p[1], width=rgb.shape[1])
            except ValueError as e:
                raise BadConfig(str(e), text.__repr__(), self, 'texts')
            
            process_text(draw, text)

        out = im.convert("RGB")
        pixel_data = numpy.asarray(out)

        self.output.rgb = pixel_data
Ejemplo n.º 3
0
 def apply_styles(self, pylab):
     # TODO: check type
     for style in self.config.fancy_styles:
         if not style in fancy_styles:
             error = ('Cannot find style %r in %s' %
                      (style, fancy_styles.keys()))
             raise BadConfig(error, self, 'style')
         function = fancy_styles[style]
         function(pylab)
Ejemplo n.º 4
0
    def get_output_signals(self):
        self.reader = self.config.file
        all_signals = self.reader.get_all_signals()

        if self.config.signals is None:
            self.signals = all_signals
        else:
            signal_list = filter(lambda x: x, self.config.signals.split(','))
            if not signal_list:
                msg = 'Bad format: %r.' % self.config.signals
                raise BadConfig(msg, self, 'signals')
            for s in signal_list:
                if not s in all_signals:
                    msg = ('Signal %r not present in log (available: %r)' %
                           (s, all_signals))
                    raise BadConfig(msg, self, 'signals')
                self.signals.append(s)

        return self.signals
Ejemplo n.º 5
0
    def init(self):
        dirname = self.config.dir
        dirname = expand(dirname)

        if not os.path.exists(dirname):
            raise BadConfig('Not existent directory %r.' % dirname, self,
                            'dir')

        if not os.path.isdir(dirname):
            raise BadConfig('The file %r is not a directory.' % dirname, self,
                            'dir')

        regexp = self.config.regexp

        # TODO: use proper logging
        self.info("Reading %r from %r." % (regexp, dirname))
        all_files = os.listdir(dirname)

        selected = [os.path.join(dirname, f)
                    for f in all_files
                    if re.match(regexp, f)]

        def natural_key(string):
            """See http://www.codinghorror.com/blog/archives/001018.html"""
            return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string)]

        selected.sort(key=lambda x: natural_key(os.path.basename(x)))

        self.info("Selected %d/%d files." % (len(selected), len(all_files)))

        fps = float(self.config.fps)
        if fps <= 0:
            raise BadConfig(self, "Invalid fps value %s." % fps, 'fps')
        # tuples (timestamp, filename)
        frames = [(i / fps, f)
                    for i, f in enumerate(selected)]

        if not frames:
            raise Exception('No frames found in dir %r.' % dirname)

        self.state.frames = frames
        self.state.next_frame = 0
Ejemplo n.º 6
0
    def get_iterator(self):
        filename = self.config.filename
        if not os.path.exists(filename):
            raise BadConfig(self, 'Not existent file %r.' % filename,
                            'filename')

        raw_events = aer_load_log_generic(filename)

        events2 = aer_raw_relative_timestamp(raw_events)
        for e in events2:
            yield 0, e['timestamp'], e
Ejemplo n.º 7
0
    def get_output_signals(self):
        import rosbag
        self.bag = rosbag.Bag(self.config.file)

        self.topics = self.get_topics()

        self.topic2signal = {}
        signals = []
        for t in self.topics:
            self.info(t)
            if ':' in t:
                tokens = t.split(':')
                assert len(tokens) == 2
                t = tokens[0]
                signal_name = tokens[1]
            else:
                signal_name = str(t).split('/')[-1]
            if signal_name in signals:
                self.error('Warning: repeated name %s' % signal_name)
                signal_name = ("%s" % t).replace('/', '_')
                self.error('Using long form %r.' % signal_name)
            signals.append(signal_name)
            self.topic2signal[t] = signal_name

        topics = self.topic2signal.keys()

        self.info(self.topic2signal)

        limit = self.config.limit
        if not isinstance(limit, (float, int)):
            msg = 'I require a number; 0 for none.'
            raise BadConfig(msg, self, 'limit')

        if self.config.t0 is not None or self.config.t1 is not None:
            t0 = self.config.t0
            t1 = self.config.t1
            start_time, end_time = self._get_start_end_time_t0_t1(t0, t1)
        else:
            start_time, end_time = self._get_start_end_time(limit)

        print('t0: %s' % self.config.t0)
        print('t1: %s' % self.config.t1)
        print('start_time: %s' % start_time)
        print('end_time: %s' % end_time)
        print('start_stamp: %s' % self.start_stamp)
        print('end_stamp: %s' % self.end_stamp)

        params = dict(topics=topics, start_time=start_time, end_time=end_time)

        self.iterator = self.bag.read_messages(**params)

        return signals
Ejemplo n.º 8
0
def choose(rgb, channel=0):
    ''' Chooses a channel from an rgb image and replicates it 
        over the other two.

        Raises an error if ``channel`` is invalid.
    
        :param rgb: Input image.
        :param channel: Which channel to choose.        
        :return: processed: The processed image.
    '''
    if not channel in [0,1,2]:
        raise BadConfig('Invalid channel specified.', config='channel')
    
    v = rgb[:,:,channel]
    return numpy.dstack((v,v,v))
Ejemplo n.º 9
0
    def init(self):
        self.format = self.config.format
        (w, h) = self.get_shape()
        self.total_width = w
        self.total_height = h
        self.frame = 0

        if self.format == 'pdf':
            self.init_pdf()
        elif self.format == 'png':
            self.init_png()
        else:
            raise BadConfig('Invalid format %r.' % self.format, self, 'format')
        self.count = 0
        self.fps = None
        self.t0 = None

        self.tmp_cr = None
Ejemplo n.º 10
0
    def init(self):
        filename = self.config.file
        filename = os.path.expandvars(filename)
        filename = os.path.expanduser(filename)

        if not os.path.exists(filename):
            raise BadConfig('File %r does not exist.' % filename, self, 'file')

        # TODO: add .gz
        if filename.endswith('bz2'):
            import bz2
            self.stream = bz2.BZ2File(filename)
        else:
            self.stream = open(filename, 'r')

        self.state.line = 0  # line counter
        self.read_next_line()

        if self.timestamp is None:
            raise Exception('Empty file %s' % filename)
Ejemplo n.º 11
0
    def init(self):
        # Find the required files
        files = glob.glob(self.config.files)

        if len(files) == 0:
            raise BadConfig(
                'No files correspond to the pattern %r.' % self.config.files,
                self, 'files')

        # Open all logs; make sure they have the required signals and
        # note their initial timestamp.

        # list(tuple(file, timestamp, signal2table))
        logs = []
        for f in files:
            hf = tc_open_for_reading(f)
            check_is_procgraph_log(hf)

            log_group = hf.root._f_getChild(PROCGRAPH_LOG_GROUP)
            log_signals = list(log_group._v_children)

            signal2table = {}
            for s in self.signals:
                if not s in log_signals:
                    raise Exception('Log %r does not have signal %r '
                                    '(it has %s).' % (f, s, log_signals))
                signal2table[s] = log_group._f_getChild(s)

            timestamp = signal2table[s][0]['time']
            logs.append((hf, timestamp, signal2table))

        # Sort them by timestamp
        self.logs = sorted(logs, key=operator.itemgetter(1))
        self.current_log = None

        for log in logs:
            filename = log[0].filename
            length = len(list(log[2].values())[0])
            self.status('- queued log (%6d rows) from %r' % (length, filename))

        self.start_reading_next_log()
Ejemplo n.º 12
0
    def update(self):
        if not self.all_input_signals_ready():
            return
        
        n = self.num_input_signals()
        for i in range(n):
            input_check_convertible_to_rgb(self, i)

        cols = self.config.cols

        if cols is not None and not isinstance(cols, int):
            raise BadConfig('Expected an integer.', self, 'cols')

        images = [self.get_input(i) for i in range(n)]
        
        images = map(torgb, images)
        canvas = make_images_grid(images,
                                  cols=self.config.cols,
                                  pad=self.config.pad,
                                  bgcolor=self.config.bgcolor)
        
        self.set_output(0, canvas)
Ejemplo n.º 13
0
    def update(self):
        self.limits = None

        start = time.clock()

        if self.figure is None:
            self.init_figure()

        pylab.figure(self.figure.number)

        self.apply_styles(pylab)

        for i in range(self.num_input_signals()):
            value = self.input[i]
            if value is None:
                raise BadInput('Input is None (did you forget a |sync|?)',
                               self, i)
            elif isinstance(value, tuple):
                if len(value) != 2:
                    raise BadInput(
                        'Expected tuple of length 2 instead of %d.' %
                        len(value), self, i)

                xo = value[0]
                yo = value[1]

                if xo is None or yo is None:
                    raise BadInput('Invalid members of tuple', self, i)

                x = np.array(xo)
                y = np.array(yo)

                # X must be one-dimensional
                if len(x.shape) > 1:
                    raise BadInput('Bad x vector w/shape %s.' % str(x.shape),
                                   self, i)

                # y should be of dimensions ...?
                if len(y.shape) > 2:
                    raise BadInput('Bad shape for y vector %s.' % str(y.shape),
                                   self, i)

                if len(x) != y.shape[0]:
                    raise BadInput('Incompatible dimensions x: %s, y: %s' %
                                   (str(x.shape), str(y.shape)))
                # TODO: check x unidimensional (T)
                # TODO: check y compatible dimensions (T x N)

            else:
                y = np.array(value)
                if len(y.shape) > 2:
                    raise BadInput('Bad shape for y vector %s.' % str(y.shape),
                                   self, i)

                if len(y.shape) == 1:
                    x = np.array(range(len(y)))
                else:
                    assert (len(y.shape) == 2)
                    x = np.array(range(y.shape[1]))

            if len(x) <= 1:
                continue

            if len(y.shape) == 2:
                y = y.transpose()

            if len(y.shape) == 1:
                pid = self.canonicalize_input(i)
                self.plot_one(pid, x, y, self.config.format)
            else:
                assert (len(y.shape) == 2)
                num_lines = y.shape[0]
                for k in range(num_lines):
                    pid = "%s-%d" % (self.canonicalize_input(i), k)
                    yk = y[k, :]
                    self.plot_one(pid, x, yk, self.config.format)
            # TODO: check that if one has time vector, also others have it

        if self.limits is not None:

            if self.config.x_min is not None:
                self.limits[0] = self.config.x_min
            if self.config.x_max is not None:
                self.limits[1] = self.config.x_max
            if self.config.y_min is not None:
                self.limits[2] = self.config.y_min
            if self.config.y_max is not None:
                self.limits[3] = self.config.y_max

            if self.config.symmetric:
                if self.config.y_min is not None or \
                   self.config.y_max is not None:
                    raise BadConfig(
                        'Cannot specify symmetric together with'
                        'y_min or y_max.', self, 'symmetric')

                M = max(abs(self.limits[2:4]))
                if 'dottedzero' in self.config.fancy_styles:
                    a = pylab.axis()
                    pylab.plot([a[0], a[1]], [0, 0], 'k--')

                self.limits[2] = -M
                self.limits[3] = M

            # leave some space above and below
            self.limits[2] = self.limits[2] * 1.1
            self.limits[3] = self.limits[3] * 1.1

            self.axes.axis(self.limits)

        if self.legend_handle is None:
            legend = self.config.legend
            if legend:
                self.legend_handle = self.axes.legend(*legend,
                                                      loc='upper right',
                                                      handlelength=1.5,
                                                      markerscale=2,
                                                      labelspacing=0.03,
                                                      borderpad=0,
                                                      handletextpad=0.03,
                                                      borderaxespad=1)

        # http://matplotlib.sourceforge.net/users/tight_layout_guide.html
        try:
            pylab.tight_layout()
        except Exception as e:
            msg = ('Could not call tight_layout(); available only on '
                   'Matplotlib >=1.1 (%s)' % e)
            if not self.warned:
                self.warning(msg)
                self.warned = True

        plotting = time.clock() - start

        start = time.clock()
        # There is a bug that makes the image smaller than desired
        # if tight is True
        pixel_data = pylab2rgb(transparent=self.config.transparent,
                               tight=self.config.tight)

        # So we check and compensate
        shape = pixel_data.shape[0:2]
        shape_expected = (self.config.height, self.config.width)
        from procgraph_images import image_pad  # need here, otherwise circular

        if shape != shape_expected:
            msg = ('pylab2rgb() returned size %s instead of %s.' %
                   (shape, shape_expected))
            msg += ' I will pad the image with white.'
            self.warning(msg)
            pixel_data = image_pad(pixel_data,
                                   shape_expected,
                                   bgcolor=[1, 1, 1])
            assert_equal(pixel_data.shape[0:2], shape_expected)

        reading = time.clock() - start

        if False:
            # 30 49 30 before
            print("plotting: %dms    reading: %dms" %
                  (plotting * 1000, reading * 1000))

        self.output.rgb = pixel_data

        if not self.config.keep:
            pylab.close(self.figure.number)
            self.figure = None
Ejemplo n.º 14
0
 def get_output_signals(self):
     self.signals = filter(lambda x: x, self.config.signals.split(','))
     if not self.signals:
         raise BadConfig('No signals specified.', self, 'signals')
     return self.signals