示例#1
0
def main_train_test(ini, common_info, logger=None):
    # Init. local variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    img_size, batch, epoch, data_yaml_path, model_yaml_path, model_weight_path, rst_dir_name = \
        ini['img_size'], ini['batch'], ini['epoch'], ini['data_yaml_path'], ini['model_yaml_path'], ini['model_weight_path'], ini['rst_dir_name']

    train_cmd = ini['train_py_cmd']
    train_args = [
        '--img', img_size, '--batch', batch, '--epoch', epoch, '--data',
        data_yaml_path, '--cfg', model_yaml_path, '--weight',
        model_weight_path, '--name', rst_dir_name
    ]

    for arg in train_args:
        train_cmd += ''.join([' ', arg])

    logger.info(" [TRAIN] # Train shell cmd : {}".format(train_cmd))
    subprocess.call(train_cmd, shell=True,
                    cwd=ini['train_root_path'])  # train by python
    # subprocess.call(train_cmd, shell=True, cwd=ini['train_root_path'])    # train by shell

    return True
示例#2
0
def main_generate(ini, common_info, logger=None):
    # Init. local variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    cg.folder_exists(vars['gt_path'], create_=True)

    img_fnames = sorted(
        cg.get_filenames(vars['img_path'], extensions=ig.IMG_EXTENSIONS))
    ann_fnames = sorted(
        cg.get_filenames(vars['ann_path'], extensions=jg.META_EXTENSION))
    logger.info(
        " [GENERATE] # Total file number to be processed: {:d}.".format(
            len(img_fnames)))

    for idx, img_fname in enumerate(img_fnames):
        _, img_core_name, img_ext = cg.split_fname(img_fname)
        img = ig.imread(img_fname, color_fmt='RGB')

        # Load json
        ann_fname = ann_fnames[idx]
        _, ann_core_name, _ = cg.split_fname(ann_fname)
        ann_core_name = ann_core_name.replace('.jpg', '')
        if ann_core_name == img_core_name:
            with open(ann_fname) as json_file:
                json_data = json.load(json_file)
                objects = json_data['objects']
                # pprint.pprint(objects)

        bboxes = []
        texts = []
        for obj in objects:
            class_name = obj['classTitle']
            if class_name != common_info['dataset_type'].lower():
                continue

            [x1, y1], [x2, y2] = obj['points']['exterior']
            text = obj['description']
            x_min, y_min, x_max, y_max = int(min(x1, x2)), int(min(
                y1, y2)), int(max(x1, x2)), int(max(y1, y2))
            if x_max - x_min <= 0 or y_max - y_min <= 0:
                continue

            rect4 = ic.convert_rect2_to_rect4([x_min, x_max, y_min, y_max])
            bboxes.append(rect4)
            texts.append(text)

        file_utils.saveResult(img_file=img_core_name,
                              img=img,
                              boxes=bboxes,
                              texts=texts,
                              dirname=vars['gt_path'])
        logger.info(" [GENERATE-OCR] # Generated to {} ({:d}/{:d})".format(
            vars['gt_path'] + img_core_name + '.txt', (idx + 1),
            len(img_fnames)))

    logger.info(" # {} in {} mode finished.".format(_this_basename_, GENERATE))
    return True
示例#3
0
def main(args):
    ini = cg.get_ini_parameters(args.ini_fname)
    common_info = {}
    for key, val in ini['COMMON'].items():
        common_info[key] = val

    logger = cl.setup_logger_with_ini(ini['LOGGER'],
                                      logging_=args.logging_,
                                      console_=args.console_logging_)

    if args.op_mode == PREPROCESS_ALL:
        # Preprocess ko, math dataset
        dataset_types = KO_MATH.split('_')
        for dataset_type in dataset_types:
            # Reload ini
            ini = cg.get_ini_parameters(
                f'craft_learn_{dataset_type.lower()}.ini')
            common_info = {}
            for key, val in ini['COMMON'].items():
                common_info[key] = val

            # Init. local variables
            vars = {}
            for key, val in ini[PREPROCESS_ALL].items():
                vars[key] = cs.replace_string_from_dict(val, common_info)

            # Run generate & split
            tgt_dir_names = vars['tgt_dir_names'].replace(' ', '').split(',')
            for tgt_dir_name in tgt_dir_names:
                common_info['tgt_dir_name'] = tgt_dir_name
                main_generate(ini[GENERATE], common_info, logger=logger)
                main_split(ini[SPLIT], common_info, logger=logger)

            # Run merge
            main_merge(ini[MERGE], common_info, logger=logger)

    elif args.op_mode == GENERATE:
        main_generate(ini[GENERATE], common_info, logger=logger)
    elif args.op_mode == SPLIT:
        main_split(ini[SPLIT], common_info, logger=logger)
    elif args.op_mode == MERGE:
        main_merge(ini[MERGE], common_info, logger=logger)
    elif args.op_mode == TRAIN:
        main_train(ini[TRAIN], common_info, logger=logger)
    elif args.op_mode == TEST:
        main_test(ini[TEST], common_info, logger=logger)
    elif args.op_mode == TRAIN_TEST:
        ret, model_dir = main_train(ini[TRAIN], common_info, logger=logger)
        main_test(ini[TEST], common_info, logger=logger)
        print(" # Trained model directory is {}".format(model_dir))
    elif args.op_mode == SPLIT_TEXTLINE:
        main_split_textline(ini[SPLIT_TEXTLINE], common_info, logger=logger)
    else:
        print(" @ Error: op_mode, {}, is incorrect.".format(args.op_mode))

    return True
示例#4
0
def main_train(ini, common_info, logger=None):
    # Init. path variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    cuda_ids = vars['cuda_ids'].split(',')
    latest_model_dir = cg.get_model_dir(root_dir=vars['root_model_path'],
                                        model_file=vars['model_name'],
                                        version='latest')
    latest_model_path = os.path.join(latest_model_dir, vars['model_name'])

    train_args = [
        '--tgt_class',
        common_info['tgt_class'],
        '--img_path',
        vars['train_img_path'],
        '--gt_path',
        vars['train_gt_path'],
        '--pretrain_model_path',
        latest_model_path,
        '--cuda',
        vars['cuda'],
        '--cuda_ids',
        cuda_ids,
        '--resume',
        vars['resume'],
        '--valid_epoch',
        vars['valid_epoch'],
        '--batch_size',
        vars['batch_size'],
        '--learning_rate',
        vars['learning_rate'],
        '--momentum',
        vars['momentum'],
        '--weight_decay',
        vars['weight_decay'],
        '--gamma',
        vars['gamma'],
        '--num_workers',
        vars['num_workers'],
    ]

    train.main(train.parse_arguments(train_args), logger=logger)

    return True
示例#5
0
def main_split_textline(ini, common_info, logger=None):
    # Init. path variables
    global box_color, rst_dir_name
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    except_dir_names = vars['except_dir_names'].replace(' ', '').split(',')
    img_mode = vars['img_mode']
    link_, copy_, border_, save_detect_box_img_, save_refine_box_img_ = \
        cs.string_to_boolean(vars['link_']), cs.string_to_boolean(vars['copy_']), cs.string_to_boolean(vars['border_']), \
        cs.string_to_boolean(vars['save_detect_box_img_']), cs.string_to_boolean(vars['save_refine_box_img_'])

    # Init. CRAFT
    gpu_ = cs.string_to_boolean(vars['cuda'])
    device = torch.device('cuda' if (
        torch.cuda.is_available() and gpu_) else 'cpu')

    ko_model_dir, math_model_dir = cg.get_model_dir(root_dir=vars['ko_model_path'], model_file=vars['ko_model_name']), \
                                        cg.get_model_dir(root_dir=vars['math_model_path'], model_file=vars['math_model_name'])
    ko_detector = get_detector(os.path.join(ko_model_dir,
                                            vars['ko_model_name']),
                               device,
                               quantize=False)
    math_detector = get_detector(os.path.join(math_model_dir,
                                              vars['math_model_name']),
                                 device,
                                 quantize=False)

    easyocr_ini = cg.get_ini_parameters(
        os.path.join(_this_folder_, vars['ocr_ini_fname']))
    craft_params = load_craft_parameters(easyocr_ini['CRAFT'])

    project = sly.Project(directory=vars['textline_dataset_path'],
                          mode=sly.OpenMode.READ,
                          block_directories=except_dir_names)

    # Preprocess datasets
    if link_:
        link_or_copy_datasets(src_dir_path=vars['textline_dataset_path'],
                              dst_dir_path=vars['refine_dataset_path'],
                              dir_names=project.datasets.keys(),
                              except_dir_names=except_dir_names,
                              tgt_dir_name='img/',
                              mode=LINK,
                              logger=logger)

    if copy_:
        link_or_copy_datasets(src_dir_path=vars['textline_dataset_path'],
                              dst_dir_path=vars['refine_dataset_path'],
                              dir_names=project.datasets.keys(),
                              except_dir_names=except_dir_names,
                              tgt_dir_name='ann/',
                              mode=COPY,
                              logger=logger)

    # Load and split textlines
    for dataset in project:
        sly.logger.info('Processing dataset: {}/{}'.format(
            project.name, dataset.name))

        for item_idx, item_name in enumerate(dataset):
            item_paths = dataset.get_item_paths(item_name)
            ann, json_data = sly.Annotation.load_json_file(
                item_paths.ann_path, project.meta)

            raw_img = sly.image.read(item_paths.img_path)
            draw_detect_img, draw_refine_img = raw_img.copy(), raw_img.copy()

            # Draw textline box
            for label in ann.labels:
                if label.obj_class.name == textline:
                    label.geometry.draw_contour(
                        draw_detect_img,
                        color=label.obj_class.color,
                        config=label.obj_class.geometry_config,
                        thickness=3)
                    label.geometry.draw_contour(
                        draw_refine_img,
                        color=label.obj_class.color,
                        config=label.obj_class.geometry_config,
                        thickness=3)

            draw_detect_img = ((draw_detect_img.astype(np.uint16) +
                                raw_img.astype(np.uint16)) / 2).astype(
                                    np.uint8)
            draw_refine_img = ((draw_refine_img.astype(np.uint16) +
                                raw_img.astype(np.uint16)) / 2).astype(
                                    np.uint8)

            # Get textline ground truths
            gt_objs = []
            for idx, label in reversed(list(enumerate(ann.labels))):
                if label.obj_class.name != textline:
                    crop_img = raw_img[
                        label.geometry.top:label.geometry.bottom,
                        label.geometry.left:label.geometry.right]
                    if crop_img.size == 0:
                        continue

                    crop_box, ret_ = ip.get_binary_area_coordinates_by_threshold(
                        crop_img, min_thresh=127, max_thresh=255)
                    if ret_:
                        crop_box_obj = ic.Box(crop_box)
                        proc_box = ic.calc_global_box_pos_in_box(
                            g_box=[
                                label.geometry.left, label.geometry.right,
                                label.geometry.top, label.geometry.bottom
                            ],
                            box=crop_box_obj.rect2,
                            format='rect2')
                        min_x, max_x, min_y, max_y = proc_box
                        # debug_img = raw_img[min_y:max_y, min_x:max_x]
                        # print('Prev geo. : ', ann.labels[idx].geometry.left, ann.labels[idx].geometry.right, ann.labels[idx].geometry.top, ann.labels[idx].geometry.bottom)

                        # Remove label
                        ann = ann.delete_label(label)

                        # update coordinates
                        crop_labels = label.crop(
                            sly.Rectangle(min_y, min_x, max_y,
                                          max_x))  # top, left, bottom, right,
                        for crop_label in crop_labels:
                            ann = ann.add_label(crop_label)
                        # print('Next geo. : ', ann.labels[idx].geometry.left, ann.labels[idx].geometry.right, ann.labels[idx].geometry.top, ann.labels[idx].geometry.bottom)

                    continue

                # Remove textline object
                ann = ann.delete_label(label)

                if (label.geometry.right - label.geometry.left) <= 0 or (
                        label.geometry.bottom - label.geometry.top) <= 0:
                    continue

                gt_box = ic.Box(
                    box=[[label.geometry.left, label.geometry.top],
                         [label.geometry.right, label.geometry.bottom]])
                gt_obj = object.Object(name=textline,
                                       box_obj=gt_box,
                                       description=label.description.strip())
                gt_objs.append(gt_obj)

            # Get predict results
            pred_objs = []
            for detector in [ko_detector, math_detector]:
                tgt_class = ko if (detector is ko_detector) else (math if (
                    detector is math_detector) else 'None')

                # # Make border
                border_margin = 0
                if border_:
                    border_color = ig.WHITE
                    border_margin = 30
                    raw_img = cv2.copyMakeBorder(raw_img,
                                                 border_margin,
                                                 border_margin,
                                                 border_margin,
                                                 border_margin,
                                                 cv2.BORDER_CONSTANT,
                                                 value=border_color)

                boxes = get_textbox(
                    detector,
                    raw_img,
                    canvas_size=craft_params['canvas_size'],
                    mag_ratio=craft_params['mag_ratio'],
                    text_threshold=craft_params['text_threshold'],
                    link_threshold=craft_params['link_threshold'],
                    low_text=craft_params['low_text'],
                    poly=False,
                    device=device,
                    optimal_num_chars=True)

                if border_:
                    boxes = [
                        np.array([
                            box[0] - border_margin, box[1] - border_margin,
                            box[2] - border_margin, box[3] - border_margin,
                            box[4] - border_margin, box[5] - border_margin,
                            box[6] - border_margin, box[7] - border_margin
                        ]) for box in boxes
                    ]

                horizontal_list, _ = group_text_box(
                    boxes, craft_params['slope_ths'],
                    craft_params['ycenter_ths'], craft_params['height_ths'],
                    craft_params['width_ths'], craft_params['add_margin'])

                for h_box in horizontal_list:
                    pred_box = ic.Box(
                        box=[[h_box[0], h_box[2]], [h_box[1], h_box[3]]])
                    pred_obj = object.Object(name=tgt_class,
                                             box_obj=pred_box,
                                             description='')
                    pred_objs.append(pred_obj)

                    if tgt_class == ko:
                        box_color = ig.BROWN
                    if tgt_class == math:
                        box_color = ig.MAGENTA

                    draw_detect_img = ip.draw_box_on_img(draw_detect_img,
                                                         pred_box.flat_box,
                                                         color=box_color,
                                                         thickness=2)

            # Save result image
            ko_model_epoch, math_model_epoch = vars['ko_model_name'].split('_')[-1].replace('.pth', ''), \
                                               vars['math_model_name'].split('_')[-1].replace('.pth', '')
            rst_dir_name = f'{ko}_' + ko_model_epoch + '_' + f'{math}_' + math_model_epoch
            rst_dir_path = os.path.join(vars['rst_path'], rst_dir_name,
                                        'draw_box')
            if save_detect_box_img_:
                cg.folder_exists(rst_dir_path, create_=True)
                ig.imwrite(
                    draw_detect_img,
                    os.path.join(rst_dir_path, f'[{img_mode}] ' + item_name))

            # Compare GT. & PRED.
            refine_gts = refine_ground_truths_by_predict_values(
                gt_objs, pred_objs, raw_img)  # test input : GTS, PREDS

            # Draw refined boxes & texts
            if save_refine_box_img_:
                for (rf_box, rf_text, rf_class) in refine_gts:
                    rf_rect2 = ic.convert_rect4_to_rect2(rf_box)
                    x_min, x_max, y_min, y_max = rf_rect2
                    box = (x_min, y_min, x_max, y_max)

                    if rf_class == ko:
                        box_color = ig.BROWN
                    if rf_class == math:
                        box_color = ig.MAGENTA

                    # Draw boxes
                    draw_refine_img = ip.draw_box_on_img(draw_refine_img,
                                                         box,
                                                         color=box_color,
                                                         thickness=3)

                    # Draw texts (for 한글)
                    pil_img = Image.fromarray(draw_refine_img)
                    draw = ImageDraw.Draw(pil_img)
                    font = cg.KOR_FONT
                    margin_x, margin_y = 10, 45
                    draw.text(xy=((x_min + 1 + margin_x),
                                  (y_min + 1 + margin_y)),
                              text=rf_text,
                              font=font,
                              fill=box_color)

                    draw_refine_img = np.array(pil_img)

                rst_dir_path = os.path.join(vars['rst_path'], rst_dir_name,
                                            'refine_box')
                cg.folder_exists(rst_dir_path, create_=True)
                ig.imwrite(
                    draw_refine_img,
                    os.path.join(rst_dir_path, f'[{img_mode}] ' + item_name))

            # Insert refine_gts to json
            if len(ann.labels) > 0:
                obj_id = ann.labels[-1].geometry.sly_id + 1
            else:
                obj_id = 0
            refine_json_data, refine_obj_id = update_json_from_results(
                ann.to_json(), obj_id, [ko, math], refine_gts)

            # Save refined json
            rst_ann_fname = item_paths.ann_path.replace(
                vars['textline_dataset_path'], vars['refine_dataset_path'])
            with open(rst_ann_fname, 'w', encoding='utf-8') as f:
                json.dump(refine_json_data, f, ensure_ascii=False, indent=4)

            sly.logger.info('[{}/{}] Refined json path : {}'.format(
                item_idx + 1, len(dataset), rst_ann_fname))

    logger.info(" # {} in {} mode finished.".format(_this_basename_, OP_MODE))
    return True
示例#6
0
def main_merge(ini, common_info, logger=None):
    # Init. path variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    cg.folder_exists(vars['total_dataset_path'], create_=True)

    datasets = [
        dataset for dataset in os.listdir(vars['dataset_path'])
        if (dataset != 'total') and ('meta.json' not in dataset)
    ]
    sort_datasets = sorted(datasets, key=lambda x: (int(x.split('_')[0])))

    lower_dataset_type = common_info['dataset_type'].lower(
    ) if common_info['dataset_type'] != TEXTLINE else ''
    if lower_dataset_type:
        tgt_dir = 'craft_{}_gt'.format(lower_dataset_type)
    else:
        tgt_dir = 'craft_gt'
    if len(sort_datasets) != 0:
        for dir_name in sort_datasets:
            src_train_path, src_test_path = os.path.join(vars['dataset_path'], dir_name, TRAIN.lower()), \
                                                os.path.join(vars['dataset_path'], dir_name, TEST.lower())
            src_train_img_path, src_train_gt_path = os.path.join(src_train_path, 'img/'), \
                                                        os.path.join(src_train_path, tgt_dir + '/')
            src_test_img_path, src_test_gt_path = os.path.join(src_test_path, 'img/'), \
                                                    os.path.join(src_test_path, tgt_dir + '/')

            dst_train_path, dst_test_path = os.path.join(vars['total_dataset_path'], TRAIN.lower()), \
                                                os.path.join(vars['total_dataset_path'], TEST.lower())
            dst_train_img_path, dst_train_gt_path = os.path.join(dst_train_path, 'img/'), \
                                                        os.path.join(dst_train_path, tgt_dir + '/')
            dst_test_img_path, dst_test_gt_path = os.path.join(dst_test_path, 'img/'), \
                                                    os.path.join(dst_test_path, tgt_dir + '/')

            if cg.folder_exists(dst_train_img_path) and cg.folder_exists(dst_train_gt_path) and \
                    cg.folder_exists(dst_test_img_path) and cg.folder_exists(dst_test_gt_path):
                logger.info(" # Already {} is exist".format(
                    vars['total_dataset_path']))
            else:
                cg.folder_exists(dst_train_img_path,
                                 create_=True), cg.folder_exists(
                                     dst_train_gt_path, create_=True)
                cg.folder_exists(dst_test_img_path,
                                 create_=True), cg.folder_exists(
                                     dst_test_gt_path, create_=True)

            # Apply symbolic link for gt & img path
            for op_mode in [TRAIN, TEST]:
                if op_mode == TRAIN:
                    src_img_path, src_gt_path = src_train_img_path, src_train_gt_path
                    dst_img_path, dst_gt_path = dst_train_img_path, dst_train_gt_path
                elif op_mode == TEST:
                    src_img_path, src_gt_path = src_test_img_path, src_test_gt_path
                    dst_img_path, dst_gt_path = dst_test_img_path, dst_test_gt_path

                # link img_path
                img_sym_cmd = 'ln "{}"* "{}"'.format(
                    src_img_path, dst_img_path)  # to all files
                subprocess.call(img_sym_cmd, shell=True)
                logger.info(" # Link img files {}\n{}->{}.".format(
                    src_img_path, MARGIN, dst_img_path))

                # link gt_path
                gt_sym_cmd = 'ln "{}"* "{}"'.format(
                    src_gt_path, dst_gt_path)  # to all files
                subprocess.call(gt_sym_cmd, shell=True)
                logger.info(" # Link gt files {}\n{}->{}.".format(
                    src_gt_path, MARGIN, dst_gt_path))

    logger.info(" # {} in {} mode finished.".format(_this_basename_, OP_MODE))
    return True
示例#7
0
def main_split(ini, common_info, logger=None):
    # Init. path variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    cg.folder_exists(vars['img_path'], create_=False)
    cg.folder_exists(vars['gt_path'], create_=False)
    cg.folder_exists(vars['train_path'], create_=False)
    cg.folder_exists(vars['test_path'], create_=False)

    train_ratio = float(vars['train_ratio'])
    test_ratio = round(1.0 - train_ratio, 2)

    lower_dataset_type = common_info['dataset_type'].lower(
    ) if common_info['dataset_type'] != TEXTLINE else ''
    if lower_dataset_type:
        tgt_dir = 'craft_{}_gt'.format(lower_dataset_type)
    else:
        tgt_dir = 'craft_gt'
    gt_list = sorted(
        cg.get_filenames(vars['gt_path'], extensions=cg.TEXT_EXTENSIONS))
    train_gt_list, test_gt_list = train_test_split(gt_list,
                                                   train_size=train_ratio,
                                                   random_state=2000)
    train_img_list, test_img_list = [gt_path.replace(tgt_dir, 'img').replace('.txt', '.jpg').replace('gt_', '') for
                                     gt_path in train_gt_list], \
                                    [gt_path.replace(tgt_dir, 'img').replace('.txt', '.jpg').replace('gt_', '') for
                                     gt_path in test_gt_list]

    train_img_path, test_img_path = os.path.join(vars['train_path'],
                                                 'img/'), os.path.join(
                                                     vars['test_path'], 'img/')
    train_gt_path, test_gt_path = os.path.join(vars['train_path'],
                                               tgt_dir + '/'), os.path.join(
                                                   vars['test_path'],
                                                   tgt_dir + '/')
    cg.folder_exists(train_img_path,
                     create_=True), cg.folder_exists(test_img_path,
                                                     create_=True)
    cg.folder_exists(train_gt_path,
                     create_=True), cg.folder_exists(test_gt_path,
                                                     create_=True)

    # Apply symbolic link for gt & img path
    if len(gt_list) != 0:
        for op_mode in [TRAIN, TEST]:
            if op_mode == TRAIN:
                gt_list = train_gt_list
                img_list = train_img_list

                gt_link_path = train_gt_path
                img_link_path = train_img_path
            elif op_mode == TEST:
                gt_list = test_gt_list
                img_list = test_img_list

                gt_link_path = test_gt_path
                img_link_path = test_img_path

            # link gt files
            for gt_path in gt_list:
                gt_sym_cmd = 'ln "{}" "{}"'.format(
                    gt_path, gt_link_path)  # to all files
                subprocess.call(gt_sym_cmd, shell=True)
            logger.info(" # Link gt files {}\n{}->{}.".format(
                gt_list[0], MARGIN, gt_link_path))

            # link img files
            for img_path in img_list:
                img_sym_cmd = 'ln "{}" "{}"'.format(
                    img_path, img_link_path)  # to all files
                subprocess.call(img_sym_cmd, shell=True)
            logger.info(" # Link img files {}\n{}->{}.".format(
                img_list[0], MARGIN, img_link_path))

    print(" # (train, test) = ({:d}, {:d}) -> {:d} % ".format(
        len(train_gt_list), len(test_gt_list),
        int(
            float(len(train_gt_list)) /
            float(len(train_gt_list) + len(test_gt_list)) * 100)))
    return True
示例#8
0
def main_crop(ini, common_info, logger=None):
    # Init. local variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    cg.folder_exists(ini['img_path'], create_=True)

    raw_path = os.path.join(_project_folder_, ini['raw_path'])
    ann_path = os.path.join(_project_folder_, ini['ann_path'])
    raw_fnames = sorted(
        cg.get_filenames(raw_path, extensions=ig.IMG_EXTENSIONS))
    ann_fnames = sorted(
        cg.get_filenames(ann_path, extensions=jg.META_EXTENSION))
    logger.info(" [CROP] # Total file number to be processed: {:d}.".format(
        len(raw_fnames)))

    for idx, raw_fname in enumerate(raw_fnames):
        logger.info(" [CROP] # Processing {} ({:d}/{:d})".format(
            raw_fname, (idx + 1), len(raw_fnames)))

        _, raw_core_name, raw_ext = cg.split_fname(raw_fname)
        img = ig.imread(raw_fname, color_fmt='RGB')

        # Load json
        ann_fname = ann_fnames[idx]
        _, ann_core_name, _ = cg.split_fname(ann_fname)
        if ann_core_name == raw_core_name + raw_ext:
            with open(ann_fname) as json_file:
                json_data = json.load(json_file)
                objects = json_data['objects']
                # pprint.pprint(objects)

        # Extract crop position
        object_cnt = 0
        for obj in objects:
            class_name = obj['classTitle']
            if class_name != ini['object_class']:
                continue

            [x1, y1], [x2, y2] = obj['points']['exterior']
            x_min, y_min, x_max, y_max = int(min(x1, x2)), int(min(
                y1, y2)), int(max(x1, x2)), int(max(y1, y2))
            if x_max - x_min <= 0 or y_max - y_min <= 0:
                continue

            try:
                crop_img = img[y_min:y_max, x_min:x_max]
            except TypeError:
                logger.error(" [CROP] # Crop error : {}".format(raw_fname))
                logger.error(" [CROP] # Error pos : {}, {}, {}, {}".format(
                    x_min, x_max, y_min, y_max))
                pass

            # Save cropped image
            rst_fpath = os.path.join(
                _project_folder_, ini['img_path'] + raw_core_name + '_' +
                str(object_cnt) + raw_ext)
            ig.imwrite(crop_img, rst_fpath)
            object_cnt += 1

    logger.info(" # {} in {} mode finished.".format(_this_basename_, OP_MODE))
    return True
示例#9
0
def main_split(ini, common_info, logger=None):
    # Init. local variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    cg.folder_exists(vars['img_path'], create_=False)

    if cg.file_exists(vars['train_path']):
        print(" @ Warning: train text file path, {}, already exists".format(
            vars["train_path"]))
        ans = input(" % Proceed (y/n) ? ")
        if ans.lower() != 'y':
            sys.exit()
    if cg.file_exists(vars['val_path']):
        print(" @ Warning: test text file path, {}, already exists".format(
            vars["val_path"]))
        ans = input(" % Proceed (y/n) ? ")
        if ans.lower() != 'y':
            sys.exit()

    # Apply symbolic link for img path
    raw_path = os.path.join(_project_folder_, vars['raw_path'])
    img_path = os.path.join(_project_folder_, vars['img_path'])
    cg.folder_exists(img_path, create_=True)

    img_fnames = sorted(
        cg.get_filenames(img_path, extensions=ig.IMG_EXTENSIONS))
    if len(img_fnames) == 0:
        sym_cmd = "ln -s {} {}".format(raw_path + '*',
                                       img_path)  # to all files
        subprocess.call(sym_cmd, shell=True)

    img_fnames = sorted(
        cg.get_filenames(img_path, extensions=ig.IMG_EXTENSIONS))

    train_ratio = float(vars['train_ratio'])
    test_ratio = (1.0 - train_ratio)

    train_img_list, test_img_list = train_test_split(img_fnames,
                                                     test_size=test_ratio,
                                                     random_state=2000)
    # Save train.txt file
    train_path = os.path.join(_project_folder_, vars['train_path'])
    with open(train_path, 'w') as f:
        f.write('\n'.join(train_img_list) + '\n')

    val_path = os.path.join(_project_folder_, vars['val_path'])
    with open(val_path, 'w') as f:
        f.write('\n'.join(test_img_list) + '\n')

    logger.info(" [SPLIT] # Train : Test ratio -> {} : {}".format(
        train_ratio, test_ratio))
    logger.info(" [SPLIT] # Train : Test size  -> {} : {}".format(
        len(train_img_list), len(test_img_list)))

    # Modify yaml file
    ref_yaml_path = os.path.join(_project_folder_, vars['ref_yaml_path'])
    with open(ref_yaml_path, 'r') as f:
        data = yaml.safe_load(f)

    data['train'] = os.path.join(_project_folder_, vars['train_path'])
    data['val'] = os.path.join(_project_folder_, vars['val_path'])
    data['names'] = common_info['obj_names'].replace(' ', '').split(',')
    data['nc'] = len(data['names'])

    # Save yaml file
    rst_yaml_path = os.path.join(_project_folder_, vars['rst_yaml_path'])
    with open(rst_yaml_path, 'w') as f:
        yaml.dump(data, f)
        pprint(data)

    logger.info(" # {} in {} mode finished.".format(_this_basename_, OP_MODE))
    return True
示例#10
0
def main_generate(ini, common_info, logger=None):
    # Init. local variables
    vars = {}
    for key, val in ini.items():
        vars[key] = cs.replace_string_from_dict(val, common_info)

    label_path = os.path.join(_project_folder_, vars['label_path'])
    cg.folder_exists(label_path, create_=True)

    raw_path = os.path.join(_project_folder_, vars['raw_path'])
    ann_path = os.path.join(_project_folder_, vars['ann_path'])
    raw_fnames = sorted(
        cg.get_filenames(raw_path, extensions=ig.IMG_EXTENSIONS))
    ann_fnames = sorted(
        cg.get_filenames(ann_path, extensions=jg.META_EXTENSION))
    logger.info(
        " [GENERATE] # Total file number to be processed: {:d}.".format(
            len(raw_fnames)))

    for idx, raw_fname in enumerate(raw_fnames):
        _, raw_core_name, raw_ext = cg.split_fname(raw_fname)
        img = ig.imread(raw_fname, color_fmt='RGB')
        h, w, c = img.shape

        # Load json
        ann_fname = ann_fnames[idx]

        _, ann_core_name, _ = cg.split_fname(ann_fname)
        if ann_core_name == raw_core_name + raw_ext:
            with open(ann_fname) as json_file:
                json_data = json.load(json_file)
                objects = json_data['objects']
                # pprint.pprint(objects)

        # Extract crop position
        obj_names = common_info['obj_names'].replace(' ', '').split(',')
        obj_type = common_info['obj_type']
        for obj in objects:
            obj_name = obj['classTitle']

            if obj_name not in obj_names:
                continue

            class_num = ObjInfo(obj_type, obj_name).get_class_number()

            [x1, y1], [x2, y2] = obj['points']['exterior']
            x_min, y_min, x_max, y_max = int(min(x1, x2)), int(min(
                y1, y2)), int(max(x1, x2)), int(max(y1, y2))
            if x_max - x_min <= 0 or y_max - y_min <= 0:
                continue

            # Save object info to COCO format
            rst_fpath = os.path.join(
                _project_folder_, vars['label_path'] + raw_core_name + '.txt')
            class_no, x_center, y_center, width, height = \
                str(class_num), str(((x_max+x_min)/2) / w), str(((y_max+y_min)/2) / h), str((x_max-x_min)/w), str((y_max-y_min)/h)

            if cg.file_exists(rst_fpath):
                logger.info(
                    " [GENERATE] # File already exist {} ({:d}/{:d})".format(
                        rst_fpath, (idx + 1), len(raw_fnames)))
            else:
                with open(rst_fpath, 'a') as f:
                    strResult = "{} {} {} {} {}\r\n".format(
                        class_no, x_center, y_center, width, height)
                    f.write(strResult)

                logger.info(
                    " [GENERATE] # File is saved {} ({:d}/{:d})".format(
                        rst_fpath, (idx + 1), len(raw_fnames)))

    logger.info(" # {} in {} mode finished.".format(_this_basename_, OP_MODE))
    return True