Conjunto de datos OBB de texto en escenas
El conjunto de datos OBB de texto en escenas combina COCO-Text y HierText en un conjunto de datos de una sola clase para detectar palabras y entrenar cajas delimitadoras orientadas (OBB). Contiene imágenes de escenas naturales y documentos con texto girado, curvo, muy denso, manuscrito e impreso.
Características principales#
- 65.325 imágenes y 1.288.991 anotaciones de palabras legibles tras la conversión.
- Una clase
textcon etiquetas de polígonos normalizadas compatibles con los modelos OBB de Ultralytics YOLO. - COCO-Text aporta una variedad de escenas naturales; HierText aporta texto denso de escenas naturales y documentos.
- Descarga automática de las fuentes, conversión de anotaciones y vinculación de imágenes multiplataforma mediante el YAML del conjunto de datos.
- Los polígonos de origen con más de cuatro puntos se conservan y se reducen a rectángulos de área mínima mediante la canalización de datos OBB.
Estructura del conjunto de datos#
El conjunto de datos convertido tiene las siguientes particiones. Los recuentos solo incluyen palabras legibles con un área de contorno de al menos un píxel; se excluyen las imágenes cuyos archivos de origen no están disponibles.
| División | Imágenes / palabras de COCO-Text | Imágenes / palabras de HierText | Imágenes / palabras combinadas |
|---|---|---|---|
| Entrenar | 43,686 / 65,919 | 8,281 / 862,577 | 51,967 / 928,496 |
| Validar | 4,927 / 7,211 | 1,724 / 178,382 | 6,651 / 185,593 |
| Prueba | 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 utiliza su partición oficial de entrenamiento. Sus imágenes oficiales de validación se dividen de forma determinista en subconjuntos de validación y prueba aproximadamente equilibrados, usando el ID de imagen. HierText conserva sus particiones oficiales de entrenamiento, validación y prueba, con validation renombrado a val.
Las imágenes sin palabras conservadas permanecen en el conjunto de datos con archivos de etiquetas vacíos y sirven como imágenes de fondo. Los directorios convertidos tienen esta estructura:
datasets/
└── scene-text-yolo/
├── coco-text/
│ ├── train/
│ │ ├── images/
│ │ └── labels/
│ ├── val/
│ └── test/
└── hiertext/
├── train/
├── val/
└── test/Cada fila de etiquetas contiene la clase 0 seguida de las coordenadas normalizadas del polígono. Las imágenes se vinculan mediante enlaces duros cuando el sistema de archivos lo permite y, en caso contrario, se copian.
YAML del conjunto de datos#
La configuración scene-text-obb.yaml hace referencia a los dos conjuntos de datos convertidos. La primera vez que se utiliza, descarga las imágenes de COCO 2017, las anotaciones de COCO-Text, las anotaciones de HierText y las imágenes de HierText antes de convertirlas.
# 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)Las fuentes requieren aproximadamente 24 GB de descargas. Reserva al menos 50 GB de espacio libre durante la descarga y extracción iniciales, incluidos los archivos temporales de COCO. Si no se pueden crear enlaces duros, las imágenes copiadas requieren espacio de almacenamiento adicional. Revisa las condiciones de licencia antes de usar o redistribuir los datos convertidos.
Uso#
Entrena un modelo YOLO26 OBB con imágenes de 640 píxeles usando los siguientes comandos. Se reutilizan los archivos de origen existentes de COCO y HierText que haya en datasets_dir de Ultralytics.
from ultralytics import YOLO
model = YOLO("yolo26n-obb.pt")
results = model.train(data="scene-text-obb.yaml", epochs=100, imgsz=640)Aplicaciones#
Usa este conjunto de datos para entrenar detectores de texto a nivel de palabra para el procesamiento de documentos, la comprensión de recibos, la traducción de señales, la inspección industrial y las canalizaciones de OCR. La detección es solo una etapa del OCR: combina el detector con un reconocedor de texto cuando necesites transcribir el texto.
Licencias#
El conjunto de datos combinado se rige por las condiciones específicas de cada fuente, no por una única licencia incondicional:
- Anotaciones de COCO-Text: CC BY 4.0. Siguen siendo aplicables las condiciones de las imágenes de COCO subyacentes.
- Anotaciones de HierText: CC BY-SA 4.0. Las adaptaciones redistribuidas requieren atribución, un aviso de cambios y una licencia igual o compatible.
- Imágenes de HierText: proceden de Open Images. Las condiciones de Open Images indican que las imágenes tienen licencia CC BY 2.0 e instan a los usuarios a verificar las licencias de cada imagen.
Estas licencias de anotaciones permiten el uso comercial sujeto a sus condiciones, pero el conjunto de datos no es de dominio público. Conserva la atribución de las fuentes y revisa las condiciones aplicables a las imágenes al redistribuir los datos.
Citas y agradecimientos#
Si usas este conjunto de datos en tu trabajo, cita ambos conjuntos de datos de origen:
@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}
}Agradecemos a los equipos de COCO-Text y HierText que hayan creado y mantengan estos conjuntos de datos.
Preguntas frecuentes#
No. La conversión genera polígonos de detección de palabras de una sola clase para el entrenamiento OBB. Si tu canalización también requiere transcripciones, usa las anotaciones originales de COCO-Text y HierText.
COCO-Text proporciona anotaciones de entrenamiento y validación. Esta configuración conserva la partición oficial de entrenamiento y divide de forma determinista las imágenes oficiales de validación en subconjuntos de validación y prueba. HierText conserva sus particiones oficiales.
Sí. Colócala en
datasets_dirde Ultralytics siguiendo la estructura estándar decoco/, incluidosimages/train2017,images/val2017y los archivos de texto de las particiones de COCO. El script de descarga la reutiliza en lugar de volver a descargar COCO.
Comentarios
Haz una pregunta, comparte tus resultados o ayuda a otra persona.