|
|
|
@ -0,0 +1,136 @@ |
|
|
|
|
#!/usr/bin/env python |
|
|
|
|
|
|
|
|
|
import os.path as osp |
|
|
|
|
from glob import glob |
|
|
|
|
|
|
|
|
|
from PIL import Image |
|
|
|
|
from tqdm import tqdm |
|
|
|
|
|
|
|
|
|
from common import (get_default_parser, add_crop_options, crop_patches, |
|
|
|
|
create_file_list, copy_dataset, create_label_list, |
|
|
|
|
get_path_tuples) |
|
|
|
|
|
|
|
|
|
# According to the official doc(https://github.com/CAPTAIN-WHU/iSAID_Devkit), |
|
|
|
|
# the files should be organized as follows: |
|
|
|
|
# |
|
|
|
|
# iSAID |
|
|
|
|
# ├── test |
|
|
|
|
# │ └── images |
|
|
|
|
# │ ├── P0006.png |
|
|
|
|
# │ └── ... |
|
|
|
|
# │ └── P0009.png |
|
|
|
|
# ├── train |
|
|
|
|
# │ └── images |
|
|
|
|
# │ ├── P0002_instance_color_RGB.png |
|
|
|
|
# │ ├── P0002_instance_id_RGB.png |
|
|
|
|
# │ ├── P0002.png |
|
|
|
|
# │ ├── ... |
|
|
|
|
# │ ├── P0010_instance_color_RGB.png |
|
|
|
|
# │ ├── P0010_instance_id_RGB.png |
|
|
|
|
# │ └── P0010.png |
|
|
|
|
# └── val |
|
|
|
|
# └── images |
|
|
|
|
# ├── P0003_instance_color_RGB.png |
|
|
|
|
# ├── P0003_instance_id_RGB.png |
|
|
|
|
# ├── P0003.png |
|
|
|
|
# ├── ... |
|
|
|
|
# ├── P0004_instance_color_RGB.png |
|
|
|
|
# ├── P0004_instance_id_RGB.png |
|
|
|
|
# └── P0004.png |
|
|
|
|
|
|
|
|
|
CLASSES = ('background', 'ship', 'storage_tank', 'baseball_diamond', |
|
|
|
|
'tennis_court', 'basketball_court', 'ground_track_field', 'bridge', |
|
|
|
|
'large_vehicle', 'small_vehicle', 'helicopter', 'swimming_pool', |
|
|
|
|
'roundabout', 'soccer_ball_field', 'plane', 'harbor') |
|
|
|
|
# Refer to https://github.com/Z-Zheng/FarSeg/blob/master/data/isaid.py |
|
|
|
|
COLOR_MAP = [[0, 0, 0], [0, 0, 63], [0, 191, 127], [0, 63, 0], [0, 63, 127], |
|
|
|
|
[0, 63, 191], [0, 63, 255], [0, 127, 63], [0, 127, 127], |
|
|
|
|
[0, 0, 127], [0, 0, 191], [0, 0, 255], [0, 63, 63], [0, 127, 191], |
|
|
|
|
[0, 127, 255], [0, 100, 155]] |
|
|
|
|
SUBSETS = ('train', 'val') |
|
|
|
|
SUBDIR = 'images' |
|
|
|
|
FILE_LIST_PATTERN = "{subset}.txt" |
|
|
|
|
LABEL_LIST_NAME = "labels.txt" |
|
|
|
|
URL = "" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def flatten(nested_list): |
|
|
|
|
flattened_list = [] |
|
|
|
|
for ele in nested_list: |
|
|
|
|
if isinstance(ele, list): |
|
|
|
|
flattened_list.extend(flatten(ele)) |
|
|
|
|
else: |
|
|
|
|
flattened_list.append(ele) |
|
|
|
|
return flattened_list |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def rgb2mask(rgb): |
|
|
|
|
palette = flatten(COLOR_MAP) |
|
|
|
|
# Pad with zero |
|
|
|
|
palette = palette + [0] * (256 * 3 - len(palette)) |
|
|
|
|
ref = Image.new(mode='P', size=(1, 1)) |
|
|
|
|
ref.putpalette(palette) |
|
|
|
|
mask = rgb.quantize(palette=ref, dither=0) |
|
|
|
|
return mask |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
parser = get_default_parser() |
|
|
|
|
parser.add_argument( |
|
|
|
|
'--crop_size', type=int, help="Size of cropped patches.", default=800) |
|
|
|
|
parser.add_argument( |
|
|
|
|
'--crop_stride', |
|
|
|
|
type=int, |
|
|
|
|
help="Stride of sliding windows when cropping patches. `crop_size` will be used only if `crop_size` is not None.", |
|
|
|
|
default=600) |
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
|
out_dir = osp.join(args.out_dataset_dir, |
|
|
|
|
osp.basename(osp.normpath(args.in_dataset_dir))) |
|
|
|
|
|
|
|
|
|
assert args.crop_size is not None |
|
|
|
|
# According to https://github.com/CAPTAIN-WHU/iSAID_Devkit/blob/master/preprocess/split.py |
|
|
|
|
# Set keep_last=True |
|
|
|
|
crop_patches( |
|
|
|
|
args.crop_size, |
|
|
|
|
args.crop_stride, |
|
|
|
|
data_dir=args.in_dataset_dir, |
|
|
|
|
out_dir=out_dir, |
|
|
|
|
subsets=SUBSETS, |
|
|
|
|
subdirs=(SUBDIR, ), |
|
|
|
|
glob_pattern='*.png', |
|
|
|
|
max_workers=8, |
|
|
|
|
keep_last=True) |
|
|
|
|
|
|
|
|
|
for subset in SUBSETS: |
|
|
|
|
path_tuples = [] |
|
|
|
|
print(f"Processing {subset} labels...") |
|
|
|
|
for im_subdir in tqdm(glob(osp.join(out_dir, subset, SUBDIR, "*/"))): |
|
|
|
|
im_name = osp.basename(im_subdir[:-1]) # Strip trailing '/' |
|
|
|
|
if '_' in im_name: |
|
|
|
|
# Do not process labels |
|
|
|
|
continue |
|
|
|
|
mask_subdir = osp.join(out_dir, subset, SUBDIR, |
|
|
|
|
im_name + '_instance_color_RGB') |
|
|
|
|
for mask_path in glob(osp.join(mask_subdir, '*.png')): |
|
|
|
|
# Convert RGB files to mask files (pseudo color) |
|
|
|
|
rgb = Image.open(mask_path).convert('RGB') |
|
|
|
|
mask = rgb2mask(rgb) |
|
|
|
|
# Write to the original location |
|
|
|
|
mask.save(mask_path) |
|
|
|
|
path_tuples.extend( |
|
|
|
|
get_path_tuples( |
|
|
|
|
im_subdir, |
|
|
|
|
mask_subdir, |
|
|
|
|
glob_pattern='*.png', |
|
|
|
|
data_dir=args.out_dataset_dir)) |
|
|
|
|
path_tuples.sort() |
|
|
|
|
|
|
|
|
|
file_list = osp.join( |
|
|
|
|
args.out_dataset_dir, FILE_LIST_PATTERN.format(subset=subset)) |
|
|
|
|
create_file_list(file_list, path_tuples) |
|
|
|
|
print(f"Write file list to {file_list}.") |
|
|
|
|
|
|
|
|
|
label_list = osp.join(args.out_dataset_dir, LABEL_LIST_NAME) |
|
|
|
|
create_label_list(label_list, CLASSES) |
|
|
|
|
print(f"Write label list to {label_list}.") |