upscale_coco.py 3.78 KB
Newer Older
yangzhong's avatar
yangzhong committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import argparse
import json
import os
import time

import cv2
import numpy as np
from coco import COCO


def parse_args():
    parser = argparse.ArgumentParser(description="Upscale COCO dataset")
    parser.add_argument(
        "--inputs",
        "-i",
        type=str,
        default="/coco",
        help="input directory for coco dataset",
    )
    parser.add_argument(
        "--outputs",
        "-o",
        type=str,
        default="/cocoup",
        help="output directory for upscaled coco dataset",
    )
    parser.add_argument(
        "--images", "-im", type=str, default="val2017", help="image directory"
    )
    parser.add_argument(
        "--annotations",
        "-a",
        type=str,
        default="annotations/instances_val2017.json",
        help="annotations directory",
    )
    parser.add_argument(
        "--size",
        required=True,
        type=int,
        nargs="+",
        help="upscaled image sizes (e.g 300 300, 1200 1200",
    )
    parser.add_argument(
        "--format",
        "-f",
        type=str,
        default="jpg",
        help="image format")
    return parser.parse_args()


def upscale_coco(indir, outdir, image_dir, annotate_file, size, fmt):
    # Build directories.
    print("Building directories...")
    size = tuple(size)
    image_in_path = os.path.join(indir, image_dir)
    image_out_path = os.path.join(outdir, image_dir)
    path, fil = os.path.split(annotate_file)
    annotate_out_path = os.path.join(outdir, path)
    annotate_out_file = os.path.join(annotate_out_path, fil)
    annotate_in_file = os.path.join(indir, annotate_file)
    if not os.path.exists(image_out_path):
        os.makedirs(image_out_path)
    if not os.path.exists(annotate_out_path):
        os.makedirs(annotate_out_path)

    # Read annotations.
    print("Reading COCO dataset...")
    coco = COCO(annotate_in_file)
    print(len(coco.imgs), "images")
    print(len(coco.anns), "annotations")

    # Upscale annotations.
    print("Upscaling annotations...")
    annotations = []
    for idx in coco.anns:
        ann = coco.anns[idx]
        # Scaling factors
        img = coco.imgs[ann["image_id"]]
        sx = size[0] / img["width"]
        sy = size[1] / img["height"]
        # Bounding boxes
        bb = ann["bbox"]
        bb[0] = bb[0] * sx
        bb[1] = bb[1] * sy
        bb[2] = bb[2] * sx
        bb[3] = bb[3] * sy
        # Area
        ann["area"] = ann["area"] * sx * sy
        annotations.append(ann)

    # Upscale images.
    print("Upscaling images...")
    count = 0
    images = []
    for idx in coco.imgs:
        img = coco.imgs[idx]
        # Load, upscale, and save image.
        image = cv2.imread(os.path.join(image_in_path, img["file_name"]))
        if len(image.shape) < 3 or image.shape[2] != 3:
            # some images might be grayscale
            image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
        image = cv2.resize(image, size, interpolation=cv2.INTER_LINEAR)
        cv2.imwrite(os.path.join(image_out_path,
                    img["file_name"][0:-3] + fmt), image)
        # Update image file extension
        img["file_name"] = img["file_name"][0:-3] + fmt
        # Image dimensions
        img["width"] = size[0]
        img["height"] = size[1]
        count = count + 1
        # print(count, end=' ', flush=True)
        images.append(img)

    # Save annotations.
    print("Saving annotations...")
    with open(annotate_in_file) as f:
        dataset = json.load(f)
    dataset["images"] = images
    dataset["annotations"] = annotations
    with open(annotate_out_file, "w") as outfile:
        json.dump(dataset, outfile)
    print("Done.")


def main():
    # Get arguments.
    args = parse_args()
    # Upscale coco.
    upscale_coco(
        args.inputs, args.outputs, args.images, args.annotations, args.size, args.format
    )


main()