ocrd.workspace module

class ocrd.workspace.Workspace(resolver, directory, mets=None, mets_basename='mets.xml', automatic_backup=False, baseurl=None)[source]

Bases: object

A workspace is a temporary directory set up for a processor. It’s the interface to the METS/PAGE XML and delegates download and upload to the Resolver.

Parameters:
  • directory (string) – Folder to work in
  • mets (OcrdMets) – OcrdMets representing this workspace. Loaded from ‘mets.xml’ if None.
  • mets_basename (string) – Basename of the METS XML file. Default: Last URL segment of the mets_url.
  • baseurl (string) – Base URL to prefix to relative URL.
add_file(file_grp, content=None, **kwargs)[source]

Add an output file. Creates an OcrdFile to pass around and adds that to the OcrdMets OUTPUT section.

download_file(f, _recursion_count=0)[source]

Download a ocrd.model.ocrd_file.OcrdFile to the workspace.

download_url(url, **kwargs)[source]

Download a URL to the workspace.

Parameters:
Returns:

The local filename of the downloaded file

Deprecated since version 1.0.0: Use workspace.download_file

image_from_page(page, page_id, fill='background', transparency=False, feature_selector='', feature_filter='')[source]

Extract an image for a PAGE-XML page from the workspace.

Given page, a PAGE PageType object, extract its PIL.Image, either from its AlternativeImage (if it exists), or from its @imageFilename (otherwise). Also crop it, if a Border exists, and rotate it, if any @orientation angle is annotated.

If feature_selector and/or feature_filter is given, then select/filter among the @imageFilename image and the available AlternativeImages the last one which contains all of the selected, but none of the filtered features (i.e. @comments classes), or raise an error.

(Required and produced features need not be in the same order, so feature_selector is merely a mask specifying Boolean AND, and feature_filter is merely a mask specifying Boolean OR.)

If the chosen image does not have the feature “cropped” yet, but a Border exists, and unless “cropped” is being filtered, then crop it. Likewise, if the chosen image does not have the feature “deskewed” yet, but an @orientation angle is annotated, and unless “deskewed” is being filtered, then rotate it. (However, if @orientation is above the [-45°,45°] interval, then apply as much transposition as possible first, unless “rotated-90” / “rotated-180” / “rotated-270” is being filtered.)

Cropping uses a polygon mask (not just the bounding box rectangle). Areas outside the polygon will be filled according to fill:

  • if background (the default), then fill with the median color of the image;
  • otherwise, use the given color, e.g. white or (255,255,255).

Moreover, if transparency is true, and unless the image already has an alpha channel, then add an alpha channel which is fully opaque before cropping and rotating. (Thus, only the exposed areas will be transparent afterwards, for those that can interpret alpha channels).

Return a tuple:

  • the extracted image,
  • a dictionary with information about the extracted image:
    • transform: a Numpy array with an affine transform which converts from absolute coordinates to those relative to the image, i.e. after cropping to the page’s border / bounding box (if any) and deskewing with the page’s orientation angle (if any)
    • angle: the rotation/reflection angle applied to the image so far,
    • features: the AlternativeImage @comments for the image, i.e. names of all operations that lead up to this result,
  • an OcrdExif instance associated with the original image.
(The first two can be used to annotate a new AlternativeImage,
or be passed down with image_from_segment.)

Example

  • get a raw (colored) but already deskewed and cropped image:

    `` page_image, page_coords, page_image_info = workspace.image_from_page(

    page, page_id, feature_selector=’deskewed,cropped’, feature_filter=’binarized,grayscale_normalized’)

    ``

image_from_segment(segment, parent_image, parent_coords, fill='background', transparency=False, feature_selector='', feature_filter='')[source]

Extract an image for a PAGE-XML hierarchy segment from its parent’s image.

Given…

  • parent_image, a PIL.Image of the parent, with

  • parent_coords, a dict with information about parent_image: - transform: a Numpy array with an affine transform which

    converts from absolute coordinates to those relative to the image, i.e. after applying all operations (starting with the original image)

    • angle: the rotation/reflection angle applied to the image so far,
    • features: the AlternativeImage @comments for the image, i.e. names of all operations that lead up to this result, and
  • segment, a PAGE segment object logically contained in it (i.e. TextRegionType / TextLineType / WordType / GlyphType),

…extract the segment’s corresponding PIL.Image, either from AlternativeImage (if it exists), or producing a new image via cropping from parent_image (otherwise).

If feature_selector and/or feature_filter is given, then select/filter among the cropped parent_image and the available AlternativeImages the last one which contains all of the selected, but none of the filtered features (i.e. @comments classes), or raise an error.

(Required and produced features need not be in the same order, so feature_selector is merely a mask specifying Boolean AND, and feature_filter is merely a mask specifying Boolean OR.)

Cropping uses a polygon mask (not just the bounding box rectangle). Areas outside the polygon will be filled according to fill:

  • if background (the default), then fill with the median color of the image;
  • otherwise, use the given color, e.g. white or (255,255,255).

Moreover, if transparency is true, and unless the image already has an alpha channel, then add an alpha channel which is fully opaque before cropping and rotating. (Thus, only the exposed areas will be transparent afterwards, for those that can interpret alpha channels).

When cropping, compensate any @orientation angle annotated for the parent (from parent-level deskewing) by rotating the segment coordinates in an inverse transformation (i.e. translation to center, then passive rotation, and translation back).

Regardless, if any @orientation angle is annotated for the segment (from segment-level deskewing), and the chosen image does not have the feature “deskewed” yet, and unless “deskewed” is being filtered, then rotate it - compensating for any previous angle. (However, if @orientation is above the [-45°,45°] interval, then apply as much transposition as possible first, unless “rotated-90” / “rotated-180” / “rotated-270” is being filtered.)

Return a tuple:

  • the extracted image,

  • a dictionary with information about the extracted image: - transform: a Numpy array with an affine transform which

    converts from absolute coordinates to those relative to the image, i.e. after applying all parent operations, and then cropping to the segment’s bounding box, and deskewing with the segment’s orientation angle (if any)

    • angle: the rotation/reflection angle applied to the image so far,
    • features: the AlternativeImage @comments for the image, i.e. names of all operations that lead up to this result.
(These can be used to create a new AlternativeImage, or passed down
for calls on lower hierarchy levels.)

Example

  • get a raw (colored) but already deskewed and cropped image:

    ``image, xywh = workspace.image_from_segment(region,

    page_image, page_xywh, feature_selector=’deskewed,cropped’, feature_filter=’binarized,grayscale_normalized’)``

reload_mets()[source]

Reload METS from disk.

remove_file(ID, force=False)[source]

Remove a file from the workspace.

Parameters:
  • ID (string|OcrdFile) – ID of the file to delete or the file itself
  • force (boolean) – Whether to delete from disk as well
remove_file_group(USE, recursive=False, force=False)[source]

Remove a fileGrp.

Parameters:
  • USE (string) – USE attribute of the fileGrp to delete
  • recursive (boolean) – Whether to recursively delete all files in the group
  • force (boolean) – When deleting recursively whether to delete files from HDD
resolve_image_as_pil(image_url, coords=None)[source]

Deprecated since version 1.0.0.

Use workspace.image_from_page and workspace.image_from_segment

resolve_image_exif(image_url)[source]

Get the EXIF metadata about an image URL as OcrdExif

Parameters:image_url (string) – URL of image
Return
OcrdExif
save_image_file(image, file_id, file_grp, page_id=None, format='PNG', force=True)[source]

Store and reference an image as file into the workspace.

Given a PIL.Image image, and an ID file_id to use in METS, store the image under the fileGrp file_grp and physical page page_id into the workspace (in a file name based on the file_grp, file_id and format extension).

Return the (absolute) path of the created file.

save_mets()[source]

Write out the current state of the METS file.