예제 #1
0
def _crop_img_2d(img_path, annt_path, out_dir, sub_array=[3, 2]):
    get_sub_path = lambda sub_index, ori_path, out_dir: out_dir + '/' + os.path.splitext(
        os.path.basename(ori_path))[0] + '-%d' % (
            sub_index) + os.path.splitext(os.path.basename(ori_path))[1]

    img_ori = Image.open(img_path)
    img_size = img_ori.size
    grid_array = ([0] + [
        math.floor((i + 1) * img_size[0] / float(sub_array[0]))
        for i in range(sub_array[0])
    ], [0] + [
        math.floor((i + 1) * img_size[1] / float(sub_array[1]))
        for i in range(sub_array[1])
    ])

    annt_info, template_tree = ut.load_annt_file(annt_path)
    sub_index = 0
    for sub_index_x in range(sub_array[0]):
        for sub_index_y in range(sub_array[1]):
            sub_img_path = get_sub_path(sub_index, img_path, out_dir)
            sub_annt_path = get_sub_path(sub_index, annt_path, out_dir)
            x_min_img = grid_array[0][sub_index_x]
            y_min_img = grid_array[1][sub_index_y]
            x_max_img = grid_array[0][sub_index_x + 1] - 1
            y_max_img = grid_array[1][sub_index_y + 1] - 1
            img_box = np.array([x_min_img, y_min_img, x_max_img, y_max_img])
            objs_info = _prune_bndbox(annt_info, img_box)
            ut.save_annt_file(sub_annt_path, objs_info, template_tree)
            sub_img = img_ori.crop(
                (x_min_img, y_min_img, x_max_img + 1, y_max_img + 1))
            sub_img.save(sub_img_path)
            sub_index += 1
예제 #2
0
def _crop_img_slide_2d(img_path, annt_path, out_dir, sub_array=[3, 2]):
	get_sub_path = lambda sub_index, ori_path, out_dir:out_dir + '/' + os.path.splitext(os.path.basename(ori_path))[0] + '-%d'%(sub_index) + os.path.splitext(os.path.basename(ori_path))[1]

	img_ori = PIL.Image.open(img_path)
	img_size = img_ori.size
	sub_size = [math.floor(img_size[idx]/float(num_itm)) for idx, num_itm in enumrate(sub_array)]
	sub_array = [num_itm*2-1 for num_itm in sub_array]
	grid_array = ([math.floor(i*img_size[0]/float(sub_array[0]+1)) for i in range(sub_array[0])],
					[math.floor(i*img_size[1]/float(sub_array[1]+1)) for i in range(sub_array[1])])
	
	annt_info, template_tree = ut.load_annt_file(annt_path)
	sub_index = 0
	for sub_index_x in range(sub_array[0]):
		for sub_index_y in range(sub_array[1]):
			sub_img_path = get_sub_path(sub_index, img_path, out_dir)
			sub_annt_path = get_sub_path(sub_index, annt_path, out_dir)
			x_min_img = grid_array[0][sub_index_x]
			y_min_img = grid_array[1][sub_index_y]
			x_max_img = grid_array[0][sub_index_x] + sub_size[0]
			y_max_img = grid_array[1][sub_index_y] + sub_size[1]
			img_box = np.array([x_min_img, y_min_img, x_max_img, y_max_img])
			objs_info = _prune_bndbox(annt_info, img_box)
			ut.save_annt_file(sub_annt_path, objs_info, template_tree)
			sub_img = img_ori.crop((x_min_img, y_min_img, x_max_img+1, y_max_img+1))
			sub_img.save(sub_img_path)
			sub_index += 1
예제 #3
0
def _restore_img_slide_2d(img_path,
                          input_dir,
                          output_dir,
                          sub_array=[3, 2],
                          img_suffix='.jpg'):
    get_sub_path = lambda sub_index, file_name, output_dir, file_suffix: output_dir + '/' + file_name + '-%d' % (
        sub_index) + file_suffix

    file_name = os.path.splitext(os.path.basename(img_path))[0]
    img_ori = Image.open(img_path)
    img_size = img_ori.size
    sub_size = [
        math.floor(img_size[idx] / float(num_itm))
        for idx, num_itm in enumrate(sub_array)
    ]
    sub_array = [num_itm * 2 - 1 for num_itm in sub_array]
    grid_array = ([
        math.floor(i * img_size[0] / float(sub_array[0] + 1))
        for i in range(sub_array[0])
    ], [
        math.floor(i * img_size[1] / float(sub_array[1] + 1))
        for i in range(sub_array[1])
    ])

    boxes = np.empty(shape=[0, 4], dtype=np.uint16)
    gt_classes = []
    ishards = np.empty(shape=[0], dtype=np.int32)

    sub_index = 0
    for sub_index_x in range(sub_array[0]):
        for sub_index_y in range(sub_array[1]):
            sub_annt_path = get_sub_path(sub_index, file_name, input_dir,
                                         '.xml')
            sub_index += 1
            x_min_img = grid_array[0][sub_index_x]
            y_min_img = grid_array[1][sub_index_y]
            x_max_img = grid_array[0][sub_index_x] + sub_size[0]
            y_max_img = grid_array[1][sub_index_y] + sub_size[1]
            img_box = np.array([x_min_img, y_min_img, x_max_img, y_max_img])

            objs_info, template_tree = ut.load_annt_file(sub_annt_path)
            objs_info_restored = _restore_cord(objs_info, img_box)
            if objs_info_restored == None:
                continue

            boxes = np.append(boxes, objs_info['boxes'], axis=0)
            ishards = np.append(ishards, objs_info['gt_ishard'], axis=0)
            gt_classes.extend(objs_info['gt_classes_name'])

    objs_info = {
        'boxes': boxes,
        'gt_classes_name': gt_classes,
        'gt_ishard': ishards
    }
    annt_path = output_dir + '/' + file_name + '.xml'
    ut.save_annt_file(annt_path, objs_info)
예제 #4
0
def _aug_img_2d(img_path,
                annt_path,
                out_dir,
                own_data_classes,
                aug_factor=60,
                trim_size=1024,
                random_seed=False,
                overlap_th=0.4,
                ratio_th=2.5):
    get_sub_path = lambda sub_index, ori_path, out_dir: os.path.join(
        out_dir,
        os.path.splitext(os.path.basename(ori_path))[0] + '-%d' %
        (sub_index) + os.path.splitext(os.path.basename(ori_path))[1])

    try:
        im = imread(img_path)
        annt_info, template_tree = ut.load_annt_file(annt_path)
    except ValueError as e:
        print(e)
        return
    except OSError as e:
        print(e)
        return

    if len(annt_info['gt_classes_name']) == 0:
        print('no bndboxes in this file.')
        return

    # random crop
    if random_seed:
        random.seed(random_seed)
    gt_boxes_ori = torch.from_numpy(annt_info['boxes'].astype(np.float))
    class_to_ind_dict = dict(
        zip(own_data_classes, range(len(own_data_classes))))
    ind_to_class_dict = dict(
        zip(range(len(own_data_classes)), own_data_classes))
    gt_classes_np = np.array(
        [class_to_ind_dict[item] for item in annt_info['gt_classes_name']])
    gt_classes_ori = torch.from_numpy(gt_classes_np)

    gt_area = (gt_boxes_ori[:, 2] - gt_boxes_ori[:, 0]) * (gt_boxes_ori[:, 3] -
                                                           gt_boxes_ori[:, 1])
    gt_ratio = (gt_boxes_ori[:, 2] -
                gt_boxes_ori[:, 0]) / (gt_boxes_ori[:, 3] - gt_boxes_ori[:, 1])
    gt_ratio[gt_ratio > ratio_th - 1e-5] = 0
    gt_ratio[gt_ratio < 1.0 / ratio_th + 1e-5] = 0

    if torch.sum(gt_ratio) < 1e-5:
        return

    # crop img
    height, width = im.shape[0], im.shape[1]
    min_x_bnd = max(0, torch.min(gt_boxes_ori[:, 0]) - trim_size)
    min_y_bnd = max(0, torch.min(gt_boxes_ori[:, 1]) - trim_size)
    max_x_bnd = min(width - trim_size, torch.max(gt_boxes_ori[:, 2]))
    max_y_bnd = min(height - trim_size, torch.max(gt_boxes_ori[:, 3]))

    sub_index = 0
    for sub_index_x in range(aug_factor):
        sub_img_path = get_sub_path(sub_index, img_path, out_dir)
        sub_annt_path = get_sub_path(sub_index, annt_path, out_dir)

        while True:
            gt_boxes = gt_boxes_ori.clone()
            gt_classes = gt_classes_ori.clone()
            x_min_img, y_min_img = random.randint(min_x_bnd,
                                                  max_x_bnd), random.randint(
                                                      min_y_bnd, max_y_bnd)
            gt_boxes[:, ::2] = gt_boxes[:, ::2] - x_min_img
            gt_boxes[:, 1::2] = gt_boxes[:, 1::2] - y_min_img
            gt_boxes.clamp_(0, trim_size - 1)
            overlap = (gt_boxes[:, 2] - gt_boxes[:, 0]) * (
                gt_boxes[:, 3] - gt_boxes[:, 1]) / gt_area
            ratio = (gt_boxes[:, 2] - gt_boxes[:, 0]) / (gt_boxes[:, 3] -
                                                         gt_boxes[:, 1])
            boxes_width = gt_boxes[:, 2] - gt_boxes[:, 0]
            boxes_height = gt_boxes[:, 3] - gt_boxes[:, 1]
            # remove bndbox
            not_keep = (overlap < overlap_th) | (ratio > ratio_th) | (
                ratio <
                (1 / ratio_th)) | (boxes_width < 5) | (boxes_height < 5)
            keep = torch.nonzero(not_keep == 0).view(-1)
            if keep.numel() == 0:
                continue

            gt_boxes = gt_boxes[keep]
            gt_classes = gt_classes[keep]
            annt_info['boxes'] = gt_boxes.numpy().astype(np.uint16)
            annt_info['gt_classes_name'] = [
                ind_to_class_dict[item]
                for item in list(gt_classes.numpy().astype(np.int32))
            ]
            annt_info['ishards'] = np.zeros(len(
                annt_info['gt_classes_name'])).astype(np.int32)

            img = im[y_min_img:y_min_img + trim_size,
                     x_min_img:x_min_img + trim_size, :]
            break

        pil_img = Image.fromarray(img)

        ut.save_annt_file(sub_annt_path, annt_info, template_tree)
        pil_img.save(sub_img_path)
        sub_index += 1