예제 #1
0
    def upload_model(self, extra):
        model_desc = self.api.simple_request('GenerateNewModelId',
                                             api_proto.ModelDescription,
                                             api_proto.Empty())
        local_extra = {
            'model_id': model_desc.id,
            'model_hash': model_desc.hash
        }
        self.logger.trace('NEW_MODEL_ID', extra=local_extra)

        cur_checkpoint_dir = os.path.join(self.dir_results, extra['subdir'])

        storage = self.data_mgr.storage.nns
        if storage.check_storage_object(model_desc.hash):
            self.logger.critical('CHECKPOINT_ALREADY_EXISTS',
                                 extra=local_extra)
            raise RuntimeError()
        storage.write_object(cur_checkpoint_dir, model_desc.hash)
        model_config_path = osp.join(cur_checkpoint_dir, 'config.json')
        if osp.isfile(model_config_path):
            local_extra['model_config'] = sly.json_load(model_config_path)

        self.logger.info('MODEL_SAVED', extra=local_extra)
        # don't report TaskStep.UPLOAD because there should be multiple uploads

        res = {
            'model_id': model_desc.id,
            'model_hash': model_desc.hash,
            'model_config': local_extra.get('model_config', {})
        }
        return res
예제 #2
0
def load_ann(ann_fpath, classes_mapping, project_meta):
    ann_packed = sly.json_load(ann_fpath)
    ann = sly.Annotation.from_packed(ann_packed, project_meta)
    # ann.normalize_figures()  # @TODO: enaaaable!
    (w, h) = ann.image_size_wh

    gt_boxes, classes_text, classes = [], [], []
    for fig in ann['objects']:
        gt = np.zeros((h, w), dtype=np.uint8)  # default bkg
        gt_idx = classes_mapping.get(fig.class_title, None)
        if gt_idx is None:
            raise RuntimeError(
                'Missing class mapping (title to index). Class {}.'.format(
                    fig.class_title))
        fig.draw(gt, 1)
        if np.sum(gt) > 0:
            xmin, ymin, xmax, ymax = get_bbox(gt)
            gt_boxes.append([ymin / h, xmin / w, ymax / h, xmax / w])
            classes_text.append(
                fig.class_title.encode('utf8')
            )  # List of string class name of bounding box (1 per box)
            classes.append(
                gt_idx)  # List of integer class id of bounding box (1 per box)
    num_boxes = len(
        gt_boxes)  # ops.convert_to_tensor(len(gt_boxes), dtype=dtypes.int32)
    # gt_boxes = ops.convert_to_tensor(gt_boxes, dtype=dtypes.float32)
    # classes = ops.convert_to_tensor(classes, dtype=dtypes.int64)
    return np.array(gt_boxes).astype('float32'), np.array(classes).astype(
        'int64'), np.array([num_boxes]).astype('int32')[0]
예제 #3
0
def serve():
    settings = {
        'device_id': 0,
        'cache_limit': 500,
        'connection': {
            'server_address': None,
            'token': None,
            'task_id': None,
        },
    }

    new_settings = sly.json_load(sly.TaskPaths(determine_in_project=False).settings_path)
    logger.info('Input settings', extra={'settings': new_settings})
    sly.update_recursively(settings, new_settings)
    logger.info('Full settings', extra={'settings': settings})

    def model_creator():
        res = UnetV2FastApplier(settings={
            'device_id': settings['device_id']
        })
        return res

    image_cache = SimpleCache(settings['cache_limit'])
    serv_instance = AgentRPCServicer(logger=logger,
                                     model_creator=model_creator,
                                     apply_cback=single_img_pipeline,
                                     conn_settings=settings['connection'],
                                     cache=image_cache)
    serv_instance.run_inf_loop()
예제 #4
0
    def _construct_project_items_to_upload(cls, project_fs, project_id, ds_names_to_ids):
        project_items = list(project_fs)
        for it in project_items:

            ann = sly.json_load(it.ann_path)
            img_w, img_h = sly.Annotation.get_image_size_wh(ann)

            # get image hash & ext
            if it.img_path and sly.file_exists(it.img_path):
                it.ia_data['image_hash'] = sly.get_image_hash(it.img_path)
                # image_ext is already determined in project_fs
                img_sizeb = sly.get_file_size(it.img_path)
            else:
                for spec_field in ann_special_fields():
                    if spec_field not in ann:
                        raise RuntimeError('Missing spec field in annotation: {}'.format(spec_field))
                it.ia_data['image_hash'] = ann['img_hash']
                it.ia_data['image_ext'] = ann['img_ext']
                img_sizeb = ann['img_size_bytes']

            # construct image info
            img_meta_str = create_img_meta_str(img_sizeb, width=img_w, height=img_h)
            img_proto_info = api_proto.Image(hash=it.ia_data['image_hash'],
                                             title=it.image_name,
                                             ext=it.ia_data['image_ext'],
                                             dataset_id=ds_names_to_ids[it.ds_name],
                                             project_id=project_id,
                                             meta=img_meta_str)
            it.ia_data['img_proto_info'] = img_proto_info

        return project_items
예제 #5
0
    def upload_result_project(self, _):
        self.report_step_done(TaskStep.MAIN)
        self._read_verif_status()
        graph_pr_name = sly.get_res_project_name(self.info['graph'])

        no_image_files = not self.download_images

        if self.is_archive is False:
            pr_id = self.data_mgr.upload_project(self.dir_results,
                                                 graph_pr_name,
                                                 no_image_files=no_image_files)
            self.logger.info('PROJECT_CREATED',
                             extra={
                                 'event_type': EventType.PROJECT_CREATED,
                                 'project_id': pr_id
                             })
        else:
            # remove excess fields from json
            root_path, project_name = sly.ProjectFS.split_dir_project(
                self.dir_results)
            project_fs = sly.ProjectFS.from_disk(root_path,
                                                 project_name,
                                                 by_annotations=True)
            for item in project_fs:
                ann_path = item.ann_path
                ann = sly.json_load(ann_path)
                for exc_field in ann_special_fields():
                    ann.pop(exc_field, None)
                sly.json_dump(ann, ann_path)

            self.data_mgr.upload_archive(self.dir_results, graph_pr_name)

        self.report_step_done(TaskStep.UPLOAD)
        return {}
예제 #6
0
    def run_inference(self):
        out_project_fs = copy(self.in_project_fs)
        out_project_fs.root_path = self.helper.paths.results_dir
        out_project_fs.make_dirs()

        inf_feeder = sly.InferenceFeederFactory.create(self.config, self.helper.in_project_meta, self.train_classes)
        out_pr_meta = inf_feeder.out_meta
        out_pr_meta.to_dir(out_project_fs.project_path)

        ia_cnt = out_project_fs.pr_structure.image_cnt
        progress = sly.progress_counter_inference(cnt_imgs=ia_cnt)

        for sample in self.in_project_fs:
            logger.info('Will process image',
                        extra={'dataset_name': sample.ds_name, 'image_name': sample.image_name})
            ann_packed = sly.json_load(sample.ann_path)
            ann = sly.Annotation.from_packed(ann_packed, self.helper.in_project_meta)

            img = cv2.imread(sample.img_path)[:, :, ::-1]
            res_ann = inf_feeder.feed(img, ann, self._infer_on_img)

            out_ann_fpath = out_project_fs.ann_path(sample.ds_name, sample.image_name)
            res_ann_packed = res_ann.pack()
            sly.json_dump(res_ann_packed, out_ann_fpath)

            if self.debug_copy_images:
                out_img_fpath = out_project_fs.img_path(sample.ds_name, sample.image_name)
                sly.ensure_base_path(out_img_fpath)
                shutil.copy(sample.img_path, out_img_fpath)

            progress.iter_done_report()

        sly.report_inference_finished()
예제 #7
0
def main():
    sly.task_verification(check_in_graph)

    logger.info('DTL started')
    helper = sly.DtlHelper()
    net = Net(helper.graph, helper.in_project_metas, helper.paths.results_dir)
    helper.save_res_meta(net.get_result_project_meta())

    # is_archive = net.is_archive()
    results_counter = 0
    for pr_name, pr_dir in helper.in_project_dirs.items():
        root_path, project_name = sly.ProjectFS.split_dir_project(pr_dir)
        project_fs = sly.ProjectFS.from_disk(root_path, project_name, by_annotations=True)
        progress = sly.progress_counter_dtl(pr_name, project_fs.image_cnt)
        for sample in project_fs:
            try:
                img_desc = sly.ImageDescriptor(sample)
                ann = sly.json_load(sample.ann_path)
                data_el = (img_desc, ann)
                export_output_generator = net.start(data_el)
                for res_export in export_output_generator:
                    logger.trace("image processed", extra={'img_name': res_export[0][0].get_img_name()})
                    results_counter += 1
            except Exception:
                ex = {
                    'project_name': sample.project_name,
                    'ds_name': sample.ds_name,
                    'image_name': sample.image_name
                }
                logger.warn('Image was skipped because some error occured', exc_info=True, extra=ex)
            progress.iter_done_report()

    logger.info('DTL finished', extra={'event_type': EventType.DTL_APPLIED, 'new_proj_size': results_counter})
예제 #8
0
    def __init__(self):
        task_paths = sly.DtlPaths()
        self.in_dir = task_paths.data_dir
        self.out_dir = task_paths.results_dir
        self.settings = sly.json_load(task_paths.settings_path)

        self.classes = set()
        self.tags = set()
예제 #9
0
 def __init__(self):
     task_paths = sly.DtlPaths()
     self.in_dir = task_paths.data_dir
     self.out_dir = task_paths.results_dir
     self.settings = sly.json_load(task_paths.settings_path)
     self.colors_file = osp.join(self.in_dir, 'colors.json')
     self._read_colors()
     self._read_datasets()
예제 #10
0
    def _read_colors(self):
        if osp.isfile(self.colors_file):
            logger.info(
                'Will try to read segmentation colors from provided file.')
            color_info = sly.json_load(self.colors_file)
        else:
            logger.info('Will use default Mapillary color mapping.')
            default_fpath = osp.join(osp.dirname(__file__), 'colors.json')
            color_info = sly.json_load(default_fpath)
        labels = color_info['labels']
        self.instance_classes = [
            el['readable'] for el in labels if el['instances']
        ]
        self.cls2col = {el['readable']: tuple(el['color']) for el in labels}
        logger.info('Determined {} class(es).'.format(len(self.cls2col)),
                    extra={'classes': list(self.cls2col.keys())})

        self.cls_names = [el['readable']
                          for el in labels]  # ! from order of labels
예제 #11
0
    def __init__(self):
        task_paths = sly.DtlPaths()
        self.in_dir = task_paths.data_dir
        self.out_dir = task_paths.results_dir
        self.settings = sly.json_load(task_paths.settings_path)

        if len(task_paths.project_dirs) > 1:
            raise RuntimeError('The project should consist of only one folder.')

        self.dataset_dir = task_paths.project_dirs[0]
        self._define_classes()
예제 #12
0
    def __init__(self):
        task_paths = sly.DtlPaths()
        self.in_dir = task_paths.data_dir
        self.out_dir = task_paths.results_dir
        self.settings = sly.json_load(task_paths.settings_path)

        if len(task_paths.project_dirs) != 1:
            raise RuntimeError(
                'Invalid data format. Input folder should contain only "images_and_annotations" dir'
            )
        self.data_dir = join(self.in_dir, 'images_and_annotations')
예제 #13
0
    def __init__(self):
        task_paths = sly.DtlPaths()
        self.in_dir = task_paths.data_dir
        self.out_dir = task_paths.results_dir
        self.settings = sly.json_load(task_paths.settings_path)

        if not os.path.exists(join(self.in_dir, 'img')) or not os.path.exists(
            (join(self.in_dir, 'ann'))):
            raise RuntimeError(
                'Invalid data format. Input folder should contain "img" and "ann" dirs'
            )
        self.img_dir = join(self.in_dir, 'img')
        self.ann_dir = join(self.in_dir, 'ann')
예제 #14
0
def load_ann(ann_path, labels_mapping, in_pr_meta):
    ann_packed = sly.json_load(ann_path)
    ann = sly.Annotation.from_packed(ann_packed, in_pr_meta)
    # ann.normalize_figures()  # @TODO: enaaaable!

    w, h = ann.image_size_wh
    gt = np.zeros((h, w), dtype=np.uint8)  # default bkg = 0
    for fig in ann['objects']:
        gt_color = labels_mapping.get(fig.class_title, None)
        if gt_color is None:
            err_str = 'Missing class mapping (title to index). Class {}.'.format(fig.class_title)
            print(err_str)  # exception info may be suppressed
            raise RuntimeError(err_str)
        fig.draw(gt, gt_color)

    gt = gt.astype(np.float32)
    return gt
예제 #15
0
def ann2label(ann_fpath, class_mapping, project_meta, out_size_wh):
    ann_packed = sly.json_load(ann_fpath)
    ann = sly.Annotation.from_packed(ann_packed, project_meta)
    (w, h) = ann.image_size_wh
    # ann.normalize_figures()  # @TODO: enaaaable!
    # will not resize figures: resize gt instead

    gt = np.zeros((h, w), dtype=np.uint8)  # default bkg
    for fig in ann['objects']:
        gt_color = class_mapping.get(fig.class_title, None)
        if gt_color is None:
            raise RuntimeError(
                'Missing class mapping (title to index). Class {}.'.format(
                    fig.class_title))
        fig.draw(gt, gt_color)

    gt = sly.resize_inter_nearest(gt, out_size_wh).astype(np.float32)
    return gt
예제 #16
0
    def _load_citysc_annotation(self, ann_path):
        json_data = sly.json_load(ann_path)
        imsize_wh = json_data['imgWidth'], json_data['imgHeight']
        figures = []
        for obj in json_data['objects']:
            cls = obj['label']
            if cls == 'out of roi':
                polygon = obj['polygon'][:5]
                interiors = [obj['polygon'][5:]]
            else:
                polygon = obj['polygon']
                interiors = []

            self.classes.add(cls)

            to_add = sly.FigurePolygon.from_np_points(cls, imsize_wh, polygon, interiors)
            figures.extend(to_add)

        ann = sly.Annotation.new_with_objects(imsize_wh, figures)
        return ann
예제 #17
0
def load_ann(ann_fpath, classes_mapping, project_meta):
    ann_packed = sly.json_load(ann_fpath)
    ann = sly.Annotation.from_packed(ann_packed, project_meta)
    (w, h) = ann.image_size_wh

    gt_boxes, classes_text, classes = [], [], []
    for fig in ann['objects']:
        gt_idx = classes_mapping.get(fig.class_title, None)
        if gt_idx is None:
            raise RuntimeError(
                'Missing class mapping (title to index). Class {}.'.format(
                    fig.class_title))
        rect = fig.get_bbox()
        x = (rect.left + rect.right) / (2 * w)
        y = (rect.bottom + rect.top) / (2 * h)
        r_width = (rect.right - rect.left) / w
        r_height = (rect.bottom - rect.top) / h
        gt_boxes.extend([gt_idx, x, y, r_width, r_height])
    num_boxes = len(ann['objects'])
    return num_boxes, gt_boxes
예제 #18
0
    def _get_sample_impl(self, img_fpath, ann_fpath):
        img = cv2.imread(img_fpath)[:, :, ::-1]  # raises exc if img is None
        h, w = img.shape[:2]
        img = cv2.resize(img, self.out_size_wh)

        ann_packed = sly.json_load(ann_fpath)
        ann = sly.Annotation.from_packed(ann_packed, self.project_meta)
        # ann.normalize_figures()  # @TODO: enaaaable!
        # will not resize figures: resize gt instead

        gt = np.ones((h, w), dtype=np.uint8) * self.bkg_color  # default bkg
        for fig in ann['objects']:
            gt_color = self.class_mapping.get(fig.class_title, None)
            if gt_color is None:
                raise RuntimeError(
                    'Missing class mapping (title to index). Class {}.'.format(
                        fig.class_title))
            fig.draw(gt, gt_color)

        gt = sly.resize_inter_nearest(gt, self.out_size_wh).astype(np.int64)
        gt = np.expand_dims(gt, 0)
        return input_image_normalizer(img), gt
예제 #19
0
def main():
    # Please note that auxiliary methods from sly (supervisely_lib) use supervisely_lib.logger to format output.
    # So don't replace formatters or handlers of the logger.
    # One may use other loggers or simple prints for other output, but it's recommended to use supervisely_lib.logger.
    logger.info('Hello ML world')
    print('Glad to see u')

    # TaskHelperTrain contains almost all needed to run training as Supervisely task,
    # including task settings and paths to data and models.
    task_helper = sly.TaskHelperTrain()

    # All settings and parameters are passed to task in json file.
    # Content of the file is entirely dependent on model implementation.
    training_settings = task_helper.task_settings
    logger.info('Task settings are read',
                extra={'task_settings': training_settings})
    cnt_epochs = training_settings[
        "epochs"]  # in the fake model we want cnt of epochs
    cnt_iters_per_epoch = training_settings["iters_per_epoch"]

    # Let's imitate model weights loading.
    # Task acquires directory with input model weights (e.g. to continue training or to initialize some parameters).
    # Content of the directory is entirely dependent on model implementation.
    model_dir = task_helper.paths.model_dir
    if task_helper.model_dir_is_empty():
        model = create_fake_model()
        logger.info('Model created from scratch')
    else:
        model = load_fake_model(model_dir)
        logger.info('Init model weights are loaded',
                    extra={'model_dir': model_dir})

    # We will save weights of trained model (checkpoints) into directories provided by the checkpoints_saver.
    checkpoints_saver = task_helper.checkpoints_saver
    logger.info('Ready to save checkpoints',
                extra={'results_dir': task_helper.paths.results_dir})

    # Let's imitate reading input project with training data.
    # Of course in real implementations it is usually wrapped in some data loaders which are executed in parallel.
    project_meta = task_helper.in_project_meta  # Project meta contains list of project classes.
    project_dir = task_helper.paths.project_dir
    project_fs = sly.ProjectFS.from_disk_dir_project(project_dir)
    # ProjectFS enlists all samples (image/annotation pairs) in input project.
    for item_descr in project_fs:
        logger.info('Processing input sample',
                    extra={
                        'dataset': item_descr.ds_name,
                        'image_name': item_descr.image_name
                    })

        # Open some image...
        img = cv2.imread(item_descr.img_path)
        logger.info('Read image from input project',
                    extra={
                        'width': img.shape[1],
                        'height': img.shape[0]
                    })

        # And read corresponding annotation...
        ann_packed = sly.json_load(item_descr.ann_path)
        ann = sly.Annotation.from_packed(ann_packed, project_meta)
        logger.info('Read annotation from input project',
                    extra={
                        'object_cnt': len(ann['objects']),
                        'tags': ann['tags']
                    })

    # We are to report progress of task over sly.ProgressCounter if we want to observe the progress in web panel.
    # In fact one task may report progress for some sequential (not nested) subtasks,
    # but here we will report training progress only.
    progress = sly.progress_counter_train(cnt_epochs, cnt_iters_per_epoch)

    epoch_flt = 0
    for epoch in range(cnt_epochs):
        logger.info("Epoch started", extra={'epoch': epoch})

        for train_iter in range(cnt_iters_per_epoch):
            logger.info('Some forward-backward pass...')
            time.sleep(1)

            progress.iter_done_report(
            )  # call it after every iteration to report progress
            epoch_flt = sly.epoch_float(epoch, train_iter + 1,
                                        cnt_iters_per_epoch)

            # And we are to report some metrics if we want to observe those amazing charts in web panel.
            # Regrettably, only the fixed metric types may be displayed now: 'loss', 'accuracy' and 'dice'.
            metric_values_train = {
                'loss': random.random(),
                'my_metric': random.uniform(0, 100)
            }
            sly.report_metrics_training(epoch_flt, metric_values_train)

        logger.info("Epoch finished", extra={'epoch': epoch})

        # Validation is not necessary but may be performed. So let's imitate validation...
        logger.info("Validation...")
        time.sleep(2)
        # Metrics for validation may also be reported.
        metric_values_val = {
            'loss': random.random(),
            'my_metric': random.uniform(0, 20)
        }
        sly.report_metrics_validation(epoch_flt, metric_values_val)

        # Save trained model weights when you want.
        # Model weights (checkpoint) should be written into directory provided by sly checkpoints_saver.
        # Content of the directory is entirely dependent on model implementation.
        cur_checkpoint_dir = checkpoints_saver.get_dir_to_write()
        dump_fake_model(cur_checkpoint_dir, model)
        checkpoints_saver.saved(is_best=True,
                                optional_data={
                                    'epoch': epoch_flt,
                                    'val_metrics': metric_values_val
                                })
        # It is necessary to call checkpoints_saver.saved after saving.
        # By default new model will be created from the best checkpoint over the whole training
        # (which is determined by "is_best" flag).
        # Some optional info may be provided. It will be linked with the checkpoint
        # and may help to distinguish checkpoints from same training.

    # Thank you for your patience.
    logger.info('Training finished')
예제 #20
0
 def _read_verif_status(self):
     if not osp.isfile(self.verif_status_path):
         raise RuntimeError('VERIFY_FAILED')
     res = sly.json_load(self.verif_status_path)
     self.download_images = res['download_images']
     self.is_archive = res['is_archive']
예제 #21
0
    def convert(self):
        # determine dir level by project meta file
        meta_p = sly.ProjectMeta.find_in_dir(self.in_dir)
        if meta_p:
            # meta_file in input dir
            in_project_root_dir, pr_name_stub = sly.ProjectFS.split_dir_project(self.in_dir)
        else:
            # meta file in subdir of input dir
            possible_projects = sly.get_subdirs(self.in_dir)
            if len(possible_projects) != 1:
                raise RuntimeError('Wrong input project structure, or multiple projects are passed.')
            in_project_root_dir, pr_name_stub = self.in_dir, possible_projects[0]

        # read if it's possible
        try:
            in_fs = sly.ProjectFS.from_disk(in_project_root_dir, pr_name_stub)
            in_pr_meta = sly.ProjectMeta.from_dir(in_fs.project_path)
        except Exception:
            logger.error('Unable to read input meta.', exc_info=False)
            raise

        in_possible_datasets = sly.get_subdirs(in_fs.project_path)
        in_datasets = list(in_fs.pr_structure.datasets.keys())
        if len(in_possible_datasets) != len(in_datasets):
            raise RuntimeError('Excess top-level directories without data (wrong img-ann structure?).')
        for ds_name, the_ds in in_fs.pr_structure.datasets.items():
            req_cnt = the_ds.image_cnt
            dataset_path = in_fs.dataset_path(ds_name)
            anns_path = in_fs.dataset_anns_path(dataset_path)
            imgs_path = in_fs.dataset_imgs_path(dataset_path)
            for subdir in (anns_path, imgs_path):
                items_cnt = len(list(os.scandir(subdir)))
                if items_cnt != req_cnt:
                    raise RuntimeError('Excess files or directories in dataset subdirectory.')

        found_exts = {x.ia_data['image_ext'] for x in in_fs}
        if not all(x in sly.ImportImgLister.extensions for x in found_exts):
            raise RuntimeError('Found image(s) with unsupported types (by extension).')
        sample_cnt = in_fs.pr_structure.image_cnt
        if sample_cnt == 0:
            raise RuntimeError('Empty project, no samples.')

        logger.info('Found source structure: Supervisely format, {} sample(s).'.format(sample_cnt))

        out_pr = deepcopy(in_fs.pr_structure)
        out_pr.name = self.settings['res_names']['project']
        out_pr_fs = sly.ProjectFS(self.out_dir, out_pr)
        out_pr_fs.make_dirs()

        in_pr_meta.to_dir(out_pr_fs.project_path)

        progress = sly.progress_counter_import(out_pr.name, out_pr.image_cnt)
        for s in out_pr_fs:
            try:
                src_img_path = in_fs.img_path(s.ds_name, s.image_name)
                sly.copy_file(src_img_path, s.img_path)  # img is ready

                src_ann_path = in_fs.ann_path(s.ds_name, s.image_name)
                packed_ann = sly.json_load(src_ann_path)
                _ = sly.Annotation.from_packed(packed_ann, in_pr_meta)  # to check if it is correct
                sly.copy_file(src_ann_path, s.ann_path)  # ann is ready
            except Exception:
                logger.error('Error occurred while processing input sample', exc_info=False, extra={
                             'dataset_name': s.ds_name, 'image_name': s.image_name,
                             })
                raise
            progress.iter_done_report()
예제 #22
0
 def load(self):
     res = sly.json_load(self.train_config_fpath)
     return res
예제 #23
0
def main():
    logger.info('Hello world.')

    # It isn't necessary, but let's suppose that our data will be stored as for Supervisely task:
    # input in '/sly_task_data/data` and results in '/sly_task_data/results'.
    # So TaskPaths provides the paths.
    task_paths = sly.TaskPaths()

    in_pr_dir = task_paths.project_dir  # the paths includes project name

    in_pr_meta = sly.ProjectMeta.from_dir(in_pr_dir)
    # Now we've read meta of input project.
    logger.info('Input project meta: {} class(es).'.format(
        len(in_pr_meta.classes)))

    in_pr_fs = sly.ProjectFS.from_disk(
        *sly.ProjectFS.split_dir_project(in_pr_dir))
    # Now we've read project structure.
    logger.info(
        'Input project: "{}" contains {} dataset(s) and {} image(s).'.format(
            in_pr_fs.pr_structure.name, len(in_pr_fs.pr_structure.datasets),
            in_pr_fs.image_cnt))

    # It's convenient to create output project structure and store source file paths in ia_data.
    out_pr_structure = sly.ProjectStructure(
        'my_new_project')  # rename project... just for fun
    for item_descr in in_pr_fs:  # iterate over input project
        new_ia_data = {
            'src_ann_path': item_descr.ann_path,
            'src_img_path': item_descr.img_path,
            **item_descr.ia_data  # contains 'image_ext' which is required to write images
        }
        out_pr_structure.add_item(item_descr.ds_name, item_descr.image_name,
                                  new_ia_data)
    # ProjectFS will provide out file paths
    out_pr_fs = sly.ProjectFS(task_paths.results_dir, out_pr_structure)

    # We will add the rectangle to each annotation.
    new_class_title = 'new-region'
    rect_to_add = sly.Rect(left=20, top=20, right=50, bottom=100)

    # Ok, start processing.
    out_pr_fs.make_dirs()  # create all directories required for writing
    for item_descr in out_pr_fs:  # iterate over output project
        logger.info('Processing sample',
                    extra={
                        'dataset': item_descr.ds_name,
                        'image_name': item_descr.image_name
                    })

        # Copy image unchanged.
        sly.copy_file(item_descr.ia_data['src_img_path'], item_descr.img_path)

        # Read annotation.
        ann_packed = sly.json_load(item_descr.ia_data['src_ann_path'])
        ann = sly.Annotation.from_packed(ann_packed, in_pr_meta)

        # Add new figure to the annotation.
        # Method to construct figures returns iterable of new figures.
        # (e.g., line cropped with image bounds may produce some lines), but here we'll get not more than one figure
        # ...or no figures if image is less than 20x20.
        new_figures = sly.FigureRectangle.from_rect(new_class_title,
                                                    ann.image_size_wh,
                                                    rect_to_add)
        ann['objects'].extend(new_figures)

        # Save annotation.
        sly.json_dump(ann.pack(), item_descr.ann_path)

    # OK, and don't forget to create and save output project meta.
    # We'll save given data and add new class with shape "rectangle".
    out_pr_meta = deepcopy(in_pr_meta)
    out_pr_meta.classes.add({
        'title': new_class_title,
        'shape': 'rectangle',
        'color': '#FFFF00'
    })
    # Then store the meta.
    out_pr_meta.to_dir(out_pr_fs.project_path)

    logger.info('Done.')
예제 #24
0
def main():
    # Please note that auxiliary methods from sly (supervisely_lib) use supervisely_lib.logger to format output.
    # So don't replace formatters or handlers of the logger.
    # One may use other loggers or simple prints for other output, but it's recommended to use supervisely_lib.logger.
    logger.info('Hello ML world')
    print('Glad to see u')

    # TaskHelperTrain contains almost all needed to run inference as Supervisely task,
    # including task settings and paths to data and model.
    task_helper = sly.TaskHelperInference()

    # All settings and parameters are passed to task in json file.
    # Content of the file is entirely dependent on model implementation.
    inference_settings = task_helper.task_settings
    logger.info('Task settings are read',
                extra={'task_settings': inference_settings})

    # Let's imitate loading training model weights. Task acquires directory with the weights.
    # And content of the directory is entirely dependent on model implementation.
    model_dir = task_helper.paths.model_dir
    model = load_fake_model(model_dir)
    logger.info('Model weights are loaded', extra={'model_dir': model_dir})

    # We are going to read input project with data for inference.
    project_meta = task_helper.in_project_meta  # Project meta contains list of project classes.
    project_dir = task_helper.paths.project_dir
    project_fs = sly.ProjectFS.from_disk_dir_project(project_dir)
    # ProjectFS enlists all samples (image/annotation pairs) in input project.

    # We are to write inference results as sly project with same structure into provided results dir.
    # There is no need to save images, only annotations and project meta are required.
    results_dir = task_helper.paths.results_dir
    out_project_fs = sly.ProjectFS(results_dir, project_fs.pr_structure)

    # It's necessary to write project meta (with list of classes) for output project.
    out_meta = sly.ProjectMeta([{
        'title': 'hat',
        'shape': 'point',
        'color': '#FF0000'
    }])  # create meta
    out_meta.to_dir(out_project_fs.project_path)  # and save

    # We are to report progress of task over sly.ProgressCounter if we want to observe the progress in web panel.
    # In fact one task may report progress for some sequential (not nested) subtasks,
    # but here we will report inference progress only.
    ia_cnt = out_project_fs.pr_structure.image_cnt
    progress = sly.progress_counter_inference(cnt_imgs=ia_cnt)

    # Iterating over samples (image/annotation pairs) in input project.
    for item_descr in project_fs:
        logger.info('Processing input sample',
                    extra={
                        'dataset': item_descr.ds_name,
                        'image_name': item_descr.image_name
                    })

        # Open some image...
        img = cv2.imread(item_descr.img_path)
        logger.info('Read image from input project',
                    extra={
                        'width': img.shape[1],
                        'height': img.shape[0]
                    })

        # And read corresponding annotation...
        ann_packed = sly.json_load(item_descr.ann_path)
        ann = sly.Annotation.from_packed(ann_packed, project_meta)
        logger.info('Read annotation from input project',
                    extra={'tags': ann['tags']})

        logger.info('Some forward pass...')
        time.sleep(1)

        # Let's imitate inference output.
        # We are to save results as sly Figures in annotation.
        ann['objects'] = [sly.FigurePoint.from_pt('hat', (800, 800))
                          ]  # imagine that our model found the point
        out_ann_path = out_project_fs.ann_path(item_descr.ds_name,
                                               item_descr.image_name)
        sly.ensure_base_path(out_ann_path)  # create intermediate directories
        sly.json_dump(ann.pack(), out_ann_path)  # and save annotation
        # Note that there is no need to save image.

        progress.iter_done_report(
        )  # call it after every iteration to report progress

    # It's necessary to report that the inference task is finished.
    sly.report_inference_finished()

    # Thank you for your patience.
    logger.info('Applying finished.')
예제 #25
0
def main():
    logger.info('Hello world.')

    # It isn't necessary, but let's suppose that our data will be stored as for Supervisely task:
    # input in '/sly_task_data/data` and results in '/sly_task_data/results'.
    # So TaskPaths provides the paths.
    task_paths = sly.TaskPaths()

    project_dir = task_paths.project_dir  # the paths includes project name

    project_meta = sly.ProjectMeta.from_dir(project_dir)
    # Now we've read meta of input project.
    logger.info('Input project meta: {} class(es).'.format(len(project_meta.classes)))

    project_fs = sly.ProjectFS.from_disk(*sly.ProjectFS.split_dir_project(project_dir))
    # Now we've read project structure.
    logger.info('Input project: "{}" contains {} dataset(s) and {} image(s).'.format(
        project_fs.pr_structure.name,
        len(project_fs.pr_structure.datasets),
        project_fs.image_cnt
    ))

    # prepare color mapping
    color_mapping = {}
    for cls_descr in project_meta.classes:
        color_s = cls_descr.get('color')
        if color_s is not None:
            color = sly.hex2rgb(color_s)  # use color from project meta if exists
        else:
            color = sly.get_random_color()  # or use random color otherwise
        color_mapping[cls_descr['title']] = color

    # enumerate all input samples (image/annotation pairs)
    for item_descr in project_fs:
        logger.info('Processing input sample',
                    extra={'dataset': item_descr.ds_name, 'image_name': item_descr.image_name})

        # Open image
        img = cv2.imread(item_descr.img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # to work with r-g-b colors

        # And read corresponding annotation.
        ann_packed = sly.json_load(item_descr.ann_path)
        ann = sly.Annotation.from_packed(ann_packed, project_meta)

        # Draw annotations on image
        for fig in ann['objects']:
            color = color_mapping.get(fig.class_title)
            fig.draw(img, color)
            # Note that this method draws lines with width 1, and points as single pixels.

        # Save image. Please note that we just save images, not new Supervisely project.
        src_image_ext = item_descr.ia_data['image_ext']  # let's preserve source image format (by extension)
        out_fpath = osp.join(
            task_paths.results_dir, item_descr.project_name, item_descr.ds_name, item_descr.image_name + src_image_ext
        )
        sly.ensure_base_path(out_fpath)  # create intermediate dirs if required

        img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)  # to work with r-g-b colors
        cv2.imwrite(out_fpath, img)  # write image

    logger.info('Done.')