Source code for stable_datasets.images.coil100

"""Columbia Object Image Library (COIL-100)."""

import re
import zipfile
from pathlib import PurePosixPath

from PIL import Image as PILImage

from stable_datasets.schema import ClassLabel, DatasetInfo, DatasetSource, DownloadInfo, Features, Value, Version
from stable_datasets.schema import Image as ImageFeature
from stable_datasets.utils import BaseDatasetBuilder


_IMAGE_NAME = re.compile(r"obj(\d+)__(\d+)\.png")


[docs] class COIL100(BaseDatasetBuilder): """100 physical objects, each photographed at 72 viewing angles.""" VERSION = Version("1.0.0") SOURCE = DatasetSource( homepage="https://www.cs.columbia.edu/CAVE/software/softlib/coil-100.php", assets={ "train": DownloadInfo( url="https://www.cs.columbia.edu/CAVE/databases/SLAM_coil-20_coil-100/coil-100/coil-100.zip" ) }, citation="""@techreport{nene1996coil100, author = {Nene, Sameer A. and Nayar, Shree K. and Murase, Hiroshi}, title = {Columbia Object Image Library (COIL-100)}, institution = {Columbia University}, number = {CUCS-006-96}, month = feb, year = {1996} }""", ) def _info(self): return DatasetInfo( description=( "COIL-100 contains 7,200 RGB images of 100 physical objects at 128x128 resolution: " "72 views per object in 5-degree increments. The single train split contains the " "complete official dataset; Columbia provides no predefined classification split." ), features=Features( { "image": ImageFeature(), "label": ClassLabel(names=[f"obj{object_id}" for object_id in range(1, 101)]), "angle": Value("int32"), } ), supervised_keys=("image", "label"), homepage=self.SOURCE["homepage"], citation=self.SOURCE["citation"], ) def _generate_examples(self, data_path, split): with zipfile.ZipFile(data_path) as archive: views = [] for member in archive.infolist(): if member.is_dir(): continue match = _IMAGE_NAME.fullmatch(PurePosixPath(member.filename).name) if match: views.append((int(match[1]), int(match[2]), member)) # Sort by object and angle so ZIP entry order cannot change row order. for index, (object_id, angle, member) in enumerate(sorted(views, key=lambda view: view[:2])): with archive.open(member) as image_file, PILImage.open(image_file) as source_image: image = source_image.convert("RGB") # Filenames use object IDs 1-100; labels use indices 0-99. yield index, {"image": image, "label": object_id - 1, "angle": angle}