예제 #1
0
class DataCollectorService(object):
    def __init__(self, comm_config, data_dirpath):
        self.comm_config = comm_config
        self.comm_config['subscribe'][
            'berrynet/engine/tensorflow/result'] = self.update
        self.comm_config['subscribe'][
            'berrynet/engine/mvclassification/result'] = self.update
        self.comm = Communicator(self.comm_config, debug=True)
        self.data_dirpath = data_dirpath

    def update(self, pl):
        if not os.path.exists(self.data_dirpath):
            try:
                os.mkdir(self.data_dirpath)
            except Exception as e:
                logger.warn('Failed to create {}'.format(self.data_dirpath))
                raise (e)

        payload_json = payload.deserialize_payload(pl.decode('utf-8'))
        jpg_bytes = payload.destringify_jpg(payload_json['bytes'])
        payload_json.pop('bytes')
        logger.debug('inference text result: {}'.format(payload_json))

        timestamp = datetime.now().isoformat()
        with open(pjoin(self.data_dirpath, timestamp + '.jpg'), 'wb') as f:
            f.write(jpg_bytes)
        with open(pjoin(self.data_dirpath, timestamp + '.json'), 'w') as f:
            f.write(json.dumps(payload_json, indent=4))

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()
예제 #2
0
class DashboardService(object):
    def __init__(self, service_name, comm_config):
        self.service_name = service_name
        self.comm_config = comm_config
        self.comm_config['subscribe'][
            'berrynet/engine/tensorflow/result'] = self.update
        self.comm_config['subscribe'][
            'berrynet/engine/mvclassification/result'] = self.update
        self.comm = Communicator(self.comm_config, debug=True)
        self.basedir = '/usr/local/berrynet/dashboard/www/freeboard'

    def update(self, pl):
        payload_json = payload.deserialize_payload(pl.decode('utf-8'))
        jpg_bytes = payload.destringify_jpg(payload_json['bytes'])
        inference_result = [
            '{0}: {1}<br>'.format(anno['label'], anno['confidence'])
            for anno in payload_json['annotations']
        ]
        logger.debug('inference results: {}'.format(inference_result))

        with open(pjoin(self.basedir, 'snapshot.jpg'), 'wb') as f:
            f.write(jpg_bytes)
        self.comm.send('berrynet/dashboard/snapshot', 'snapshot.jpg')
        self.comm.send('berrynet/dashboard/inferenceResult',
                       json.dumps(inference_result))

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()
예제 #3
0
class DydaConfigUpdateClient(object):
    def __init__(self, comm_config, debug=False):
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = self.handleResult
        self.comm = Communicator(self.comm_config, debug=True)

    def sendConfig(self, jsonPayload):
        self.comm.send(self.comm_config['publish'], jsonPayload)

    def handleResult(self, pl):
        try:
            payload_json = payload.deserialize_payload(pl.decode('utf-8'))
            print(payload_json)
            self.comm.stop_nb()
            sys.exit(0)
        except Exception as e:
            logger.info(e)

    def run(self, args):
        """Infinite loop serving inference requests"""
        with open(args['payload']) as f:
            payload = f.read()
            self.sendConfig(payload)
        self.comm.run()
예제 #4
0
class DydaConfigUpdateService(object):
    def __init__(self, comm_config, debug=False):
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = self.handleConfig
        self.comm = Communicator(self.comm_config, debug=True)

    def sendConfig(self, jsonPayload):
        self.comm.send(self.comm_config['publish'], jsonPayload)
        
    def handleConfig(self, pl):
        payload_json = ""
        try:
            payload_json = payload.deserialize_payload(pl.decode('utf-8'))
            self.comm.send(self.comm_config['publish'], payload.serialize_payload(payload_json))
        except Exception as e:
            logger.info(e)

        # output config file
        with open(self.comm_config['configfile'], 'w') as configfile:
            configfile.write(payload.serialize_payload(payload_json))
            configfile.close()

        # restart service
        subprocess.run(["supervisorctl", "restart", "bnpipeline-bndyda"])
            
    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()
예제 #5
0
class EngineService(object):
    def __init__(self, service_name, engine, comm_config):
        self.service_name = service_name
        self.engine = engine
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = eval(functor)
        self.comm_config['subscribe'][
            'berrynet/data/rgbimage'] = self.inference
        self.comm = Communicator(self.comm_config, debug=True)

    def inference(self, pl):
        duration = lambda t: (datetime.now() - t).microseconds / 1000

        t = datetime.now()
        logger.debug('payload size: {}'.format(len(pl)))
        logger.debug('payload type: {}'.format(type(pl)))
        jpg_json = payload.deserialize_payload(pl.decode('utf-8'))
        jpg_bytes = payload.destringify_jpg(jpg_json['bytes'])
        logger.debug('destringify_jpg: {} ms'.format(duration(t)))

        t = datetime.now()
        rgb_array = payload.jpg2rgb(jpg_bytes)
        logger.debug('jpg2rgb: {} ms'.format(duration(t)))

        t = datetime.now()
        image_data = self.engine.process_input(rgb_array)
        output = self.engine.inference(image_data)
        model_outputs = self.engine.process_output(output)
        logger.debug('Result: {}'.format(model_outputs))
        logger.debug('Classification takes {} ms'.format(duration(t)))

        #self.engine.cache_data('model_output', model_outputs)
        #self.engine.cache_data('model_output_filepath', output_name)
        #self.engine.save_cache()

        self.result_hook(self.generalize_result(jpg_json, model_outputs))

    def generalize_result(self, eng_input, eng_output):
        eng_input.update(eng_output)
        return eng_input

    def result_hook(self, generalized_result):
        logger.debug('base result_hook')

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.engine.create()
        self.comm.run()
예제 #6
0
class PipelineRestarterService(object):
    def __init__(self, service_name, comm_config):
        self.service_name = service_name
        self.comm_config = comm_config
        self.comm_config['subscribe']['dlboxapi/config/update'] = \
            self.restart_pipeline
        self.comm = Communicator(self.comm_config, debug=True)

    def restart_pipeline(self, pl):
        logger.debug('Restart pipeline')
        subprocess.call('dlbox-manager restart dlbox-pipeline.service',
                        shell=True)

    def run(self, args):
        """Infinite loop serving pipeline restart requests"""
        self.comm.run()
예제 #7
0
class DydaConfigUpdateService(object):
    def __init__(self, comm_config, debug=False):
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = self.handleConfig
        self.comm = Communicator(self.comm_config, debug=True)
        idlistConfig = configparser.ConfigParser()
        idlistConfig.read(self.comm_config['idlist'])
        self.idlist = idlistConfig["ID"]

    def sendConfig(self, jsonPayload):
        self.comm.send(self.comm_config['publish'], jsonPayload)

    def handleConfig(self, pl):
        payload_json = ""
        try:
            id = pl.decode('utf-8')
            if (id in self.idlist):
                configFilename = self.idlist[id]
                f = open(configFilename)
                payload_json = payload.deserialize_payload(f.read())
                self.sendConfig(payload.serialize_payload(payload_json))
            else:
                logger.warning("ID %s is not in idlist" % (id))
                return
        except Exception as e:
            logger.info(e)

        # output config file
        with open(self.comm_config['configfile'], 'w') as configfile:
            configfile.write(payload.serialize_payload(payload_json))
            configfile.close()

        # restart service
        subprocess.run(["supervisorctl", "restart", "bnpipeline-bndyda"])

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()
예제 #8
0
class SnapshotService(object):
    def __init__(self, comm_config):
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = eval(functor)
        self.comm_config['subscribe'][
            'berrynet/trigger/controller/snapshot'] = self.snapshot
        self.comm = Communicator(self.comm_config, debug=True)

    def snapshot(self, pl):
        '''Send camera snapshot.

        The functionality is the same as using camera client in file mode.

        The difference is that snapshot client retrieves image from camera
        instead of given filepath.
        '''
        duration = lambda t: (datetime.now() - t).microseconds / 1000

        # WORKAROUND: Prevent VideoCapture from buffering frames.
        #     VideoCapture will buffer frames automatically, and we need
        #     to find a way to disable it.
        self.capture = cv2.VideoCapture(0)
        status, im = self.capture.read()
        if (status is False):
            logger.warn('ERROR: Failure happened when reading frame')

        t = datetime.now()
        retval, jpg_bytes = cv2.imencode('.jpg', im)
        mqtt_payload = payload.serialize_jpg(jpg_bytes)
        self.comm.send('berrynet/data/rgbimage', mqtt_payload)
        logger.debug('send: {} ms'.format(duration(t)))
        self.capture.release()

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()
예제 #9
0
class DataCollectorService(object):
    def __init__(self, comm_config, data_dirpath):
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = eval(functor)
        #self.comm_config['subscribe']['berrynet/data/rgbimage'] = self.update
        self.comm_config['subscribe']['berrynet/engine/pipeline/result'] = self.save_pipeline_result
        self.comm = Communicator(self.comm_config, debug=True)
        self.data_dirpath = data_dirpath

    def update(self, pl):
        payload_json = payload.deserialize_payload(pl.decode('utf-8'))

        # update UI with the latest inference result
        self.ui.update(payload_json, 'bytes')

        if self.data_dirpath:
            if not os.path.exists(self.data_dirpath):
                try:
                    os.mkdir(self.data_dirpath)
                except Exception as e:
                    logger.warn('Failed to create {}'.format(self.data_dirpath))
                    raise(e)

            jpg_bytes = payload.destringify_jpg(payload_json['bytes'])
            payload_json.pop('bytes')
            logger.debug('inference text result: {}'.format(payload_json))

            timestamp = datetime.now().isoformat()
            with open(pjoin(self.data_dirpath, timestamp + '.jpg'), 'wb') as f:
                f.write(jpg_bytes)
            with open(pjoin(self.data_dirpath, timestamp + '.json'), 'w') as f:
                f.write(json.dumps(payload_json, indent=4))

    def save_pipeline_result(self, pl):
        payload_json = payload.deserialize_payload(pl.decode('utf-8'))

        # update UI with the latest inference result
        self.ui.update(payload_json, 'image_blob')

        if self.data_dirpath:
            if not os.path.exists(self.data_dirpath):
                try:
                    os.mkdir(self.data_dirpath)
                except Exception as e:
                    logger.warn('Failed to create {}'.format(self.data_dirpath))
                    raise(e)

            jpg_bytes = payload.destringify_jpg(payload_json['image_blob'])
            payload_json.pop('image_blob')
            logger.debug('inference text result: {}'.format(payload_json))

            timestamp = datetime.now().isoformat()
            with open(pjoin(self.data_dirpath, timestamp + '.jpg'), 'wb') as f:
                f.write(jpg_bytes)
            with open(pjoin(self.data_dirpath, timestamp + '.json'), 'w') as f:
                f.write(json.dumps(payload_json, indent=4))

    def send_snapshot_trigger(self):
        payload = {}
        payload['timestamp'] = datetime.now().isoformat()
        mqtt_payload = json.dumps(payload)
        self.comm.send('berrynet/trigger/controller/snapshot', mqtt_payload)

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()
예제 #10
0
class GmailService(object):
    def __init__(self, comm_config):
        self.comm_config = comm_config
        for topic, functor in self.comm_config['subscribe'].items():
            self.comm_config['subscribe'][topic] = eval(functor)
        self.comm_config['subscribe'][
            'berrynet/engine/darknet/result'] = self.update
        self.comm_config['subscribe'][
            'berrynet/engine/tensorflow/result'] = self.update
        self.comm = Communicator(self.comm_config, debug=True)
        self.email = comm_config['email']
        self.pipeline_compatible = comm_config['pipeline_compatible']
        self.target_label = comm_config['target_label']

    def find_target_label(self, target_label, generalized_result):
        label_list = [i['label'] for i in generalized_result['annotations']]
        logger.debug('Result labels: {}'.format(label_list))
        return target_label in label_list

    def update(self, pl):
        payload_json = payload.deserialize_payload(pl.decode('utf-8'))
        if self.pipeline_compatible:
            b64img_key = 'image_blob'
        else:
            b64img_key = 'bytes'
        jpg_bytes = payload.destringify_jpg(payload_json[b64img_key])
        payload_json.pop(b64img_key)
        logger.debug('inference text result: {}'.format(payload_json))

        match_target_label = self.find_target_label(self.target_label,
                                                    payload_json)

        logger.debug('Find target label {0}: {1}'.format(
            self.target_label, match_target_label))

        if match_target_label:
            timestamp = datetime.now().isoformat()
            notification_image = pjoin('/tmp', timestamp + '.jpg')
            notification_text = pjoin('/tmp', timestamp + '.json')
            with open(notification_image, 'wb') as f:
                f.write(jpg_bytes)
            with open(notification_text, 'w') as f:
                f.write(json.dumps(payload_json, indent=4))

            try:
                send_email_text(self.email['sender_address'],
                                self.email['sender_password'],
                                self.email['receiver_address'],
                                body=('Target label {} is found. '
                                      'Please check the attachments.'
                                      ''.format(self.target_label)),
                                subject='BerryNet mail client notification',
                                attachments=set(
                                    [notification_image, notification_text]))
            except Exception as e:
                logger.warn(e)

            os.remove(notification_image)
            os.remove(notification_text)
        else:
            # target label is not in generalized result, do nothing
            pass

    def run(self, args):
        """Infinite loop serving inference requests"""
        self.comm.run()