Photo collections stored on a filesystem as nested RO-Crates by
rocphotos. Three kinds of crate share
one root Dataset shape, so one profile covers them; cardinality is asserted
only where it holds for all three.
Root crate (one per collection): sub-collections as Datasets, albums
(ImageGallery), and on mentions every Person/Pet depicted. People are
described here.
Sub-collection crate (one per photo directory): an ImageObject per
photo, an ImageRegion per tagged face/pet, and an instance of each
person/pet depicted.
Faces crate (in the app's housekeeping directory): a FaceEmbedding per
face-recognition reference, for inspection only; matching uses a SQLite index.
People and pets
Identity is collection-wide, derived from the name
(arcp://name,rocphoto/person/<NameSlug>). Each crate holds one instance
per person, which prov:specializationOf that identity; image about, region
about and standoff body proxies point at the instance. This lets a person
appear under different names in different crates (e.g. birth name in 2005,
chosen name in 2025).
Canonical and instance are both schema:Person, told apart by required
properties: name vs prov:specializationOf. Same for pets and body proxies.
Face regions
EXIF (MWG): rebuilt from the photo file on every scan. Area is a
centre point plus size, as fractions.
Standoff: a face confirmed in the app, typed oa:Annotation and
ImageRegion. oa:hasTarget is a Media Fragment whose xywh is the
top-left corner. oa:motivatedBy is always oa:identifying (see
Value lists, below).
Namespaces
schema: and oa: where a term exists; otherwise rocphotos:
(https://w3id.org/ldac/rocphotos/terms#): Pet, ImageRegion,
FaceEmbedding, regionType, writtenToFile, embedding, rating, etc.
Each crate's @context binds these, so bare terms don't fall through to
@vocab. width/height stay schema.org.
Value lists
ItemList values are IRIs, and the crate must contain each value's entity,
matching the profile's copy property for property (@type compared as a
literal string, so write oa:Motivation, not the full IRI).
oa:motivatedBy: "Annotation motivations" list, currently only
oa:identifying (same entity as the
Web Annotation schema).
A list so more motivations can be added later.
regionType: a literal ("Face" or "Pet"), so declared as text, not an
ItemList.
Known gaps
The rocphotos: terms are coined here; schema.org defines none of them.
A FaceEmbedding's about points at a Person the faces crate doesn't
contain, so it is left unconstrained.
about — Everyone depicted, always via this crate's instance of them, never the shared identity directly. #prop_photo_about
about — Who this region depicts, via the crate's instance of them. #prop_region_about
about — The person this is a reference for. Absent entirely for a stranger. #prop_embedding_about
dateCreated — From EXIF DateTimeOriginal. #prop_photo_dateCreated
dateModified — The source file's modification time when last processed — what a rescan compares against to decide whether to re-read it. #prop_photo_dateModified
description — The photo's own caption, if it has one. #prop_photo_description
embedding — The model's own vector. #prop_embedding_embedding
embeddingModel — The model that produced it. #prop_embedding_model
embeddingModelVersion — Its version — a bump makes every reference obsolete, which is why it is recorded per entity. #prop_embedding_modelVersion
exifData — Selected EXIF fields, each as a PropertyValue. #prop_photo_exifData
hasPart — The photos in this crate, or — in the root crate — each sub-collection Dataset and each album. #prop_root_hasPart
hasPart — Membership and display order at once: array order is the order. #prop_album_hasPart
height — The region's height, as a fraction of the image. #prop_region_height
keywords — IPTC/XMP keywords, excluding any that duplicate a region's name. #prop_photo_keywords
mentions — Root crate only: every Person/Pet depicted anywhere in the collection. This is what makes them reachable in the graph, and where their description is meant to accumulate. Deliberately unrestricted in range: a Pet cannot be range-checked until rocphotos binds the rocphotos: prefix in its crates (see the profile text). #prop_root_mentions
name — For a sub-collection, its path relative to the collection root. #prop_root_name
name — The sub-collection's path, e.g. 2025/03/10. #prop_subcollection_name
name — The EXIF field name, e.g. Make. #prop_exif_name
name — The person's name, or "Ignored stranger" for a permanently-suppressed face. #prop_embedding_name
oa:hasBody — A per-region proxy for the subject, so this one sighting could later carry its own properties. #prop_standoff_hasBody
oa:hasTarget — A W3C Media Fragment on the photo — #xywh=percent:x,y,w,h, a top-left corner and size, unlike the centre-based EXIF shape. #prop_standoff_hasTarget
oa:motivatedBy — Always oa:identifying — the annotation says who this is. The value comes from an ItemList so more motivations can be added later. As with any ItemList value, the crate must carry the oa:identifying entity itself, matching the one in this profile. #prop_standoff_motivatedBy
processingError — An EXIF and/or thumbnail failure. Removed once the file processes cleanly. #prop_photo_processingError
prov:specializationOf — The real photo this item stands for. #prop_albumitem_specializationOf
prov:specializationOf — The shared identity this is an instance of. #prop_personinstance_specializationOf
prov:specializationOf — The shared identity this is an instance of. #prop_petinstance_specializationOf
prov:specializationOf — This crate's instance of the person depicted. #prop_regionbody_specializationOf
rating — XMP star rating, 1-5. Absent rather than 0 when unrated. #prop_photo_rating
regions — Every tagged region on this photo, of either shape. #prop_photo_regions
regionType — A literal, either "Face" or "Pet". #prop_region_regionType
regionType — A literal, either "Face" or "Pet". #prop_standoff_regionType
sourceImage — The photo it was computed from, as a collection-relative path. #prop_embedding_sourceImage
sourceRegion — The region it was computed from. Absent for a stranger, which is never written back as a region. #prop_embedding_sourceRegion
thumbnail — The generated thumbnail. #prop_photo_thumbnail
title — Always present: the IPTC/XMP title if the file has one, its filename otherwise. #prop_photo_title
width — The region's width, as a fraction of the image. #prop_region_width
writtenToFile — Whether this region has been written into the photo file's own XMP. Once a rescan finds the same name in the file's real EXIF regions, this region is replaced by the EXIF-derived one. #prop_standoff_writtenToFile
xPosition — The region's centre X, as a fraction of the image. #prop_region_xPosition
yPosition — The region's centre Y, as a fraction of the image. #prop_region_yPosition
Types of entities (specializations of Classes) and expected Properties
Class: Root Data Entity
The root of any rocphotos crate: the collection root, a sub-collection directory, or the faces crate. Distinguished from the sub-collection Datasets a root crate lists by having hasPart of its own.
At least 1 instances of this type MUST be present in the crate.
A maximum of 1 instances of this type MAY be present in the crate.
Root crate only: every Person/Pet depicted anywhere in the collection. This is what makes them reachable in the graph, and where their description is meant to accumulate. Deliberately unrestricted in range: a Pet cannot be range-checked until rocphotos binds the rocphotos: prefix in its crates (see the profile text).
Class: Sub-collection reference
How the root crate lists a sub-collection directory: a Dataset with a trailing-slash id and no hasPart of its own (its own crate holds the photos).
Instances of this type MAY be present in the crate.
A source photograph. Distinguished from the crate's other ImageObjects (thumbnails, album items) by carrying a title, which is always present — the file's own IPTC/XMP title, or its filename.
Instances of this type MAY be present in the crate.
A person, identified by name across the whole collection (arcp://name,rocphoto/person/). The root crate's copy is the one to describe in full; each sub-collection crate carries a minimal copy so it reads standalone.
Instances of this type MAY be present in the crate.
A person as depicted in one crate — one per person per crate, which everything in that crate points at rather than the shared identity. Lets the same person be recorded under the name they went by in this part of the collection.
Instances of this type MAY be present in the crate.
A face or pet tagged in the photo file itself (MWG), rebuilt from EXIF on every rescan. Its area is MWG's own convention: a centre point plus size, as fractions of the image.
Instances of this type MAY be present in the crate.
The region's centre Y, as a fraction of the image.
Number
Class: Region (confirmed here)
A face confirmed in this application, recorded whether or not it is ever written into the photo file. Typed as a Web Annotation as well as an ImageRegion, which is what tells it apart from the EXIF-derived shape.
Instances of this type MAY be present in the crate.
Always oa:identifying — the annotation says who this is. The value comes from an ItemList so more motivations can be added later. As with any ItemList value, the crate must carry the oa:identifying entity itself, matching the one in this profile.
Whether this region has been written into the photo file's own XMP. Once a rescan finds the same name in the file's real EXIF regions, this region is replaced by the EXIF-derived one.
Boolean
Class: Region body
The body of a standoff region: a proxy for the subject, specializing this crate's instance of them (which in turn specializes the shared identity).
Instances of this type MAY be present in the crate.
One reference embedding in the faces crate, for inspection — matching itself queries the companion SQLite index. Points back at the region it came from rather than holding image data.
Instances of this type MAY be present in the crate.
Root crate only: every Person/Pet depicted anywhere in the collection. This is what makes them reachable in the graph, and where their description is meant to accumulate. Deliberately unrestricted in range: a Pet cannot be range-checked until rocphotos binds the rocphotos: prefix in its crates (see the profile text).
Always oa:identifying — the annotation says who this is. The value comes from an ItemList so more motivations can be added later. As with any ItemList value, the crate must carry the oa:identifying entity itself, matching the one in this profile.
Whether this region has been written into the photo file's own XMP. Once a rescan finds the same name in the file's real EXIF regions, this region is replaced by the EXIF-derived one.
{
"@id": "http://www.w3.org/ns/oa#identifying",
"@type": "oa:Motivation",
"name": "identifying",
"description": "The motivation for when the user intends to assign an identity to the Target or identify what is being depicted or described in the Target."
}