Ultralytics YOLO27: Запишись в список ожидания.
Начать

Набор данных Scene Text OBB

Набор данных Scene Text OBB объединяет COCO-Text и HierText в набор данных с одним классом для обнаружения слов с помощью ориентированных ограничивающих рамок (OBB). Он содержит изображения естественных сцен и документов с повернутым, изогнутым, плотно расположенным, рукописным и печатным текстом.

Основные особенности#

  • 65 325 изображений и 1 288 991 читаемая аннотация слов после преобразования.
  • Один класс text с нормализованными метками-полигонами, совместимыми с моделями Ultralytics YOLO OBB.
  • COCO-Text содержит разнообразные изображения естественных сцен; HierText — плотный текст на изображениях естественных сцен и документов.
  • Автоматическая загрузка исходных данных, преобразование аннотаций и кроссплатформенное связывание изображений через YAML-файл набора данных.
  • Исходные полигоны, содержащие более четырёх точек, сохраняются; конвейер обработки данных OBB преобразует их в прямоугольники минимальной площади.

Структура набора данных#

Преобразованный набор данных разделён следующим образом. В подсчёты входят только читаемые слова с площадью контура не менее одного пикселя; изображения, для которых отсутствуют исходные файлы, исключены.

ПодвыборкаИзображения / слова COCO-TextИзображения / слова HierTextВсего изображений / слов
Обучение43,686 / 65,9198,281 / 862,57751,967 / 928,496
Валидация4,927 / 7,2111,724 / 178,3826,651 / 185,593
Тестовая5,073 / 7,7141,634 / 167,1886,707 / 174,902
Итого53,686 / 80,84411,639 / 1,208,14765,325 / 1,288,991

Для COCO-Text используется официальный обучающий раздел. Официальные изображения для валидации детерминированно распределяются на примерно равные подмножества для валидации и тестирования по ID изображения. В HierText сохраняются официальные разделы для обучения, валидации и тестирования, а validation переименовывается в val.

Изображения, для которых не сохранилось ни одного слова, остаются в наборе данных с пустыми файлами меток и используются как фоновые изображения. Преобразованные каталоги имеют следующую структуру:

datasets/
└── scene-text-yolo/
    ├── coco-text/
    │   ├── train/
    │   │   ├── images/
    │   │   └── labels/
    │   ├── val/
    │   └── test/
    └── hiertext/
        ├── train/
        ├── val/
        └── test/

Каждая строка метки содержит класс 0, за которым следуют нормализованные координаты полигона. Если файловая система поддерживает жёсткие ссылки, изображения связываются ими; в противном случае они копируются.

Файл YAML набора данных#

Конфигурация scene-text-obb.yaml ссылается на оба преобразованных набора данных. При первом использовании она загружает изображения COCO 2017, аннотации COCO-Text, аннотации HierText и изображения HierText, а затем преобразует их.

scene-text-obb.yaml
# 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)
Размер загрузки и лицензирование

Для загрузки исходных данных требуется около 24 ГБ. На время первоначальной загрузки и распаковки, включая временные архивы COCO, выдели не менее 50 ГБ свободного места. Если жёсткие ссылки недоступны, для копирования изображений потребуется дополнительное место. Перед использованием или распространением преобразованных данных ознакомься с условиями лицензирования.

Использование#

Обучи модель YOLO26 OBB с размером изображения 640 пикселей с помощью следующих команд. Существующие исходные файлы COCO и HierText в каталоге Ultralytics datasets_dir будут использованы повторно.

Пример обучения
from ultralytics import YOLO

model = YOLO("yolo26n-obb.pt")
results = model.train(data="scene-text-obb.yaml", epochs=100, imgsz=640)

Применение#

Используй этот набор данных для обучения детекторов текста на уровне слов для обработки документов, распознавания чеков, перевода надписей, промышленного контроля и конвейеров OCR. Обнаружение — лишь один из этапов OCR: если нужна транскрипция, добавь к детектору распознаватель текста.

Лицензирование#

Для объединённого набора данных действуют условия лицензирования, установленные для каждого источника; единой безусловной лицензии нет:

  • Аннотации COCO-Text: CC BY 4.0. Также действуют условия использования изображений COCO.
  • Аннотации HierText: CC BY-SA 4.0. При распространении адаптированных материалов необходимо указывать авторство, сообщать об изменениях и лицензировать материалы на условиях той же или совместимой лицензии.
  • Изображения HierText: взяты из Open Images. В условиях Open Images указано, что изображения распространяются по лицензии CC BY 2.0; пользователям рекомендуется проверять лицензии отдельных изображений.

Эти лицензии на аннотации разрешают коммерческое использование при соблюдении их условий, но набор данных не является общественным достоянием. При распространении данных сохраняй указание источников и проверяй применимые условия лицензирования изображений.

Цитирование и благодарности#

Если ты используешь этот набор данных в своей работе, процитируй оба исходных набора данных:

Цитирование
@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}
}

Благодарим команды COCO-Text и HierText за создание и поддержку этих наборов данных.

Часто задаваемые вопросы#

  • Нет. При преобразовании создаются полигоны одного класса для обнаружения слов и обучения OBB-моделей. Если для твоего конвейера также нужны транскрипции, используй исходные аннотации COCO-Text и HierText.

  • В COCO-Text есть аннотации для обучения и валидации. В этой конфигурации сохраняется официальный обучающий раздел, а официальные изображения для валидации детерминированно распределяются на подмножества для валидации и тестирования. В HierText остаются официальные разделы.

  • Да. Помести его в каталог Ultralytics datasets_dir, соблюдая стандартную структуру coco/, включая images/train2017, images/val2017 и текстовые файлы разделов COCO. Скрипт загрузки использует эти файлы повторно, не загружая COCO ещё раз.

Участники

Комментарии

Задай вопрос, поделись результатами или помоги кому-нибудь.