import zipfile
from stable_datasets.schema import ClassLabel, DatasetInfo, DatasetSource, DownloadInfo, Features, Version
from stable_datasets.schema import Image as ImageFeature
from stable_datasets.utils import BaseDatasetBuilder
# The upstream repository is updated in place, so pin a commit (README version 2026.10.18.2).
_COMMIT = "18fbaa1b48a70d356e6aa47a8ff88156fb96b887"
_URL = f"https://github.com/fruits-360/fruits-360-100x100/archive/{_COMMIT}.zip"
_CHECKSUM = "sha256:50213ec3770a9f5dbceac91e8ca660b5507accb405ba89ac5fe9253b5597cadb"
[docs]
class Fruits360(BaseDatasetBuilder):
"""Fruits-360: 100x100 images of fruits, vegetables, nuts, seeds and mushrooms.
Each object was filmed while rotating on a slow motor in front of a white background, and the background
was removed with a flood-fill algorithm. Different varieties of the same fruit are separate classes.
The official Training/Test partitions are kept as released.
"""
VERSION = Version("2026.10.18")
SOURCE = DatasetSource(
homepage="https://github.com/fruits-360",
assets={
"train": DownloadInfo(url=_URL, checksum=_CHECKSUM),
"test": DownloadInfo(url=_URL, checksum=_CHECKSUM),
},
citation="""@article{muresan2018fruit,
title = {Fruit recognition from images using deep learning},
author = {Mure{\\c{s}}an, Horea and Oltean, Mihai},
journal = {Acta Universitatis Sapientiae, Informatica},
volume = {10},
number = {1},
pages = {26--42},
year = {2018} }
""",
)
_SPLIT_DIRS = {"train": "Training", "test": "Test"}
def _info(self):
return DatasetInfo(
description="""Fruits-360 contains 100x100 RGB images of fruits, vegetables, nuts, seeds and mushrooms
on a white background, across 274 classes where varieties of the same fruit are distinct classes.""",
features=Features({"image": ImageFeature(), "label": ClassLabel(names=self._labels())}),
supervised_keys=("image", "label"),
homepage=self.SOURCE["homepage"],
citation=self.SOURCE["citation"],
)
def _generate_examples(self, data_path, split):
"""Yield the JPEGs under ``<repo>/<Training|Test>/<class>/`` in the zip archive.
Upstream has a few class folders that differ only in letter case (e.g. ``Blackberry 3`` and
``BlackBerry 3``) and hold disjoint images of the same class, so class names are matched
case-insensitively. This gives the 274 classes reported by the dataset authors.
"""
label_ids = {name.lower(): i for i, name in enumerate(self._labels())}
split_dir = self._SPLIT_DIRS[split]
with zipfile.ZipFile(data_path) as archive:
for member in archive.infolist():
parts = member.filename.split("/")
if member.is_dir() or len(parts) != 4 or parts[1] != split_dir or not parts[3].endswith(".jpg"):
continue
yield member.filename, {"image": archive.read(member), "label": label_ids[parts[2].lower()]}
@staticmethod
def _labels():
return [
"Almonds 1",
"Apple 10",
"Apple 11",
"Apple 12",
"Apple 13",
"Apple 14",
"Apple 17",
"Apple 18",
"Apple 19",
"Apple 20",
"Apple 21",
"Apple 22",
"Apple 23",
"Apple 5",
"Apple 6",
"Apple 7",
"Apple 8",
"Apple 9",
"Apple Braeburn 1",
"Apple Crimson Snow 1",
"Apple Golden 1",
"Apple Golden 2",
"Apple Golden 3",
"Apple Granny Smith 1",
"Apple Pink Lady 1",
"Apple Red 1",
"Apple Red 2",
"Apple Red 3",
"Apple Red Delicious 1",
"Apple Red Yellow 1",
"Apple Red Yellow 2",
"Apricot 1",
"Avocado 1",
"Avocado 2",
"Avocado Black 1",
"Avocado Black 2",
"Avocado Green 1",
"Banana 1",
"Banana 2",
"Banana 3",
"Banana 4",
"Banana Lady Finger 1",
"Banana Red 1",
"Bean pod 1",
"Beetroot 1",
"Blackberry 1",
"Blackberry 2",
"Blackberry 3",
"Blackberry 4",
"Blackberry 5",
"Blueberry 1",
"Cabbage red 1",
"Cabbage white 1",
"Cactus fruit 1",
"Cactus fruit green 1",
"Cactus fruit red 1",
"Caju seed 1",
"Cantaloupe 1",
"Cantaloupe 2",
"Cantaloupe 3",
"Carambola 1",
"Carambola 2",
"Carambola 3",
"Carrot 1",
"Cauliflower 1",
"Celery 1",
"Cherimoya 1",
"Cherry 1",
"Cherry 2",
"Cherry 3",
"Cherry 4",
"Cherry 5",
"Cherry Rainier 1",
"Cherry Rainier 2",
"Cherry Rainier 3",
"Cherry Sour 1",
"Cherry Wax 1",
"Cherry Wax 2",
"Cherry Wax Black 1",
"Cherry Wax Red 1",
"Cherry Wax Red 2",
"Cherry Wax Red 3",
"Cherry Wax Yellow 1",
"Chestnut 1",
"Clementine 1",
"Cocos 1",
"Corn 1",
"Corn Husk 1",
"Cucumber 1",
"Cucumber 10",
"Cucumber 11",
"Cucumber 12",
"Cucumber 13",
"Cucumber 3",
"Cucumber 4",
"Cucumber 5",
"Cucumber 6",
"Cucumber 7",
"Cucumber 8",
"Cucumber 9",
"Dates 1",
"Dates 2",
"Eggplant 1",
"Eggplant long 1",
"Fig 1",
"Ginger 1",
"Ginger 2",
"Gooseberry 1",
"Granadilla 1",
"Grape 1",
"Grape Blue 1",
"Grape Pink 1",
"Grape White 1",
"Grape White 2",
"Grape White 3",
"Grape White 4",
"Grape pink 2",
"Grapefruit Pink 1",
"Grapefruit White 1",
"Guava 1",
"Hazelnut 1",
"Huckleberry 1",
"Kaki 1",
"Kiwi 1",
"Kohlrabi 1",
"Kumquats 1",
"Lemon 1",
"Lemon Meyer 1",
"Limes 1",
"Lychee 1",
"Mandarine 1",
"Mango 1",
"Mango Red 1",
"Mangostan 1",
"Maracuja 1",
"Melon Piel de Sapo 1",
"Mulberry 1",
"Mushroom champignon 1",
"Mushroom champignon 2",
"Mushroom champignon 3",
"Mushroom champignon 4",
"Mushroom champignon 5",
"Nectarine 1",
"Nectarine Flat 1",
"Nectarine Flat 2",
"Nut 1",
"Nut 2",
"Nut 3",
"Nut 4",
"Nut 5",
"Nut Forest 1",
"Nut Pecan 1",
"Onion 2",
"Onion Red 1",
"Onion Red 2",
"Onion Red 3",
"Onion White 1",
"Onion White 2",
"Orange 1",
"Orange 2",
"Orange 3",
"Orange 5",
"Orange peeled 1",
"Papaya 1",
"Papaya 2",
"Passion Fruit 1",
"Peach 1",
"Peach 2",
"Peach 3",
"Peach 4",
"Peach 5",
"Peach 6",
"Peach Flat 1",
"Peanut shell 1x 1",
"Pear 1",
"Pear 10",
"Pear 11",
"Pear 12",
"Pear 13",
"Pear 14",
"Pear 2",
"Pear 3",
"Pear 5",
"Pear 6",
"Pear 7",
"Pear 8",
"Pear 9",
"Pear Abate 1",
"Pear Forelle 1",
"Pear Kaiser 1",
"Pear Monster 1",
"Pear Red 1",
"Pear Stone 1",
"Pear Williams 1",
"Pepino 1",
"Pepper 1",
"Pepper 2",
"Pepper Green 1",
"Pepper Orange 1",
"Pepper Orange 2",
"Pepper Red 1",
"Pepper Red 2",
"Pepper Red 3",
"Pepper Red 4",
"Pepper Red 5",
"Pepper Yellow 1",
"Physalis 1",
"Physalis with Husk 1",
"Physalis with husk 2",
"Physalis with husk 3",
"Pineapple 1",
"Pineapple Mini 1",
"Pistachio 1",
"Pitahaya Red 1",
"Pitahaya red 2",
"Pitahaya red 3",
"Plum 1",
"Plum 2",
"Plum 3",
"Plum 4",
"Plum 5",
"Pomegranate 1",
"Pomelo Sweetie 1",
"Potato Red 1",
"Potato Red 2",
"Potato Sweet 1",
"Potato White 1",
"Quince 1",
"Quince 2",
"Quince 3",
"Quince 4",
"Rambutan 1",
"Raspberry 1",
"Raspberry 2",
"Raspberry 3",
"Raspberry 4",
"Raspberry 5",
"Raspberry 6",
"Redcurrant 1",
"Redcurrant 2",
"Salak 1",
"Strawberry 1",
"Strawberry 2",
"Strawberry 3",
"Strawberry Wedge 1",
"Tamarillo 1",
"Tangelo 1",
"Tomato 1",
"Tomato 10",
"Tomato 11",
"Tomato 2",
"Tomato 3",
"Tomato 4",
"Tomato 5",
"Tomato 7",
"Tomato 8",
"Tomato 9",
"Tomato Cherry Maroon 1",
"Tomato Cherry Orange 1",
"Tomato Cherry Red 1",
"Tomato Cherry Red 2",
"Tomato Cherry Yellow 1",
"Tomato Heart 1",
"Tomato Maroon 1",
"Tomato Maroon 2",
"Tomato Yellow 1",
"Walnut 1",
"Watermelon 1",
"Zucchini 1",
"Zucchini Green 1",
"Zucchini dark 1",
"garlic bulb 1",
"grape pink 3",
"orange 4",
]