Beispiel #1
0
def load_ss_data(coco_dir, data_name, cache_dir, input_size=None):
    """セマンティックセグメンテーションのデータの読み込み。"""
    from pycocotools import coco, mask as cocomask

    coco_dir = pathlib.Path(coco_dir)
    cache_dir = pathlib.Path(cache_dir)
    if isinstance(input_size, int):
        input_size = (input_size, input_size)

    coco = coco.COCO(
        str(coco_dir / "annotations" / f"instances_{data_name}.json"))

    class_names = [c["name"] for c in coco.loadCats(coco.getCatIds())]
    jsonclassid_to_index = {
        c["id"]: class_names.index(c["name"])
        for c in coco.loadCats(coco.getCatIds())
    }

    X, y = [], []
    for entry in utils.tqdm(coco.loadImgs(coco.getImgIds()),
                            desc="load_ss_data"):
        dirname, filename = entry["coco_url"].split("/")[-2:]
        save_path = cache_dir / dirname / (filename + ".npy")
        X.append(coco_dir / dirname / filename)
        y.append(save_path)
        if not save_path.exists():
            # 読み込み
            objs = coco.loadAnns(
                coco.getAnnIds(imgIds=entry["id"], iscrowd=None))
            mask = np.zeros(
                (entry["height"], entry["width"], len(class_names)),
                dtype=np.uint8)
            for obj in objs:
                if obj.get("ignore", 0) == 1:
                    continue
                rle = cocomask.frPyObjects(obj["segmentation"],
                                           entry["height"], entry["width"])
                m = cocomask.decode(rle)
                class_id = jsonclassid_to_index[obj["category_id"]]
                mask[:, :, class_id] |= m
            mask = np.where(mask, np.uint8(255), np.uint8(0))
            # リサイズ
            if input_size is not None:
                mask = ndimage.resize(mask, input_size[1], input_size[0])
            # 保存
            save_path.parent.mkdir(parents=True, exist_ok=True)
            np.save(str(save_path), mask)

    return np.array(X), np.array(y), class_names
Beispiel #2
0
def load_od_data(coco_dir, data_name, use_crowded):
    """物体検出のデータの読み込み。"""
    import pycocotools.coco

    coco_dir = pathlib.Path(coco_dir)
    coco = pycocotools.coco.COCO(
        str(coco_dir / "annotations" / f"instances_{data_name}.json"))

    class_names = [c["name"] for c in coco.loadCats(coco.getCatIds())]
    jsonclassid_to_index = {
        c["id"]: class_names.index(c["name"])
        for c in coco.loadCats(coco.getCatIds())
    }

    labels = []
    for entry in coco.loadImgs(coco.getImgIds()):
        dirname, filename = entry["coco_url"].split("/")[-2:]
        objs = coco.loadAnns(
            coco.getAnnIds(imgIds=entry["id"],
                           iscrowd=None if use_crowded else False))

        bboxes, classes, areas, crowdeds = [], [], [], []
        width, height = entry["width"], entry["height"]
        for obj in objs:
            if obj.get("ignore", 0) == 1:
                continue
            x, y, w, h = obj["bbox"]
            bbox = np.array([x, y, x + w, y + h]) / np.array(
                [width, height, width, height])
            bbox = np.clip(bbox, 0, 1)
            if (bbox[:2] < bbox[2:]).all():
                bboxes.append(bbox)
                classes.append(jsonclassid_to_index[obj["category_id"]])
                areas.append(obj["area"])
                crowdeds.append(obj["iscrowd"])

        labels.append(
            tk.od.ObjectsAnnotation(
                path=coco_dir / dirname / filename,
                width=width,
                height=height,
                classes=classes,
                bboxes=bboxes,
                areas=areas,
                crowdeds=crowdeds,
            ))
    return tk.od.ObjectsAnnotation.create_dataset(labels,
                                                  class_names=class_names)
Beispiel #3
0
def coco(writer, name_index, profile, row, verify=False):
    root = os.path.expanduser(os.path.expandvars(row['root']))
    year = str(row['year'])
    name = profile + year
    path = os.path.join(root, 'annotations', 'instances_%s.json' % name)
    if not os.path.exists(path):
        tf.logging.warn(path + ' not exists')
        return False
    import pycocotools.coco
    coco = pycocotools.coco.COCO(path)
    catIds = coco.getCatIds(catNms=list(name_index.keys()))
    cats = coco.loadCats(catIds)
    id_index = dict((cat['id'], name_index[cat['name']]) for cat in cats)
    imgIds = coco.getImgIds()
    path = os.path.join(root, name)
    imgs = coco.loadImgs(imgIds)
    _imgs = list(filter(lambda img: os.path.exists(os.path.join(path, img['file_name'])), imgs))
    if len(imgs) > len(_imgs):
        tf.logging.warn('%d of %d images not exists' % (len(imgs) - len(_imgs), len(imgs)))
    cnt_noobj = 0
    for img in tqdm.tqdm(_imgs):
        annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
        anns = coco.loadAnns(annIds)
        if len(anns) <= 0:
            cnt_noobj += 1
            continue
        imagepath = os.path.join(path, img['file_name'])
        width, height = img['width'], img['height']
        imageshape = [height, width, 3]
        objects_class = np.array([id_index[ann['category_id']] for ann in anns], dtype=np.int64)
        objects_coord = [ann['bbox'] for ann in anns]
        objects_coord = [(x, y, x + w, y + h) for x, y, w, h in objects_coord]
        objects_coord = np.array(objects_coord, dtype=np.float32)
        if verify:
            if not verify_coords(objects_coord, imageshape):
                tf.logging.error('failed to verify coordinates of ' + imagepath)
                continue
            if not verify_image_jpeg(imagepath, imageshape):
                tf.logging.error('failed to decode ' + imagepath)
                continue
        assert len(objects_class) == len(objects_coord)
        example = tf.train.Example(features=tf.train.Features(feature={
            'imagepath': tf.train.Feature(bytes_list=tf.train.BytesList(value=[tf.compat.as_bytes(imagepath)])),
            'imageshape': tf.train.Feature(int64_list=tf.train.Int64List(value=imageshape)),
            'objects': tf.train.Feature(bytes_list=tf.train.BytesList(value=[objects_class.tostring(), objects_coord.tostring()])),
        }))
        writer.write(example.SerializeToString())
    if cnt_noobj > 0:
        tf.logging.warn('%d of %d images have no object' % (cnt_noobj, len(_imgs)))
    return True
Beispiel #4
0
def get_keypoint_names(parameters):
    """
    Return the keypoint names for persons category.

    :param parameters: Dict with:
        parameters = {
            'coco-data-dir': pathlib.Path(...),
            'annotations': Path to annotations file with keypoints
        }

    :return: List of keypoint names.
    """
    coco = pycocotools.coco.COCO(
        str(parameters['coco-data-dir'] / parameters['annotations']))
    category_id = coco.getCatIds('person')

    category_info = coco.loadCats(category_id)[0]
    keypoint_names = category_info['keypoints']

    return keypoint_names
Beispiel #5
0
    return bbox


_cat_ids = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
    23, 24, 25, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
    46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
    65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
    89, 90
]
num_classes = 80
_classes = {ind + 1: cat_id for ind, cat_id in enumerate(_cat_ids)}
_to_order = {cat_id: ind for ind, cat_id in enumerate(_cat_ids)}
coco = coco.COCO(ANN_PATH)
CAT_NAMES = [
    coco.loadCats([_classes[i + 1]])[0]['name'] for i in range(num_classes)
]
COLORS = [((np.random.random((3, )) * 0.6 + 0.4) * 255).astype(np.uint8)
          for _ in range(num_classes)]


def add_box(image, bbox, sc, cat_id):
    cat_id = _to_order[cat_id]
    cat_name = CAT_NAMES[cat_id]
    cat_size = cv2.getTextSize(cat_name + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                               2)[0]
    color = np.array(COLORS[cat_id]).astype(np.int32).tolist()
    txt = '{}{:.0f}'.format(cat_name, sc * 10)
    if bbox[1] - cat_size[1] - 2 < 0:
        cv2.rectangle(image, (bbox[0], bbox[1] + 2),
                      (bbox[0] + cat_size[0], bbox[1] + cat_size[1] + 2),
     raise Exception('Cant find directory with images [%s]' % dirImg)
 dirOut = '%s/%s-food2' % (dataDir, dataType)
 makeDirIfNotExists(pathToDir=dirOut, isCleanIfExists=False)
 #
 annFile = '%s/annotations/instances_%s.json' % (dataDir, dataType)
 imgDir = '%s/%s' % (dataDir, dataType)
 if not os.path.isdir(imgDir):
     raise Exception('Cant find directory with MS-COCO images [%s]' %
                     dataDir)
 #
 coco = COCO(annFile)
 #
 listCatsFoodIdx = coco.getCatIds(supNms=['food'])
 assert (set(listCatsFoodIdx) == set(listSortedFoodIds))
 for ii, idx in enumerate(listCatsFoodIdx):
     tmpCat = coco.loadCats(ids=idx)[0]
     print('%d [%d] : %s (%s)' %
           (ii, idx, tmpCat['name'], tmpCat['supercategory']))
 #
 tmpDictFoodImgIds = {}
 for ii, idx in enumerate(listSortedFoodIds):
     tmpImgIds = coco.getImgIds(catIds=idx)
     for timgId in tmpImgIds:
         if tmpDictFoodImgIds.has_key(timgId):
             tmpDictFoodImgIds[timgId].append(idx)
         else:
             tmpDictFoodImgIds[timgId] = [idx]
 setAllFoodImgIds = sorted(tmpDictFoodImgIds.keys())
 print('#list/#set = %d' % len(tmpDictFoodImgIds.keys()))
 numImages = len(setAllFoodImgIds)
 for ii, kk in enumerate(setAllFoodImgIds):
Beispiel #7
0
                    dtype=np.int32)
    return bbox


_cat_ids = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
    23, 24, 25, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
    46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
    65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
    89, 90
]
num_classes = 80
_classes = {ind + 1: cat_id for ind, cat_id in enumerate(_cat_ids)}
_to_order = {cat_id: ind for ind, cat_id in enumerate(_cat_ids)}
coco = coco.COCO(ANN_PATH)
CAT_NAMES = [coco.loadCats([_classes[i + 1]])[0]['name'] \
             for i in range(num_classes)]
COLORS = [((np.random.random((3,)) * 0.6 + 0.4) * 255).astype(np.uint8) \
          for _ in range(num_classes)]


def add_box(image, bbox, sc, cat_id):
    cat_id = _to_order[cat_id]
    cat_name = CAT_NAMES[cat_id]
    cat_size = cv2.getTextSize(cat_name + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                               2)[0]
    color = np.array(COLORS[cat_id]).astype(np.int32).tolist()
    txt = '{}{:.0f}'.format(cat_name, sc * 10)
    if bbox[1] - cat_size[1] - 2 < 0:
        cv2.rectangle(image, (bbox[0], bbox[1] + 2),
                      (bbox[0] + cat_size[0], bbox[1] + cat_size[1] + 2),
Beispiel #8
0
def cache(config, path, category_index):
    phase = os.path.splitext(os.path.basename(path))[0]
    data = []
    for i, row in pd.read_csv(os.path.splitext(__file__)[0] + '.tsv',
                              sep='\t').iterrows():
        logging.info('loading data %d (%s)' %
                     (i, ', '.join([k + '=' + str(v)
                                    for k, v in row.items()])))
        root = os.path.expanduser(os.path.expandvars(row['root']))
        year = str(row['year'])
        suffix = phase + year
        path = os.path.join(root, 'annotations', 'instances_%s.json' % suffix)
        if not os.path.exists(path):
            logging.warning(path + ' not exists')
            continue
        coco = pycocotools.coco.COCO(path)
        catIds = coco.getCatIds(catNms=list(category_index.keys()))
        cats = coco.loadCats(catIds)
        id_index = dict(
            (cat['id'], category_index[cat['name']]) for cat in cats)
        imgIds = coco.getImgIds()
        path = os.path.join(root, suffix)
        imgs = coco.loadImgs(imgIds)
        _imgs = list(
            filter(
                lambda img: os.path.exists(os.path.join(
                    path, img['file_name'])), imgs))
        if len(imgs) > len(_imgs):
            logging.warning('%d of %d images not exists' %
                            (len(imgs) - len(_imgs), len(imgs)))
        for img in tqdm.tqdm(_imgs):
            annIds = coco.getAnnIds(imgIds=img['id'],
                                    catIds=catIds,
                                    iscrowd=None)
            anns = coco.loadAnns(annIds)
            if len(anns) <= 0:
                continue
            path = os.path.join(path, img['file_name'])
            width, height = img['width'], img['height']
            bbox = np.array([ann['bbox'] for ann in anns], dtype=np.float32)
            yx_min = bbox[:, 1::-1]
            hw = bbox[:, -1:1:-1]
            yx_max = yx_min + hw
            cls = np.array([id_index[ann['category_id']] for ann in anns],
                           dtype=np.int)
            difficult = np.zeros(cls.shape, dtype=np.uint8)
            try:
                if config.getboolean('cache', 'verify'):
                    size = (height, width)
                    image = cv2.imread(path)
                    assert image is not None
                    assert image.shape[:2] == size[:2]
                    utils.cache.verify_coords(yx_min, yx_max, size[:2])
            except configparser.NoOptionError:
                pass
            assert len(yx_min) == len(cls)
            assert yx_min.shape == yx_max.shape
            assert len(yx_min.shape) == 2 and yx_min.shape[-1] == 2
            data.append(
                dict(path=path,
                     yx_min=yx_min,
                     yx_max=yx_max,
                     cls=cls,
                     difficult=difficult))
        logging.warning('%d of %d images are saved' % (len(data), len(_imgs)))
    return data
def main(input_json: str,
         image_dir: str,
         coco_output_dir: Optional[str],
         tfrecords_output_dir: Optional[str],
         detection_output: str,
         detection_input: Optional[str],
         split_by: str,
         exclude_categories: List[str],
         detection_threshold: float,
         padding_factor: float,
         test_fraction: float,
         ims_per_record: int) -> None:
    """
    Args:
        input_json: str, path to JSON file with COCO-style dataset annotations
        image_dir: str, path to root folder of images
        coco_output_dir: str, path to output directory for a dataset in COCO
            format
        tfrecords_output_dir: str, path to output directory for a dataset in
            TFRecords format
        detection_output: str, path to pickle file for saving detections
        detection_input: str, path to pickle file of existing detections
            generated by this script, used to continue a partially processed
            dataset
        split_by: str, key in image-level annotations that specifies the
            splitting criteria
        exclude_categories: list of str, names of categories to ignore during
            detection
        detection_threshold: float, in [0, 1]
        padding_factor: float, padding around detected objects when cropping
        test_fraction: float, in [0, 1]
        ims_per_record: int
    """
    graph = load_frozen_graph(args.frozen_graph)

    # Load COCO style annotations from the input dataset
    coco = pycocotools.coco.COCO(input_json)

    # Get all categories, their names, and create updated ID for the json file
    categories = coco.loadCats(coco.getCatIds())
    cat_id_to_names = {cat['id']: cat['name'] for cat in categories}
    cat_id_to_new_id = {
        old_key: idx
        for idx, old_key in enumerate(cat_id_to_names.keys())
    }
    print('All categories:', list(cat_id_to_names.values()))
    for ignore_cat in exclude_categories:
        if ignore_cat not in cat_id_to_names.values():
            raise ValueError(f'Category {ignore_cat} does not exist in dataset')

    # Prepare the coco-style json files
    train_json = dict(images=[], categories=[], annotations=[])
    test_json = dict(images=[], categories=[], annotations=[])

    for old_cat_id in cat_id_to_names.keys():
        train_json['categories'].append(dict(
            id=cat_id_to_new_id[old_cat_id],
            name=cat_id_to_names[old_cat_id],
            supercategory='entity'))
    test_json['categories'] = train_json['categories']

    # Split the dataset by locations
    random.seed(0)
    print('Example of the annotation of a single image:')
    print(list(coco.imgs.items())[0])
    print('The corresponding category annoation:')
    print(coco.imgToAnns[list(coco.imgs.items())[0][0]])
    locations = sorted(set(ann[split_by] for ann in coco.imgs.values()))
    test_locations = sorted(
        random.sample(locations, max(1, int(test_fraction * len(locations)))))
    train_locations = sorted(set(locations) - set(test_locations))
    print('{} locations in total, {} for training, {} for testing'.format(
        len(locations), len(train_locations), len(test_locations)))
    print('Training uses locations ', train_locations)
    print('Testing uses locations ', test_locations)

    # Load detections
    if detection_input is not None:
        print(f'Loading existing detections from {detection_input}')
        with open(detection_input, 'rb') as f:
            detections = pickle.load(f)
    else:
        detections = dict()

    train_tfr_writer = None
    test_tfr_writer = None
    if tfrecords_output_dir is not None:
        train_tfr_writer = TFRecordsWriter(
            os.path.join(tfrecords_output_dir, 'train-{:05d}'), ims_per_record)
        test_tfr_writer = TFRecordsWriter(
            os.path.join(tfrecords_output_dir, 'test-{:05d}'), ims_per_record)

    with graph.as_default():
        with tf.Session() as sess:
            run_detection(
                sess, coco, cat_id_to_names, cat_id_to_new_id, detections,
                train_locations, train_json, test_json, train_tfr_writer,
                test_tfr_writer, image_dir, coco_output_dir, split_by,
                exclude_categories, detection_threshold, padding_factor)

    if tfrecords_output_dir is not None:
        train_tfr_writer.close()
        test_tfr_writer.close()

        label_map = [
            'item {{name: "{}" id: {}}}\n'.format(cat['name'], cat['id'])
            for cat in train_json['categories']]
        pbtxt_path = os.path.join(tfrecords_output_dir, 'label_map.pbtxt')
        with open(pbtxt_path, 'w') as f:
            f.write(''.join(label_map))

    if coco_output_dir is not None:
        # Write out COCO-style json files to the output directory
        with open(os.path.join(coco_output_dir, 'train.json'), 'wt') as fi:
            json.dump(train_json, fi)
        with open(os.path.join(coco_output_dir, 'test.json'), 'wt') as fi:
            json.dump(test_json, fi)

    # Write detections to file with pickle
    with open(detection_output, 'wb') as f:
        pickle.dump(detections, f, pickle.HIGHEST_PROTOCOL)
Beispiel #10
0
    def load_coco(self,
                  dataset_dir,
                  subset,
                  year=DEFAULT_DATASET_YEAR,
                  class_ids=None,
                  class_map=None,
                  return_coco=False,
                  auto_download=False):
        """Load a subset of the COCO dataset.
        dataset_dir: The root directory of the COCO dataset.
        subset: What to load (train, val, minival, valminusminival)
        year: What dataset year to load (2014, 2017) as a string, not an integer
        class_ids: If provided, only loads images that have the given classes.
        class_map: TODO: Not implemented yet. Supports maping classes from
            different datasets to the same class ID.
        return_coco: If True, returns the COCO object.
        auto_download: Automatically download and unzip MS-COCO images and annotations
        """

        if auto_download is True:
            self.auto_download(dataset_dir, subset, year)

        coco = COCO("{}/annotations/instances_{}{}.json".format(
            dataset_dir, subset, year))
        if subset == "minival" or subset == "valminusminival":
            subset = "val"
        image_dir = "{}/{}{}".format(dataset_dir, subset, year)

        # Load all classes or a subset?
        if not class_ids:
            # All classes
            class_ids = sorted(coco.getCatIds())

        # All images or a subset?
        if class_ids:
            image_ids = []
            for id in class_ids:
                image_ids.extend(list(coco.getImgIds(catIds=[id])))
            # Remove duplicates
            image_ids = list(set(image_ids))
        else:
            # All images
            image_ids = list(coco.imgs.keys())

        # Add classes
        for i in class_ids:
            self.add_class("coco", i, coco.loadCats(i)[0]["name"])

        # Add images
        for i in image_ids:
            self.add_image("coco",
                           image_id=i,
                           path=os.path.join(image_dir,
                                             coco.imgs[i]['file_name']),
                           width=coco.imgs[i]["width"],
                           height=coco.imgs[i]["height"],
                           annotations=coco.loadAnns(
                               coco.getAnnIds(imgIds=[i],
                                              catIds=class_ids,
                                              iscrowd=None)))
        if return_coco:
            return coco
Beispiel #11
0
def visualize_coco_annotations(image,
                               annotations,
                               coco,
                               show_label=True,
                               show_bbox=True,
                               show_segm=True):
    ''' Draws the segmentation, bounding box, and label of each annotation.
	'''

    import PIL.ImageDraw, PIL.ImageFont

    if 'posix' == os.name:
        font_dir_path = '/home/sangwook/work/font'
    else:
        font_dir_path = 'D:/work/font'
    font_filepath = font_dir_path + '/DejaVuSans.ttf'
    try:
        font = PIL.ImageFont.truetype(font_filepath, 15)
    except Exception as ex:
        print('Invalid font, {}: {}.'.format(font_filepath, ex))
        raise

    # Define color codes.
    colors = [(0, 0, 255), (0, 255, 0), (255, 0, 0), (0, 255, 255),
              (255, 0, 255), (255, 255, 0)]

    draw = PIL.ImageDraw.Draw(image, 'RGBA')
    for annotation in annotations:
        cat_name = coco.loadCats(ids=[annotation['category_id']])[0]['name']
        bbox = annotation['bbox']  # (left, top, width, height).

        color = colors[(annotation['category_id'] - 1) % len(colors)]

        if show_segm and 'segmentation' in annotation and annotation[
                'segmentation']:
            # Draw segmentation.
            draw.polygon(annotation['segmentation'][0], fill=color + (64, ))
        if show_bbox:
            # Draw bbox.
            draw.rectangle(
                (bbox[0], bbox[1], bbox[0] + bbox[2], bbox[1] + bbox[3]),
                outline=color + (255, ),
                width=2)
        if show_label:
            # Draw label.
            tw, th = draw.textsize(text=cat_name, font=font)
            if bbox[3] < th:
                draw.rectangle((bbox[0] + bbox[2], bbox[1],
                                bbox[0] + bbox[2] + tw, bbox[1] + th),
                               fill=(64, 64, 64, 255))
                draw.text((bbox[0] + bbox[2], bbox[1]),
                          text=cat_name,
                          fill=(255, 255, 255, 255),
                          font=font)
            else:
                draw.rectangle((bbox[0], bbox[1], bbox[0] + tw, bbox[1] + th),
                               fill=(64, 64, 64, 255))
                draw.text((bbox[0], bbox[1]),
                          text=cat_name,
                          fill=(255, 255, 255, 255),
                          font=font)
    return np.asarray(image)