Ultralytics YOLO27: Inscreve-te na lista de espera.
Começar

Conjunto de dados OBB de texto em cena

O conjunto de dados OBB de texto em cena combina COCO-Text e HierText num conjunto de dados de deteção de palavras com uma única classe para treinar Caixas delimitadoras orientadas (OBB). Inclui imagens de cenas naturais e documentos com texto rotacionado, curvo, densamente agrupado, manuscrito e impresso.

Principais funcionalidades#

  • 65.325 imagens e 1.288.991 anotações de palavras legíveis após a conversão.
  • Uma classe text com rótulos de polígonos normalizados, compatíveis com os modelos OBB do Ultralytics YOLO.
  • COCO-Text inclui cenas naturais variadas; HierText inclui texto denso de cenas naturais e documentos.
  • Transferências automáticas das fontes, conversão de anotações e ligação de imagens entre plataformas através do YAML do conjunto de dados.
  • Os polígonos de origem com mais de quatro pontos são preservados e reduzidos a retângulos de área mínima pelo pipeline de dados OBB.

Estrutura do conjunto de dados#

O conjunto de dados convertido tem as seguintes divisões. As contagens incluem apenas palavras legíveis com uma área de contorno de pelo menos um píxel; as imagens sem os respetivos ficheiros de origem são excluídas.

DivisãoImagens / palavras de COCO-TextImagens / palavras de HierTextImagens / palavras combinadas
Treinar43,686 / 65,9198,281 / 862,57751,967 / 928,496
Validar4,927 / 7,2111,724 / 178,3826,651 / 185,593
Teste5,073 / 7,7141,634 / 167,1886,707 / 174,902
Total53,686 / 80,84411,639 / 1,208,14765,325 / 1,288,991

COCO-Text usa a sua divisão oficial de treino. As imagens oficiais de validação são repartidas deterministicamente em subconjuntos de validação e teste aproximadamente equilibrados, com base no ID da imagem. HierText mantém as divisões oficiais de treino, validação e teste, com validation renomeado para val.

As imagens sem palavras mantidas permanecem no conjunto de dados com ficheiros de rótulos vazios e servem como imagens de fundo. Os diretórios convertidos usam esta estrutura:

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

Cada linha de rótulo contém a classe 0, seguida das coordenadas normalizadas do polígono. As imagens são ligadas através de ligações físicas quando o sistema de ficheiros as suporta e, caso contrário, são copiadas.

YAML do conjunto de dados#

A configuração scene-text-obb.yaml faz referência aos dois conjuntos de dados convertidos. Na primeira utilização, transfere as imagens COCO 2017, as anotações de COCO-Text e HierText, e as imagens de HierText antes de as converter.

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)
Tamanho das transferências e licenciamento

As fontes requerem aproximadamente 24 GB de transferências. Reserva pelo menos 50 GB de espaço livre durante a transferência e extração iniciais, incluindo os arquivos temporários de COCO. Se as ligações físicas não estiverem disponíveis, as imagens copiadas requerem espaço de armazenamento adicional. Consulta as condições de licenciamento antes de usar ou redistribuir os dados convertidos.

Uso#

Treina um modelo YOLO26 OBB com imagens de 640 píxeis usando os seguintes comandos. Os ficheiros de origem COCO e HierText existentes em datasets_dir do Ultralytics são reutilizados.

Exemplo de treino
from ultralytics import YOLO

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

Aplicações#

Usa este conjunto de dados para treinar detetores de texto ao nível das palavras para processamento de documentos, compreensão de recibos, tradução de sinalética, inspeção industrial e pipelines de OCR. A deteção é apenas uma etapa do OCR: combina o detetor com um reconhecedor de texto quando for necessária a transcrição.

Licenciamento#

O conjunto de dados combinado está sujeito a condições específicas de cada fonte, em vez de uma única licença incondicional:

  • Anotações de COCO-Text: CC BY 4.0. As condições de utilização das imagens COCO subjacentes continuam a aplicar-se.
  • Anotações de HierText: CC BY-SA 4.0. As adaptações redistribuídas requerem atribuição, um aviso de alterações e licenciamento ao abrigo da mesma licença ou de uma licença compatível.
  • Imagens de HierText: Obtidas do Open Images. As condições do Open Images indicam que as imagens estão abrangidas pela licença CC BY 2.0 e instruem os utilizadores a verificar as licenças de cada imagem.

Estas licenças de anotação permitem o uso comercial, sujeito às respetivas condições, mas o conjunto de dados não é de domínio público. Mantém a atribuição às fontes e consulta as condições aplicáveis às imagens ao redistribuir dados.

Citações e agradecimentos#

Se usares este conjunto de dados no teu trabalho, cita ambos os conjuntos de dados de origem:

Citação
@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 às equipas de COCO-Text e HierText por criarem e manterem estes conjuntos de dados.

Perguntas frequentes#

  • Não. A conversão gera polígonos de deteção de palavras de classe única para treino OBB. Usa as anotações originais de COCO-Text e HierText se o teu pipeline também precisar de transcrições.

  • COCO-Text disponibiliza anotações de treino e validação. Esta configuração mantém a divisão oficial de treino e reparte deterministicamente as imagens oficiais de validação em subconjuntos de validação e teste. HierText mantém as suas divisões oficiais.

  • Sim. Coloca-a em datasets_dir do Ultralytics, no formato padrão coco/, incluindo images/train2017, images/val2017 e os ficheiros de texto das divisões de COCO. O script de transferência reutiliza-a em vez de transferir COCO novamente.

Colaboradores

Comentários

Faz uma pergunta, partilha os teus resultados ou ajuda alguém.