Jeu de données OBB de texte dans les scènes
Le jeu de données OBB de texte dans les scènes combine COCO-Text et HierText en un jeu de données à classe unique pour la détection de mots, destiné à l’entraînement de boîtes englobantes orientées (OBB). Il contient des images de scènes naturelles et de documents avec du texte orienté, incurvé, dense, manuscrit et imprimé.
Fonctionnalités clés#
- 65 325 images et 1 288 991 annotations de mots lisibles après conversion.
- Une seule classe
textavec des étiquettes polygonales normalisées compatibles avec les modèles OBB Ultralytics YOLO. - COCO-Text apporte une variété de scènes naturelles ; HierText apporte du texte dense issu de scènes naturelles et de documents.
- Téléchargement automatique des sources, conversion des annotations et liaison des images multiplateforme via le fichier YAML du jeu de données.
- Les polygones source comportant plus de quatre points sont conservés et réduits à des rectangles de surface minimale par le pipeline de données OBB.
Structure du jeu de données#
Le jeu de données converti comprend les partitions suivantes. Les nombres incluent uniquement les mots lisibles dont l’aire du contour est d’au moins un pixel ; les images dont les fichiers source sont absents sont exclues.
| Partition | Images / mots COCO-Text | Images / mots HierText | Images / mots combinés |
|---|---|---|---|
| Entraînement | 43,686 / 65,919 | 8,281 / 862,577 | 51,967 / 928,496 |
| Validation | 4,927 / 7,211 | 1,724 / 178,382 | 6,651 / 185,593 |
| Test | 5,073 / 7,714 | 1,634 / 167,188 | 6,707 / 174,902 |
| Total | 53,686 / 80,844 | 11,639 / 1,208,147 | 65,325 / 1,288,991 |
COCO-Text utilise sa partition d’entraînement officielle. Ses images de validation officielles sont réparties de façon déterministe en sous-ensembles de validation et de test approximativement équilibrés, à partir de l’identifiant de l’image. HierText conserve ses partitions officielles d’entraînement, de validation et de test, avec validation renommé en val.
Les images sans mots conservés restent dans le jeu de données avec des fichiers d’étiquettes vides et servent d’images d’arrière-plan. Les répertoires convertis suivent cette structure :
datasets/
└── scene-text-yolo/
├── coco-text/
│ ├── train/
│ │ ├── images/
│ │ └── labels/
│ ├── val/
│ └── test/
└── hiertext/
├── train/
├── val/
└── test/Chaque ligne d’étiquette contient la classe 0, suivie des coordonnées polygonales normalisées. Les images sont liées en dur si le système de fichiers le permet, et copiées dans le cas contraire.
Fichier YAML du jeu de données#
La configuration scene-text-obb.yaml référence les deux jeux de données convertis. Lors de la première utilisation, elle télécharge les images COCO 2017, les annotations COCO-Text, les annotations HierText et les images HierText avant de les convertir.
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
# Scene Text OBB dataset combining COCO-Text and HierText legible word annotations
# COCO-Text: https://bgshih.github.io/cocotext/ (annotations: CC BY 4.0; COCO image terms apply)
# HierText: https://github.com/google-research-datasets/hiertext (CC BY-SA 4.0; Open Images terms apply)
# Documentation: https://docs.ultralytics.com/datasets/obb/scene-text
# Example usage: yolo obb train data=scene-text-obb.yaml model=yolo26n-obb.pt imgsz=640
# parent
# ├── ultralytics
# └── datasets
# ├── coco
# ├── coco-text
# ├── hiertext
# └── scene-text-yolo
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: scene-text-yolo # dataset root dir
train:
- coco-text/train/images # 43686 images, 65919 words
- hiertext/train/images # 8281 images, 862577 words
val:
- coco-text/val/images # 4927 images, 7211 words
- hiertext/val/images # 1724 images, 178382 words
test:
- coco-text/test/images # 5073 images, 7714 words
- hiertext/test/images # 1634 images, 167188 words
names:
0: text
# Download COCO 2017 images and both annotation sources, then convert legible words to YOLO OBB format (~24 GB)
download: |
import gzip
import hashlib
import json
import os
import shutil
from pathlib import Path
from tempfile import TemporaryDirectory
import cv2
import numpy as np
from ultralytics.data.utils import check_det_dataset
from ultralytics.utils import TQDM
from ultralytics.utils.downloads import download
def polygon_label(vertices, width, height):
polygon = np.asarray(vertices, dtype=np.float32).reshape(-1, 2)
if len(polygon) < 3 or cv2.contourArea(polygon) < 1:
return ""
polygon[:, 0] = polygon[:, 0].clip(0, width - 1)
polygon[:, 1] = polygon[:, 1].clip(0, height - 1)
polygon /= np.array([width, height], dtype=np.float32)
return "0 " + " ".join(f"{x:.7f} {y:.7f}" for x, y in polygon)
def link_image(source, destination):
destination.parent.mkdir(parents=True, exist_ok=True)
try:
os.link(source, destination)
except OSError:
shutil.copy2(source, destination)
def write_labels(label_dir, stem, labels):
label_dir.mkdir(parents=True, exist_ok=True)
(label_dir / f"{stem}.txt").write_text("\n".join(labels) + ("\n" if labels else ""), encoding="utf-8")
def convert_coco_text(parent, destination):
source_dir = parent / "coco-text"
annotations = source_dir / "cocotext.v2.json"
if not annotations.is_file():
download(
"https://github.com/bgshih/cocotext/releases/download/dl/cocotext.v2.zip",
dir=source_dir,
delete=True,
)
coco = check_det_dataset("coco.yaml")
images = Path(coco["path"]) / "images"
data = json.loads(annotations.read_text(encoding="utf-8"))
for image_id, image in TQDM(data["imgs"].items(), desc="Converting COCO-Text"):
split = (
"train"
if image["set"] == "train"
else ("val" if hashlib.sha256(str(image["id"]).encode()).digest()[0] < 128 else "test")
)
filename = image["file_name"].replace("COCO_train2014_", "", 1)
source = images / "train2017" / filename
if not source.exists():
source = images / "val2017" / filename
if not source.exists():
continue
image_dir = destination / split / "images"
link_image(source, image_dir / filename)
im = cv2.imread(str(source))
if im is None:
raise ValueError(f"Unreadable image: {source}")
height, width = im.shape[:2]
labels = []
for ann_id in data["imgToAnns"].get(image_id, []):
ann = data["anns"][str(ann_id)]
if ann["legibility"] == "legible" and (label := polygon_label(ann["mask"], width, height)):
labels.append(label)
write_labels(destination / split / "labels", Path(filename).stem, labels)
def convert_hiertext(parent, destination):
source = parent / "hiertext" / "source"
splits = {"train": "train", "validation": "val", "test": "test"}
base = "https://raw.githubusercontent.com/google-research-datasets/hiertext/main"
if not all((source / "gt" / f"{split}.jsonl.gz").is_file() for split in splits):
download([f"{base}/gt/{split}.jsonl.gz" for split in splits], dir=source / "gt", unzip=False, threads=3)
if not all((source / split).is_dir() for split in splits):
download(
[f"https://open-images-dataset.s3.amazonaws.com/ocr/{split}.tgz" for split in splits],
dir=source,
delete=True,
threads=3,
)
for source_split, split in splits.items():
with gzip.open(source / "gt" / f"{source_split}.jsonl.gz", "rt", encoding="utf-8") as f:
rows = json.load(f)["annotations"]
for row in TQDM(rows, desc=f"Converting HierText {source_split}"):
image_id = row["image_id"]
source_image = source / source_split / f"{image_id}.jpg"
if not source_image.exists():
continue
image = destination / split / "images" / f"{image_id}.jpg"
link_image(source_image, image)
im = cv2.imread(str(image))
if im is None:
raise ValueError(f"Unreadable image: {source_image}")
height, width = im.shape[:2]
labels = []
for paragraph in row["paragraphs"]:
for line in paragraph["lines"]:
for word in line["words"]:
if word["legible"] and (label := polygon_label(word["vertices"], width, height)):
labels.append(label)
write_labels(destination / split / "labels", image_id, labels)
final = Path(yaml["path"])
parent = final.parent
parent.mkdir(parents=True, exist_ok=True)
with TemporaryDirectory(dir=parent, prefix=".scene-text-") as tmp:
destination = Path(tmp)
convert_coco_text(parent, destination / "coco-text")
convert_hiertext(parent, destination / "hiertext")
destination.rename(final)Les sources nécessitent environ 24 Go de téléchargements. Prévois au moins 50 Go d’espace de stockage libre pendant le téléchargement et l’extraction initiaux, y compris pour les archives COCO temporaires. Si les liens physiques ne sont pas disponibles, les copies des images nécessitent de l’espace de stockage supplémentaire. Consulte les conditions de licence avant d’utiliser ou de redistribuer les données converties.
Utilisation#
Entraîne un modèle YOLO26 OBB avec une taille d’image de 640 pixels à l’aide des commandes suivantes. Les fichiers source COCO et HierText existants dans le répertoire Ultralytics datasets_dir sont réutilisés.
from ultralytics import YOLO
model = YOLO("yolo26n-obb.pt")
results = model.train(data="scene-text-obb.yaml", epochs=100, imgsz=640)Applications#
Utilise ce jeu de données pour entraîner des détecteurs de texte au niveau des mots destinés au traitement de documents, à la compréhension de reçus, à la traduction de panneaux, à l’inspection industrielle et aux pipelines OCR. La détection n’est qu’une étape de l’OCR : associe le détecteur à un reconnaisseur de texte si une transcription est nécessaire.
Licence#
Le jeu de données combiné est soumis aux conditions propres à chaque source, et non à une licence unique inconditionnelle :
- Annotations COCO-Text : CC BY 4.0. Les conditions d’utilisation des images COCO sous-jacentes restent applicables.
- Annotations HierText : CC BY-SA 4.0. Les adaptations redistribuées doivent mentionner la source, signaler les modifications et être diffusées sous la même licence ou sous une licence compatible.
- Images HierText : issues d’Open Images. Les conditions d’utilisation d’Open Images indiquent que les images sont sous licence CC BY 2.0 et demandent aux utilisateurs de vérifier les licences de chaque image.
Ces licences d’annotation autorisent l’utilisation commerciale sous réserve de leurs conditions, mais le jeu de données n’est pas dans le domaine public. Conserve les mentions d’attribution des sources et vérifie les conditions applicables aux images avant de redistribuer les données.
Citations et remerciements#
Si tu utilises ce jeu de données dans tes travaux, cite les deux jeux de données sources :
@article{veit2016cocotext,
title={COCO-Text: Dataset and Benchmark for Text Detection and Recognition in Natural Images},
author={Veit, Andreas and Matera, Tomas and Neumann, Lukas and Matas, Jiri and Belongie, Serge},
journal={arXiv preprint arXiv:1601.07140},
year={2016}
}
@inproceedings{long2022towards,
title={Towards End-to-End Unified Scene Text Detection and Layout Analysis},
author={Long, Shangbang and Qin, Siyang and Panteleev, Dmitry and Bissacco, Alessandro and Fujii, Yasuhisa and Raptis, Michalis},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
year={2022}
}Nous remercions les équipes COCO-Text et HierText d’avoir créé et maintenu ces jeux de données.
FAQ#
Non. La conversion produit des polygones de détection de mots à classe unique pour l’entraînement OBB. Utilise les annotations COCO-Text et HierText d’origine si ton pipeline nécessite aussi des transcriptions.
COCO-Text fournit des annotations d’entraînement et de validation. Cette configuration conserve la partition d’entraînement officielle et divise de façon déterministe les images officielles de validation en sous-ensembles de validation et de test. HierText conserve ses partitions officielles.
Oui. Place-le dans le répertoire Ultralytics
datasets_dir, en respectant la structure standardcoco/, avecimages/train2017,images/val2017et les fichiers texte des partitions COCO. Le script de téléchargement le réutilise au lieu de télécharger COCO à nouveau.
Commentaires
Pose une question, partage tes résultats ou aide quelqu’un d’autre.