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 ocrd.Resolver.

Parameters
  • directory (string) – Filesystem folder to work in

  • mets (ocrd_models.ocrd_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.

  • overwrite_mode (boolean) – Whether to force add operations on this workspace globally

  • baseurl (string) – Base URL to prefix to relative URL.

add_file(file_grp, content=None, **kwargs)[source]

Add a file to the ocrd_models.ocrd_mets.OcrdMets of the workspace.

Parameters

file_grp (string) – @USE of the METS fileGrp to add to

Keyword Arguments
Returns

a new ocrd_models.ocrd_file.OcrdFile

download_file(f, _recursion_count=0)[source]

Download a ocrd_models.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.

Parameters
Keyword Arguments
  • fill (string) – a PIL color specifier

  • transparency (boolean) – whether to add an alpha channel for masking

  • feature_selector (string) – a comma-separated list of @comments classes

  • feature_filter (string) – a comma-separated list of @comments classes

Extract a PIL.Image from page, 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, unexposed/masked areas will be transparent afterwards for consumers that can interpret alpha channels).

Returns

a tuple of
  • the extracted PIL.Image,

  • a dict 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 applied operations that lead up to this result,

  • an ocrd_models.ocrd_exif.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().)

Examples

  • 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.

Parameters

segment (object) – a PAGE segment object

:param (i.e. ocrd_models.ocrd_page.TextRegionType: or ocrd_models.ocrd_page.TextLineType

parent_image (PIL.Image): image of the segment’s parent parent_coords (dict): 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

Keyword Arguments
  • fill (string) – a PIL color specifier

  • transparency (boolean) – whether to add an alpha channel for masking

  • feature_selector (string) – a comma-separated list of @comments classes

  • feature_filter (string) – a comma-separated list of @comments classes

Extract a PIL.Image from segment, either from AlternativeImage (if it exists), or producing a new image via cropping from parent_image (otherwise). Pass in parent_image and parent_coords from the result of the next higher-level of this function or from image_from_page().

If feature_selector and/or feature_filter is given, then select/filter among the cropped parent_image and the available AlternativeImage`s 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, unexposed/masked areas will be transparent afterwards for consumers 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.)

Returns

a tuple of
  • the extracted PIL.Image,

  • a dict 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 applied operations that lead up to this result.

(These can be used to create a new AlternativeImage, or passed down

for image_from_segment() calls on lower hierarchy levels.)

Examples

  • 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 the filesystem.

remove_file(ID, force=False, keep_file=False, page_recursive=False, page_same_group=False)[source]

Remove a METS file from the workspace.

Parameters

ID (string|:py:class:ocrd_models.ocrd_file.OcrdFile) – @ID of the METS file to delete or the file itself

Keyword Arguments
  • force (boolean) – Continue removing even if file not found in METS

  • keep_file (boolean) – Whether to keep files on disk

  • page_recursive (boolean) – Whether to remove all images referenced in the file if the file is a PAGE-XML document.

  • page_same_group (boolean) – Remove only images in the same file group as the PAGE-XML. Has no effect unless page_recursive is True.

remove_file_group(USE, recursive=False, force=False, keep_files=False, page_recursive=False, page_same_group=False)[source]

Remove a METS fileGrp.

Parameters

USE (string) – @USE of the METS fileGrp to delete

Keyword Arguments
  • recursive (boolean) – Whether to recursively delete all files in the group

  • force (boolean) – Continue removing even if group or containing files not found in METS

  • keep_files (boolean) – When deleting recursively whether to keep files on disk

  • page_recursive (boolean) – Whether to remove all images referenced in the file if the file is a PAGE-XML document.

  • page_same_group (boolean) – Remove only images in the same file group as the PAGE-XML. Has no effect unless page_recursive is True.

rename_file_group(old, new)[source]

Rename a METS fileGrp.

Parameters
  • old (string) – @USE of the METS fileGrp to rename

  • new (string) – @USE of the METS fileGrp to rename as

resolve_image_as_pil(image_url, coords=None)[source]

Resolve an image URL to a PIL.Image.

Parameters

image_url (string) – @href (path or URL) of the METS file to retrieve

Keyword Arguments

coords (list) – Coordinates of the bounding box to cut from the image

Returns

Full or cropped PIL.Image

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 ocrd_models.ocrd_exif.OcrdExif

Parameters

image_url (string) – @href (path or URL) of the METS file to inspect

Returns

ocrd_models.ocrd_exif.OcrdExif

save_image_file(image, file_id, file_grp, page_id=None, mimetype='image/png', force=False)[source]

Store an image in the filesystem and reference it as new file in the METS.

Parameters
  • image (PIL.Image) – derived image to save

  • file_id (string) – @ID of the METS file to use

  • file_grp (string) – @USE of the METS fileGrp to use

Keyword Arguments
  • page_id (string) – @ID in the METS physical structMap to use

  • mimetype (string) – MIME type of the image format to serialize as

  • force (boolean) – whether to replace any existing file with that @ID

Serialize the image into the filesystem, and add a file for it in the METS. Use a filename extension based on mimetype.

Returns

The (absolute) path of the created file.

save_mets()[source]

Write out the current state of the METS file to the filesystem.

ocrd.workspace.cvtColor(src, code[, dst[, dstCn]]) → dst

. @brief Converts an image from one color space to another. . . The function converts an input image from one color space to another. In case of a transformation . to-from RGB color space, the order of the channels should be specified explicitly (RGB or BGR). Note . that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the . bytes are reversed). So the first byte in a standard (24-bit) color image will be an 8-bit Blue . component, the second byte will be Green, and the third byte will be Red. The fourth, fifth, and . sixth bytes would then be the second pixel (Blue, then Green, then Red), and so on. . . The conventional ranges for R, G, and B channel values are: . - 0 to 255 for CV_8U images . - 0 to 65535 for CV_16U images . - 0 to 1 for CV_32F images . . In case of linear transformations, the range does not matter. But in case of a non-linear . transformation, an input RGB image should be normalized to the proper value range to get the correct . results, for example, for RGB f$rightarrowf$ L*u*v* transformation. For example, if you have a . 32-bit floating-point image directly converted from an 8-bit image without any scaling, then it will . have the 0..255 value range instead of 0..1 assumed by the function. So, before calling #cvtColor , . you need first to scale the image down: . @code . img *= 1./255; . cvtColor(img, img, COLOR_BGR2Luv); . @endcode . If you use #cvtColor with 8-bit images, the conversion will have some information lost. For many . applications, this will not be noticeable but it is recommended to use 32-bit images in applications . that need the full range of colors or that convert an image before an operation and then convert . back. . . If conversion adds the alpha channel, its value will set to the maximum of corresponding channel . range: 255 for CV_8U, 65535 for CV_16U, 1 for CV_32F. . . @param src input image: 8-bit unsigned, 16-bit unsigned ( CV_16UC… ), or single-precision . floating-point. . @param dst output image of the same size and depth as src. . @param code color space conversion code (see #ColorConversionCodes). . @param dstCn number of channels in the destination image; if the parameter is 0, the number of the . channels is derived automatically from src and code. . . @see @ref imgproc_color_conversions