Spaces:
Runtime error
Runtime error
# coding=utf-8 | |
# Copyright 2021 The Deeplab2 Authors. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
"""Tests for build_coco_data.""" | |
import json | |
import os | |
from absl import flags | |
import numpy as np | |
from PIL import Image | |
import tensorflow as tf | |
from deeplab2.data import build_coco_data | |
from deeplab2.data import coco_constants | |
FLAGS = flags.FLAGS | |
_TEST_FILE_NAME = '000000123456.png' | |
class BuildCOCODataTest(tf.test.TestCase): | |
def setUp(self): | |
super().setUp() | |
self.data_dir = FLAGS.test_tmpdir | |
self.height = 100 | |
self.width = 100 | |
self.split = 'train' | |
image_path = os.path.join(self.data_dir, | |
build_coco_data._FOLDERS_MAP[self.split]['image']) | |
panoptic_map_path = os.path.join(self.data_dir, | |
build_coco_data._FOLDERS_MAP | |
[self.split]['label']) | |
tf.io.gfile.makedirs(panoptic_map_path) | |
panoptic_map_path = os.path.join(panoptic_map_path, | |
'panoptic_%s2017' % self.split) | |
tf.io.gfile.makedirs(image_path) | |
tf.io.gfile.makedirs(panoptic_map_path) | |
self.panoptic_maps = {} | |
image_id = int(_TEST_FILE_NAME[:-4]) | |
self.panoptic_maps[image_id] = self._create_image_and_panoptic_map( | |
image_path, panoptic_map_path, image_id) | |
def _create_image_and_panoptic_map(self, image_path, panoptic_path, image_id): | |
def id2rgb(id_map): | |
id_map_copy = id_map.copy() | |
rgb_shape = tuple(list(id_map.shape) + [3]) | |
rgb_map = np.zeros(rgb_shape, dtype=np.uint8) | |
for i in range(3): | |
rgb_map[..., i] = id_map_copy % 256 | |
id_map_copy //= 256 | |
return rgb_map | |
# Creates dummy images and panoptic maps. | |
# Dummy image. | |
image = np.random.randint( | |
0, 255, (self.height, self.width, 3), dtype=np.uint8) | |
with tf.io.gfile.GFile( | |
os.path.join(image_path, '%012d.jpg' % image_id), 'wb') as f: | |
Image.fromarray(image).save(f, format='JPEG') | |
# Dummy panoptic map. | |
semantic = np.random.randint( | |
0, 201, (self.height, self.width), dtype=np.int32) | |
instance_ = np.random.randint( | |
0, 100, (self.height, self.width), dtype=np.int32) | |
id_mapping = coco_constants.get_id_mapping() | |
valid_semantic = id_mapping.keys() | |
for i in range(201): | |
if i not in valid_semantic: | |
mask = (semantic == i) | |
semantic[mask] = 0 | |
instance_[mask] = 0 | |
instance = instance_.copy() | |
segments_info = [] | |
for sem in np.unique(semantic): | |
ins_id = 1 | |
if sem == 0: | |
continue | |
if id_mapping[sem] in build_coco_data._CLASS_HAS_INSTANCE_LIST: | |
for ins in np.unique(instance_[semantic == sem]): | |
instance[np.logical_and(semantic == sem, instance_ == ins)] = ins_id | |
area = np.logical_and(semantic == sem, instance_ == ins).sum() | |
idx = sem * 256 + ins_id | |
iscrowd = 0 | |
segments_info.append({ | |
'id': idx.tolist(), | |
'category_id': sem.tolist(), | |
'area': area.tolist(), | |
'iscrowd': iscrowd, | |
}) | |
ins_id += 1 | |
else: | |
instance[semantic == sem] = 0 | |
area = (semantic == sem).sum() | |
idx = sem * 256 | |
iscrowd = 0 | |
segments_info.append({ | |
'id': idx.tolist(), | |
'category_id': sem.tolist(), | |
'area': area.tolist(), | |
'iscrowd': iscrowd, | |
}) | |
encoded_panoptic_map = semantic * 256 + instance | |
encoded_panoptic_map = id2rgb(encoded_panoptic_map) | |
with tf.io.gfile.GFile( | |
os.path.join(panoptic_path, '%012d.png' % image_id), 'wb') as f: | |
Image.fromarray(encoded_panoptic_map).save(f, format='PNG') | |
for i in range(201): | |
if i in valid_semantic: | |
mask = (semantic == i) | |
semantic[mask] = id_mapping[i] | |
decoded_panoptic_map = semantic * 256 + instance | |
# Write json file | |
json_annotation = { | |
'annotations': [ | |
{ | |
'file_name': _TEST_FILE_NAME, | |
'image_id': int(_TEST_FILE_NAME[:-4]), | |
'segments_info': segments_info | |
} | |
] | |
} | |
json_annotation_path = os.path.join(self.data_dir, | |
build_coco_data._FOLDERS_MAP | |
[self.split]['label'], | |
'panoptic_%s2017.json' % self.split) | |
with tf.io.gfile.GFile(json_annotation_path, 'w') as f: | |
json.dump(json_annotation, f, indent=2) | |
return decoded_panoptic_map | |
def test_build_coco_dataset_correct(self): | |
build_coco_data._convert_dataset( | |
coco_root=self.data_dir, | |
dataset_split=self.split, | |
output_dir=FLAGS.test_tmpdir) | |
output_record = os.path.join( | |
FLAGS.test_tmpdir, '%s-%05d-of-%05d.tfrecord' % | |
(self.split, 0, build_coco_data._NUM_SHARDS)) | |
self.assertTrue(tf.io.gfile.exists(output_record)) | |
# Parses tf record. | |
image_ids = sorted(self.panoptic_maps) | |
for i, raw_record in enumerate( | |
tf.data.TFRecordDataset([output_record]).take(5)): | |
image_id = image_ids[i] | |
example = tf.train.Example.FromString(raw_record.numpy()) | |
panoptic_map = np.fromstring( | |
example.features.feature['image/segmentation/class/encoded'] | |
.bytes_list.value[0], | |
dtype=np.int32).reshape((self.height, self.width)) | |
np.testing.assert_array_equal(panoptic_map, self.panoptic_maps[image_id]) | |
if __name__ == '__main__': | |
tf.test.main() | |