{"id":23124291,"url":"https://github.com/cconzen/readingorderrecalculation","last_synced_at":"2025-06-28T19:37:25.881Z","repository":{"id":257035684,"uuid":"857119631","full_name":"cconzen/ReadingOrderRecalculation","owner":"cconzen","description":"Post-process PageXMLs to improve their region reading order","archived":false,"fork":false,"pushed_at":"2024-10-21T16:50:54.000Z","size":11452,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-04T23:24:06.509Z","etag":null,"topics":["pagexml","reading-order","transkribus"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cconzen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-13T20:59:51.000Z","updated_at":"2025-01-27T11:00:29.000Z","dependencies_parsed_at":"2024-10-22T16:25:35.819Z","dependency_job_id":null,"html_url":"https://github.com/cconzen/ReadingOrderRecalculation","commit_stats":null,"previous_names":["cconzen/readingordercorrection"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cconzen/ReadingOrderRecalculation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cconzen%2FReadingOrderRecalculation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cconzen%2FReadingOrderRecalculation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cconzen%2FReadingOrderRecalculation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cconzen%2FReadingOrderRecalculation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cconzen","download_url":"https://codeload.github.com/cconzen/ReadingOrderRecalculation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cconzen%2FReadingOrderRecalculation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262484877,"owners_count":23318546,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pagexml","reading-order","transkribus"],"created_at":"2024-12-17T07:39:57.574Z","updated_at":"2025-06-28T19:37:25.860Z","avatar_url":"https://github.com/cconzen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PageXML Reading Order Recalculation\n\nThis is a simple rule-based script for recalculating the region reading order of a PageXML file. It is meant to post-process results of a layout recognition using [Transkribus](https://www.transkribus.org/) or [Loghi](https://github.com/knaw-huc/loghi). More specifically, it is modelled to correctly order one or two page scans which contain marginalia. \n\nThis script was developed for [Het Utrechts Archief](https://hetutrechtsarchief.nl/) within the context of an internship.\n\n## What It Does\n\n- **Extract Features**: Parses XML files to extract image information (height, width) as well as text regions and their coordinates.\n- **Calculate Reading Order**: Uses extracted features to calculate the region reading order.\n- **Update Files**: Saves the new reading order into the PageXMLs.\n  \n## Requirements\n\nYou only need numpy and pandas in addition to some standard Python libraries. You can install the required dependencies using pip:\n\n```\npip install numpy pandas\n```\n\n## Usage\n\n### Batch Reading Order Recalculation of PageXML files\n\nThe code is written to process all XML files located in a directory; To execute the script, install all dependencies first and then run following:\n```\npython reorder.py example_folder/page --overwrite\n```\nAs arguments, specify the base directory containing the PageXML files (here example_folder/page), and add --overwrite if you wish to overwrite the existing file.\n\n## How It Works\n\nThe script is using simple logic based on the geometric properties of the regions and page.\n\nGiven this sample layout of a scan:\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/start.svg\" width=\"100%\"\u003e\n\n1. Determine orientation (landscape = two pages, portrait = one page) based on the image’s height and width. Depending on the orientation, the bookfold location is estimated:\n   - at the horizontal centre of the scan for landscape orientation\n   - at the left edge (x = 0) for portrait orientation\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/page_side.svg\" width=\"100%\"\u003e\n\n2. The regions are assigned either 0 for left page or 1 for right page based on where their own horizontal centre is located.\n3. The regions are ordered:\n    - Left page to right page\n        - Top to bottom\n            - Left to right\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/firstorder.svg\" width=\"100%\"\u003e\n\n4. The script then uses this initial order to iterate through all regions, comparing every current box with its immediate following one in the ranking. It checks whether the following box might be a marginalium by inspecting if they are located on the same page, and then if the candidate is vertically contained within the current box:\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/verticallywithin.svg\" width=\"100%\"\u003e\n\n5. It is then confirmed that it is located to the left or right of the current box (In this case, it is considered to be left of it; it’s comparing the left edge for the left condition (and vice versa) so overlapping boxes are handled correctly):\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/leftcheck.svg\" width=\"100%\"\u003e\n\n6. If all these conditions apply, their ranks/indices are swapped:\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/swapranks.svg\" width=\"100%\"\u003e\n\n7. If a swap occurs, the loop breaks and restarts with the new order. This gets repeated until no more swaps occur in a full loop; the final reading order has been reached:\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/explanation_svgs/finalorder.svg\" width=\"100%\"\u003e\n\n### Visualisation\n\nYou can visualise the calculated reading order path by specifying your base directory and executing it:\n```\npython visualise.py example_folder\n```\nHere are some side-by-side comparisons of input image and visualised result: \n\n(these can be found in the [example_folder](https://github.com/cconzen/ReadingOrderRecalculation/tree/main/example_folder); The scans were processed using [Loghi](https://github.com/knaw-huc/loghi).\n\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/example_folder/default.jpg\" width=\"50%\" height=\"50%\"\u003e\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/visualisation/default_vis.jpg\" width=\"50%\" height=\"50%\"\u003e\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/example_folder/default2.jpg\" width=\"50%\" height=\"50%\"\u003e\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/visualisation/default2_vis.jpg\" width=\"50%\" height=\"50%\"\u003e\n\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/example_folder/default5.jpg\" width=\"50%\" height=\"50%\"\u003e\u003cimg src=\"https://github.com/cconzen/readingOrderCorrection/blob/main/visualisation/default5_vis.jpg\" width=\"50%\" height=\"50%\"\u003e\n\n# License\nThis project is licensed under the MIT License - see the LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcconzen%2Freadingorderrecalculation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcconzen%2Freadingorderrecalculation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcconzen%2Freadingorderrecalculation/lists"}