Skip to content

Humanités numériques dans Potato : IIIF, Web Annotation, PAGE XML, TEI et Zooniverse

Importez des manifestes IIIF, des W3C Web Annotations, du PAGE XML et du TEI dans Potato, corrigez des lignes HTR, menez un workflow Zooniverse en privé, et exportez vers chaque format.

Potato 2.12.0 lit et écrit quatre formats d'échange employés en humanités numériques : les manifestes IIIF, W3C Web Annotation, PAGE XML et TEI. Chaque importateur construit un projet exécutable à partir d'un manifeste de bibliothèque, d'une collection d'annotations, d'un export Transkribus ou eScriptorium, ou d'une édition TEI, et chaque exportateur réécrit le travail corrigé dans son format d'origine. Un workflow Zooniverse et ses classifications s'importent de la même façon.

FormatImportExportSource typique
Manifestes IIIF Presentation API 3 (et 2.x)-f iiif-f iiif_annotationsCollections d'images de bibliothèques et de musées, Mirador, Universal Viewer
W3C Web Annotation (JSON-LD)-f web_annotation-f web_annotationAnnotorious, Mirador, Hypothesis
PAGE XML-f page_xml-f page_xmlTranskribus, eScriptorium, OCR-D
TEI P5-f tei-f teiÉditions savantes, corpus

Les annotations de la source arrivent sous forme de pré-annotations, qu'un annotateur voit comme point de départ et qui ne sont stockées que lorsque quelqu'un enregistre.

bash
potato import -i <file or folder> -o <project folder> [-f <format>]
python potato/flask_server.py start <project folder>/config.yaml -p 8000
python -m potato.export -c <project folder>/config.yaml -f <format> -o <output folder>

Les fichiers locaux ne sont copiés que depuis le dossier d'entrée. Un importateur ne copie une image ou un texte local dans le dossier media/ du projet que si le fichier se trouve dans le dossier que vous importez, ou dans un dossier que vous désignez avec --image-dir ou --texts. Toute autre référence, comme un chemin absolu, une URI file://, un chemin ../ ou un lien symbolique qui sort du dossier, est ignorée avec un avertissement, car le serveur publie media/. Déplacez le fichier dans le dossier d'entrée et relancez l'import.

Manifestes IIIF

bash
potato import -f iiif -i manifest.json -o book-project
potato import -f iiif -i https://example.org/iiif/book1/manifest.json -o book-project

L'entrée est un fichier de manifeste, un dossier qui en contient un, ou une URL http(s). Une URL est la seule entrée qui fait utiliser le réseau à l'importateur : il récupère le manifeste et toutes les pages d'annotations que le manifeste référence par URL. Pour un manifeste local, les pages référencées sont lues dans des fichiers du même nom placés à côté de lui.

Chaque Canvas devient un item. L'image est l'id du corps de l'annotation de peinture (painting) ou, quand ce corps n'a pas d'id exploitable ou que --iiif-size est indiqué, une requête au service Image du corps à cette taille (!2000,2000 par défaut). Les libellés et les metadata du manifeste et du canvas sont affichés au-dessus de l'image. Les pages d'annotations du canvas deviennent des formes sur un schéma image_annotation nommé regions, dont les étiquettes sont tirées des tags des annotations. Les coordonnées du canvas sont converties ; un canvas dont la taille diffère de la taille en pixels de l'image reste donc aligné. Les manifestes Presentation 2.x sont lus au mieux.

bash
python -m potato.export -c book-project/config.yaml -f iiif_annotations -o out \
    --option base_url=https://example.org/iiif-out/

L'exportateur écrit une page d'annotations par canvas annoté dans out/annotations/<canvas>.json, et une copie du manifeste dans out/manifest.json avec une référence vers chaque page, dans la version propre au manifeste. Ouvrez le manifeste copié dans Mirador ou Universal Viewer pour voir les annotations. Les rectangles deviennent des fragments #xywh=, les polygones, polylignes, ellipses et formes à main levée deviennent des sélecteurs SVG, les points de repère deviennent des sélecteurs de point, et les réponses aux questions deviennent des corps textuels sur le canvas, chacun avec l'utilisateur Potato qui l'a tracé comme creator. --option embed=true place les pages d'annotations à l'intérieur de la copie du manifeste, de sorte qu'il n'y a rien d'autre à héberger. Les masques n'ont pas de forme IIIF et sont laissés de côté.

L'exemple examples/image/iiif-manifest/ contient deux folios générés, dont l'un porte déjà des annotations.

W3C Web Annotation

bash
potato import -f web_annotation -i annotations.jsonld -o project --texts documents/

L'importateur accepte une AnnotationCollection, une AnnotationPage, une liste d'annotations ou de pages, une Annotation isolée, la réponse de recherche de l'API Hypothesis et les fichiers IIIF 2.x sc:AnnotationList.

CibleDevient
TextQuoteSelector ou TextPositionSelectorUn span sur un schéma span
FragmentSelector xywh=, ou un fragment #xywh= sur la cibleUn rectangle sur un schéma image_annotation
SvgSelector avec un polygon, polyline, rect, circle, ellipse ou pathUn polygone, une polyligne, un rectangle ou une ellipse
PointSelectorUn point de repère
La ressource entièreUne réponse radio ou multiselect à partir des corps tagging et classifying, ou une réponse text à partir des corps describing et commenting

Un span a besoin du texte sur lequel il a été tracé, que l'importateur cherche dans --texts : un dossier de fichiers texte nommés d'après le dernier segment de chemin de chaque cible, ou un fichier JSONL ou JSON de lignes comportant text et l'un des champs source, id, url, uri ou iri. Quand une position et une citation se contredisent, le span est retrouvé par sa citation, prefix et suffix départageant les occurrences répétées. Les régions en pixels ont besoin de la taille de l'image, qui provient des lignes de --texts, du fichier image ou du viewBox d'un sélecteur SVG. Les régions en pixels sur une image de taille inconnue sont laissées de côté avec un avertissement plutôt que placées à une échelle devinée.

Le creator de chaque annotation devient la réponse de cette personne, et avec --keep-annotators ces réponses sont écrites comme le travail enregistré de chacun. Un créateur de type Software est enregistré comme le modèle qui a fait la suggestion. L'export web_annotation écrit web_annotations.jsonld, une seule AnnotationCollection contenant chaque span, région et réponse.

PAGE XML et correction de lignes HTR

bash
potato import -f page_xml -i transkribus-export/ -o htr-project                 # lines (default)
potato import -f page_xml -i transkribus-export/ -o layout-project --page-xml-mode regions

L'entrée est un fichier .xml ou un dossier, parcouru récursivement ; un export Transkribus avec son sous-dossier page/ fonctionne donc. L'image de chaque page est cherchée à côté du XML, un dossier plus haut et dans --image-dir. Les versions de schéma du 2013-07-15 et du 2019-07-15 sont lues.

Le mode lignes, par défaut, crée un item par TextLine, dans l'ordre de lecture de la page. L'annotateur voit la ligne découpée dans la page grâce à l'affichage image_region et corrige le texte reconnu dans un schéma text_edit, qui part du texte de la ligne et montre un diff par mots par rapport à lui. Quand le moteur de reconnaissance a stocké une confiance, elle est reprise sous le nom htr_confidence. Le mode régions crée un item par page, avec chaque région et chaque ligne de texte sous forme de polygone sur un schéma image_annotation nommé layout, étiqueté par type de région.

image_region affiche un rectangle d'une image plus grande. Le navigateur télécharge l'image de la page une seule fois et la découpe ; passer d'une ligne à l'autre d'une même page ne la télécharge donc pas à nouveau :

yaml
instance_display:
  fields:
    - key: line_image
      type: image_region
      label: Line
      padding: 12
json
{"image": "/media/page-001.png", "width": 2480, "height": 3508,
 "region": [412, 980, 1630, 96],
 "polygon": [[412, 980], [2042, 984], [2040, 1076], [410, 1072]]}
OptionValeur par défautSignification
padding8Pixels de l'image affichés autour de la région de chaque côté
outlinetrueTrace le polygone ou le rectangle par-dessus le découpage
show_pagetrueAjoute un volet dépliable "Show the whole image" avec la région délimitée sur la page entière
max_scale2.0Le découpage n'est jamais affiché plus large que ce multiple de sa taille en pixels
alt_text""Nom accessible du découpage
bash
python -m potato.export -c htr-project/config.yaml -f page_xml -o out

L'exportateur ouvre la copie de chaque fichier conservée dans le projet, ne modifie que ce qui a été corrigé et réécrit tout le reste tel quel, y compris les métadonnées, l'ordre de lecture et la version du schéma. Une ligne corrigée reçoit son nouveau texte, et la confiance du moteur de reconnaissance est supprimée. En mode mise en page, les formes déplacées mettent à jour les coordonnées de leur élément, les nouvelles formes deviennent de nouvelles lignes ou régions, et les formes supprimées sont retirées avec leur référence dans l'ordre de lecture. Les lignes que personne n'a annotées restent inchangées.

L'exemple examples/text/htr-line-correction/ contient une image de page générée comportant cinq lignes et un fichier PAGE XML dont le texte reconnu comporte des erreurs à corriger.

TEI P5

bash
potato import -f tei -i edition/ -o tei-project              # one item per block
potato import -f tei -i letters.xml -o tei-project --tei-unit div

--tei-unit définit ce qui compte comme un item : p (paragraphes, titres et groupes de vers, par défaut), div, s ou l. Les éléments en ligne <persName>, <placeName>, <orgName>, <geogName>, <name>, <date> et <time> deviennent des spans étiquetés du nom de l'élément, et <rs type="ship"> est étiqueté ship. Le texte de l'item est un texte de lecture : <choice> prend la forme régularisée, corrigée ou développée, <del>, <note> et <fw> sont laissés de côté, <lb/> est un saut de ligne, et <gap/> vaut [...].

L'export tei écrit un document TEI par fichier source, en enveloppant chaque span dans son étiquette quand celle-ci est un élément de nom TEI, et dans <rs type="LABEL"> sinon. Un span qui en chevauche un autre ne peut pas s'imbriquer en XML ; il est donc placé dans <standOff><listAnnotation> comme annotation string-range, et le résumé de l'export indique combien l'ont été. L'exportateur construit un nouveau document à partir du projet et ne modifie pas le fichier source ; les métadonnées d'en-tête autres que le titre ne sont donc pas reprises.

Zooniverse

potato import lit les exports d'un projet Zooniverse : les tâches du workflow deviennent des schémas d'annotation, les sujets deviennent des items, et les classifications des bénévoles peuvent être reprises comme leur travail enregistré. Cela convient pour mener un workflow en privé, avec des données non publiées, une équipe de laboratoire ou des annotateurs rémunérés, ou pour calculer l'accord sur les classifications d'un projet existant.

Depuis Lab → Data Exports dans le projet, demandez les exports du workflow, des classifications et des sujets, et placez les trois fichiers CSV dans un même dossier :

bash
potato import -i zooniverse-exports/ -o my-project --keep-annotators
Tâche ZooniversePotato
Question (réponse unique)radio
Question (réponses multiples), raccourcimultiselect
Textetext
Curseurslider
Liste déroulante (simple)select
Dessin : point, rectangle, polygone, ligne, cercle ou ellipse, main levéeimage_annotation avec l'outil correspondant
Surligneurspan, quand le texte du sujet figure dans ses métadonnées
ComboSes tâches, chacune comme ci-dessus
Branchementdisplay_logic sur les tâches atteintes par cette réponse

Zooniverse présente les tâches l'une après l'autre, et Potato les présente sur une seule page, en révélant chacune dès que les réponses qui y mènent sont données. Une seule version du workflow est importée, par défaut la version majeure la plus récente utilisée par les classifications. Les tâches de type survey (identification d'espèces avec questions de suivi), les questions de sous-tâches de dessin, les tâches de transcription et les classifications portant sur plusieurs sujets sont comptées dans la sortie et ne sont pas importées. Les bénévoles qui n'étaient pas connectés apparaissent sous la forme anon_<id> ; une même personne peut donc apparaître plusieurs fois.

Pour aller plus loin

Pour les détails d'implémentation, consultez la documentation source sur les formats des humanités numériques et sur Zooniverse.