Validate and transform various OCR file formats (hOCR, ALTO, PAGE, FineReader)



Codacy Badge Build Status GitHub release ocr-fileformat Docker build

Validate and transform between OCR file formats (hOCR, ALTO, PAGE, FineReader)

Screenshot GUI



You can run the command line scripts and web interface as a Docker container, you only need Docker installed.

To start the web interface on http://localhost:8080:

docker run --rm -it -p 8080:8080 ubma/ocr-fileformat

To run the command line scripts, mount the directory containing your input files into the container's /data directory:

docker run --rm -it -v "$PWD":/data ubma/ocr-fileformat ocr-transform alto2.0 hocr somefile.alto


To install system-wide to /usr/local:

sudo make install

To install without sudo to your home directory:

make install PREFIX=$HOME/.local

If $HOME/.local/bin is not in your PATH, add this to your shell startup file (e.g. ~/.bashrc or ~/.zshrc):

export PATH="$HOME/.local/bin $PATH"

The web application has a PHP backed. You can deploy it on any PHP-capable server by copying the web folder somewhere below the document root of your server, e.g. /var/www/html for Apache on Debian/Ubuntu:

sudo -u www-data cp -r web /var/www/html/ocr-fileformat

In this example the GUI would be available under http://localhost/ocr-fileformat/.


The project offers two functionalities, which can be accessd via a command line script (CLI), using a web interface (GUI) or in you own tools (API)


  • ocr-transform: Transformation of OCR output between OCR formats
  • ocr-validate: Validation of OCR output against OCR format schemas


The web interface is for testing validation and transformations. You can upload a file or select an input file by URL.



Transformation CLI

Usage: ocr-transform [-dl] <input-fmt> <output-fmt> [<input> [<output>]] [-- <saxon_opts>]

For example, you can transform an ALTO XML to a hOCR file with:

ocr-transform alto hocr sample.xml sample.hocr

Or convert from ALTO XML (version 2.1) to hOCR with:

ocr-transform alto2.1 hocr sample.alto sample.hocr

You can also pass arguments directly to the Saxon CLI by passing them after a double dash (--). For example, to set the foo parameter to bar:

ocr-transform alto hocr sample.xml sample.hocr -- foo=bar

Try ocr-transform -h to get an overview:

Usage: ocr-transform [-dhLv]   [ []] [-- ]

        --help    -h     Show this help
        --version -v     Show version
        --debug   -d     Increase debug level by 1, can be repeated
        --list    -L     List transformations

        abbyy hocr
        abbyy page
        alto2.0 alto3.0
        alto2.0 alto3.1
        alto2.0 hocr
        alto2.1 alto3.0
        alto2.1 alto3.1
        alto2.1 hocr
        alto page
        alto text
        gcv hocr
        gcv page
        hocr alto2.0
        hocr alto2.1
        hocr page
        hocr text
        page alto
        page hocr
        page page2019
        page text
        tei hocr

    Saxon options:
        Usage: see!using-xsl/commandline
        Options available: -? -a -catalog -config -cr -diag -dtd -ea -expand -explain -export -ext -im -init -it -jit -l -lib -license -m -nogo -now -o -opt -or -outval -p -quit -r -relocate -repeat -s -sa -scmin -strip -t -T -target -threads -TJ -Tlevel -Tout -TP -traceout -tree -u -val -versionmsg -warnings -x -xi -xmlversion -xsd -xsdversion -xsiloc -xsl -y
        Use -XYZ:? for details of option XYZ
          param=value           Set stylesheet string parameter
          +param=filename       Set stylesheet document parameter
          ?param=expression     Set stylesheet parameter using XPath
          !param=value          Set serialization parameter

Transformation GUI

Select the Transform menu option. Choose a URL, an input and an output format. Click Transform.

Transformation API

The stylesheets are installed in $PREFIX/share/ocr-fileformat/xslt and can be used directly in your scripts and software. You will need to use an XSLT 2.0 capable stylesheet transformer.

Supported Transformations

hOCR =
FineReader -
Google Cloud Vision -
TEI - -


Usage: ocr-validate [-dhL]   []

        --help    -h     Show this help
        --version -v     Show version
        --debug   -d     Increase debug level by 1, can be repeated
        --list    -L     List available schemas

        alto-1-0 alto-1-1 alto-1-2 alto-1-3 alto-1-4 alto-2-0 alto-2-1 alto-2-2-draft alto-3-0 alto-3-1 alto-3-2-draft alto-4-0 alto-4-1
        abbyy-6-schema-v1 abbyy-8-schema-v2 abbyy-9-schema-v1 abbyy-10-schema-v1
        page-2009-03-16 page-2010-01-12 page-2010-03-19 page-2013-07-15 page-2016-07-15 page-2017-07-15 page-2018-07-15 page-2019-07-15

Validation CLI

For example, to validate an XML file againt the ALTO 3.1 schema:

ocr-validate alto-3-1 myFile.alto

Validation GUI

Select the Validate menu option. Choose a URL and an schema. Click Validate.

Validation API

The XSD files are installed under $PREFIX/share/ocr-fileformat/xsd

Supported Validation Formats

hOCR ALTO PAGEXML FineReader Google Cloud Vision
Validation -


This is free software. You may use it under the terms of the MIT License.

During the installation process several projects are included (in ./vendor). These projects have different licenses:

  • Converting hOCR to Alto

    Converting hOCR to Alto

    Hi, first thanks for making this tool.

    I have questions using the GUI to convert hOCR to Alto XML.

    My hOCR file looks as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
    <html xmlns="" xml:lang="unknown" lang="unknown">
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <meta name='ocr-system' content='' />
        <meta name='ocr-langs' content='unknown' />
        <meta name='ocr-number-of-pages' content='1' />
        <meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_line ocrx_word ocrp_lang'/>
        <div class='ocr_page' lang='unknown' title='bbox 0 0 1420 2068'>
            <div class='ocr_carea' lang='unknown' title='bbox 176 121 1420 2068'>
                <span class='ocr_line' id='line_0' title='bbox 678 121 747 168; baseline 0 -5'>
                    <span class='ocrx_word' id='word_0_0' title='bbox 678 121 747 168'>2T</span>
                <span class='ocr_line' id='line_1' title='bbox 383 184 572 218; baseline 0 -5'>
                    <span class='ocrx_word' id='word_1_0' title='bbox 383 184 572 218'>Especially</span>
                <span class='ocr_line' id='line_2' title='bbox 583 184 697 218; baseline 0 -5'>
                    <span class='ocrx_word' id='word_2_0' title='bbox 583 184 697 218'>during</span>
                <span class='ocr_line' id='line_3' title='bbox 722 188 775 215; baseline 0 -5'>
                    <span class='ocrx_word' id='word_3_0' title='bbox 722 188 775 215'>the</span>
                <span class='ocr_line' id='line_4' title='bbox 796 186 888 218; baseline 0 -5'>
                    <span class='ocrx_word' id='word_4_0' title='bbox 796 186 888 218'>years</span>
                <span class='ocr_line' id='line_5' title='bbox 904 184 977 218; baseline 0 -5'>
                    <span class='ocrx_word' id='word_5_0' title='bbox 904 184 977 218'>1933</span>
                <span class='ocr_line' id='line_6' title='bbox 1040 187 1110 218; baseline 0 -5'>
                    <span class='ocrx_word' id='word_6_0' title='bbox 1040 187 1110 218'>1938</span>

    But the ALTO output from the GUI gives me two xml files, which look like this:

    <alto xmlns=""
          <OCRProcessing ID="IdOcr">
          <Page ID="" PHYSICAL_IMG_NR="1" HEIGHT="" WIDTH="">
             <PrintSpace HEIGHT="" WIDTH="" VPOS="0" HPOS="0">
                <ComposedBlock ID="" HEIGHT="1947" WIDTH="1244" VPOS="121" HPOS="176"/>


    <?xml version="1.0" encoding="utf-8"?>
    <alto xmlns=""

    I've not worked with ALTO formats before, but I'm thinking it shouldn't look like this? Please let me know what you think, any help would be greatly appreciated!

    opened by asor12 21
  • Release v0.2.0?

    Release v0.2.0?

    I think we should create a new release. I started to draft one in GitHub, see . However, I am not sure, what has to been done with the release option in the Makefile. Is it enough to increase the version counter? Do you agree that we are now at v0.2.0?

    opened by zuphilip 13
  • Fix conversion from ALTO to PAGE and vice versa

    Fix conversion from ALTO to PAGE and vice versa

    • Fix order of arguments passed
    • Remove shell debugging (-x)
    • Handle input from STDIN
    • Add -convert-to ALTO argument needed for conversion from PAGE to ALTO
    opened by stweil 11
  • Support for google cloud vision 2 hocr by @dinosauria123

    Support for google cloud vision 2 hocr by @dinosauria123

    Works, but ideally:

    • [x] use upstream repo
    • [x] delete temporary files
    • [ ] fall back to max x/y if width height unspecified
    • [ ] maybe port to more flexible language, e.g. python
    opened by kba 11
  • Integrate PRIMA Labs PageConverter

    Integrate PRIMA Labs PageConverter

    Integrates Currently supports ALTO -> PAGE conversion but could be extended (also accepts Google Cloud Vision, hocr, older PAGE versions and FRXML).

    @wrznr @maxnth @chreul

    opened by kba 10
  • Convert Google Cloud Vision OCR output to hocr.

    Convert Google Cloud Vision OCR output to hocr.

    I have a question.

    I try to use Google Cloud Vision API to OCR.

    The output of the OCR results including the position of the texts.

    I want to convert Google OCR output to hocr format, do you have any ideas ?

    I already talked this subject here. Please check our previous discussions.

    opened by dinosauria123 9
  • installation problem under macOS 10.13.6

    installation problem under macOS 10.13.6

    Thanks for the great tool.

    Right now when I run sudo make install I get the following output:

    (base) MacBook-Pro:ocr-fileformat$ sudo make install
    /Applications/ -C vendor check
    # download the dependencies
    /Applications/ -C vendor all
    mkdir -p xsd
    # copy Alto XSD
    cd xsd && ln -sf ../vendor/alto-schema/*/*.xsd . && \
    		for xsd in *.xsd;do \
    			target_xsd=`echo $xsd|sed 's/.//g'|sed 's/-/./'`; \
    			if [ ! -e $target_xsd ];then \
    				mv -f $xsd $target_xsd; \
    			fi; done
    # copy PAGE XSD
    # copy ABBYY XSD
    cd xsd && ln -sf ../vendor/abbyy-schema/*.xsd .
    mkdir -p xslt
    # symlink hocr<->alto as well as the language codes lookup xml
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/hocr2alto2.0.xsl hocr__alto2.0.xsl
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/hocr2alto2.1.xsl hocr__alto2.1.xsl
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/alto2hocr.xsl alto2.0__hocr.xsl
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/alto2hocr.xsl alto2.1__hocr.xsl
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/hocr2text.xsl hocr__text.xsl
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/alto2text.xsl alto__text.xsl
    cd xslt && ln -sf ../vendor/hOCR-to-ALTO/codes_lookup.xml codes_lookup.xml
    cd xslt && ln -sf ../vendor/format-converters/page2hocr.xsl page__hocr.xsl
    cd xslt && ln -sf alto2.0__alto3.0.xsl alto2.0__alto3.1.xsl
    cd xslt && ln -sf alto2.0__alto3.0.xsl alto2.1__alto3.0.xsl
    cd xslt && ln -sf alto2.0__alto3.0.xsl alto2.1__alto3.1.xsl
    mkdir -p /usr/local/share/ocr-fileformat
    cp -r script xsd xslt vendor /usr/local/share/ocr-fileformat
    mkdir -p /usr/local/bin
    sed '/^SHAREDIR=/c SHAREDIR="/usr/local/share/ocr-fileformat"' bin/ > /usr/local/bin/ocr-transform
    sed: 1: "/^SHAREDIR=/c SHAREDIR= ...": command c expects \ followed by text
    make: *** [install] Error 1

    The Docker image runs fine however.

    What am I doing wrong?

    Thanks again

    opened by jtlz2 9
  • Proxy support

    Proxy support

    When a HTTP proxy is needed, conversion from PAGE to ALTO is failing:

    # ocrd-fileformat-transform -I OCR-D-GT-PAGE -O ALTO
    14:36:13.086 INFO ocrd-fileformat-transform - page --> alto: input file OCR-D-GT-PAGE_00000024 (PHYS_0024) Connection timed out (Connection timed out)
            at java.base/ Method)
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/<init>(
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
            at java.base/
    Could not initialise ALTO XML writer
    14:38:23.306 ERROR ocrd-fileformat-transform - Transformation exited with return value 0 but no file was written.

    Unfortunately with the network setup here, this also is a long wait for a connection error because packets are simply dropped...

    The preferred solution for me would be that ocr-fileformat would parse the somewhat standard http_proxy environment variable and passes the correct parameter to java:

    java -Dhttp.proxyPort=3128 [...other parameters...]
    opened by mikegerber 7
  • Add abbyy2hocr transformation by @OCR-D

    Add abbyy2hocr transformation by @OCR-D

    I did not yet test it, but it looks straightforward.

    opened by zuphilip 7
  • Codacy


    (splitted out from #64)

    We first should merge #64 and #66 and then this PR.

    opened by zuphilip 7
  • [doc][fix] clear README cli links

    [doc][fix] clear README cli links


    opened by M3ssman 0
  • Add ImageWare MyBib to ALTO conversion by karkraeg, fix #139

    Add ImageWare MyBib to ALTO conversion by karkraeg, fix #139

    @karkraeg If you could share some test data to make sure the integration works as expected, that would be appreciated.

    opened by kba 2
  • Transformation for ImageWare MyBib

    Transformation for ImageWare MyBib

    I wrote a conversion script to transform ImageWare MyBib eL OCR to ALTO:

    Example for ImageWare OCR:

    Please feel free to use the XSL in your Tool!

    opened by karkraeg 2
  • page__text.xsl is not honoring the reading order

    page__text.xsl is not honoring the reading order

    page__text.xsl is not honoring the reading order in the PAGE-XML (pc:ReadingOrder), which gives completely false results. For this page, I get this text (shortened):

    % docker run --rm -it -v "$PWD":/data ubma/ocr-fileformat ocr-transform page text OCR-D-GT-PAGE/OCR-D-GT-PAGE_00000024.xml | head
    ein gleies vorgegeben, und ſo gar ſehr viele mahle gegen ae menſlie Mglikeit mit Gewalt for-
    ciret worden zu ſeyn, behaupten wi, mithin neb dem Bredekaw, weler (§. 28. 29.)  in aen ſeinen
    Auagen wiederſproen, mit der Pœna fal um do gewier zu belegen i, da
    ſecund. Farin. Tit. 9. qu. 66. p. m. 320.
    die Klage ſo wohl als das Zeugnß vor falſ und erditet mßen gehalten werden.
    §. 35) So viel die von der Inquitin
    write /dev/stdout: broken pipe

    For comparison, dinglehopper-extract gives the correct text:

    % dinglehopper-extract OCR-D-GT-PAGE/OCR-D-GT-PAGE_00000024.xml| head
    rath mit einer Pœna fiſcali angeſehen worden, und ſolche durch des Hrn. Graffen von Königsfeld Vor-
    ſpruch, nur aus Gnaden nachgelaſſen erhalten.
    Sondern man hat auch dieſen 4. Wochen lang alle Abend bey der Inquiſitin gantz allein gelaſſen.
    Binnen welcher gantzer Zeit der Schreiber Bredekaw beſtändig bey Ihme geweſen, und ſich in
    der am 13 ten Octobr. a.c. in Judicio gegen ſeinen geweſenen Hrn. introducirter Appellation deſſen Bey-
    raths bedienet hat;
    §. 33) Dabenebenſt iſt der Schreiber binnen dieſer gantzen Zeit auf freyem Fuß geblieben, und
    hat nicht nur durch ſeinen Conſulenten, ſondern auch, weilen der Inquiſitin ſelbſten in Ihrem Gefängnüß
    ſo viele Freyheit gelaſſen worden, daß ſie frembden Beſuch von Ihren Anverwandten ohngehindert em-

    Image from the ZIP (converted to JPEG), for easier understanding:


    bug enhancement 
    opened by mikegerber 6
  • Web interface in Docker container/ Error when uploading document:

    Web interface in Docker container/ Error when uploading document: "Must be either POST with the field 'file'...."

    I am running the Web service in a Docker container. When trying to upload and process a file, I am getting the following Error: Must be either POST with file field 'file' or GET with param 'url'.

    Bildschirmfoto 2021-05-13 um 12 37 58


    • MacOS 11.3.1
    • Docker Engine v20.10.0
    • ocr-transform v0.4.0
    opened by cboulanger 1
  • Support conversion to MiniOCR

    Support conversion to MiniOCR

    Minimal-noise OCR format for full text indexing

    opened by kba 0
  • alto to text: too many spaces

    alto to text: too many spaces

    Example alto excerpt:

    <TextLine><String CONTENT="Wappen:"/><SP/><String CONTENT="Heimstatt;"/><SP/><String CONTENT="Heimstatt,">... ...

    converts to text

    Wappen:␣␣Heimstatt;␣␣Heimstatt,␣␣Neipperg,␣␣Gemmingen ... ...
    opened by jbarth-ubhd 5
  • Google Cloud Vision to PAGE-XML

    Google Cloud Vision to PAGE-XML

    It was mentioned before but @cneud just reminded me of . Should not be too hard to integrate and would allow using GCV results in OCR-D/Transkribus/OCR4all.

    BTW: Has anyone experience with the Azure Computer Vision API in the context of OCR? As a sign of goodwill in times of Covid-19, they are currently offering a generous free tier including access to the vision API. Would be interesting to compare.

    opened by kba 0
  • New Saxon version 10.2 is out

    New Saxon version 10.2 is out

    We can update to the new Saxon version which is out since some days:

    In principle this only means a similar commit like in but this should be tested then also.

    opened by zuphilip 4
Universitätsbibliothek Mannheim
Mannheim University Library
Universitätsbibliothek Mannheim
Tools for manipulating and evaluating the hOCR format for representing multi-lingual OCR results by embedding them into HTML.

hocr-tools About About the code Installation System-wide with pip System-wide from source virtualenv Available Programs hocr-check -- check the hOCR f

OCRopus 248 Nov 27, 2021
PAGE XML format collection for document image page content and more

PAGE-XML PAGE XML format collection for document image page content and more For an introduction, please see the following publication: http://www.pri

PRImA Research Lab 39 Nov 22, 2021
Page to PAGE Layout Analysis Tool

P2PaLA Page to PAGE Layout Analysis (P2PaLA) is a toolkit for Document Layout Analysis based on Neural Networks. ?? Try our new DEMO for online baseli

Lorenzo Quirós Díaz 169 Nov 19, 2021
OCR-D-compliant page segmentation

ocrd_segment This repository aims to provide a number of OCR-D-compliant processors for layout analysis and evaluation. Installation In your virtual e

OCR-D 52 Nov 29, 2021
Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)

English | 简体中文 Introduction PaddleOCR aims to create multilingual, awesome, leading, and practical OCR tools that help users train better models and a

null 17.7k Dec 3, 2021
It is a image ocr tool using the Tesseract-OCR engine with the pytesseract package and has a GUI.

OCR-Tool It is a image ocr tool made in Python using the Tesseract-OCR engine with the pytesseract package and has a GUI. This is my second ever pytho

Khant Htet Aung 3 Oct 15, 2021
Indonesian ID Card OCR using tesseract OCR

KTP OCR Indonesian ID Card OCR using tesseract OCR KTP OCR is python-flask with tesseract web application to convert Indonesian ID Card to text / JSON

Revan Muhammad Dafa 5 Nov 30, 2021
Deskew is a command line tool for deskewing scanned text documents. It uses Hough transform to detect "text lines" in the image. As an output, you get an image rotated so that the lines are horizontal.

Deskew by Marek Mauder v1.30 2019-06-07 Overview Deskew is a command line tool for des

Marek Mauder 95 Nov 16, 2021
Text page dewarping using a "cubic sheet" model

page_dewarp Page dewarping and thresholding using a "cubic sheet" model - see full writeup at

Matt Zucker 1.1k Dec 2, 2021
Deep learning based page layout analysis

Deep Learning Based Page Layout Analyze This is a Python implementaion of page layout analyze tool. The goal of page layout analyze is to segment page

null 169 Nov 8, 2021
ocroseg - This is a deep learning model for page layout analysis / segmentation.

ocroseg This is a deep learning model for page layout analysis / segmentation. There are many different ways in which you can train and run it, but by

NVIDIA Research Projects 72 Nov 4, 2021
a deep learning model for page layout analysis / segmentation.

OCR Segmentation a deep learning model for page layout analysis / segmentation. dependencies tensorflow1.8 python3 dataset: uw3-framed-lines-degraded-

null 99 Sep 13, 2021
This repository lets you train neural networks models for performing end-to-end full-page handwriting recognition using the Apache MXNet deep learning frameworks on the IAM Dataset.

Handwritten Text Recognition (OCR) with MXNet Gluon These notebooks have been created by Jonathan Chung, as part of his internship as Applied Scientis

Amazon Web Services - Labs 375 Nov 29, 2021
Simple app for visual editing of Page XML files

Name nw-page-editor - Simple app for visual editing of Page XML files. Version: 2021.02.22 Description nw-page-editor is an application for viewing/ed

Mauricio Villegas 26 Nov 15, 2021
~1000 book pages + OpenCV + python = page regions identified as paragraphs, lines, images, captions, etc.

cosc428-structor I had an open-ended Computer Vision assignment to complete, and an out-of-copyright book that I wanted to turn into an ebook. Convent

Chad Oliver 40 Nov 11, 2021
Ready-to-use OCR with 80+ supported languages and all popular writing scripts including Latin, Chinese, Arabic, Devanagari, Cyrillic and etc.

EasyOCR Ready-to-use OCR with 80+ languages supported including Chinese, Japanese, Korean and Thai. What's new 1 February 2021 - Version 1.2.3 Add set

Jaided AI 13.2k Dec 2, 2021
Turn images of tables into CSV data. Detect tables from images and run OCR on the cells.

Table of Contents Overview Requirements Demo Modules Overview This python package contains modules to help with finding and extracting tabular data fr

Eric Ihli 209 Dec 2, 2021
Code for the paper STN-OCR: A single Neural Network for Text Detection and Text Recognition

STN-OCR: A single Neural Network for Text Detection and Text Recognition This repository contains the code for the paper: STN-OCR: A single Neural Net

Christian Bartz 487 Nov 9, 2021