File size: 2,366 Bytes
fc27bf1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | # Copyright 2026 AutomatosX
# SPDX-License-Identifier: AGPL-3.0-only
# Modified 2026-10-19 for v1.3; prior component notices are in NOTICE.
"""Detect layout on one page raster using the pinned public Hub weights."""
from __future__ import annotations
import argparse
import json
import sys
import warnings
from pathlib import Path
import numpy as np
from PIL import Image
from ax_doclayout import AXDocLayout, AXDocLayoutError, InvalidPageImageError, PageImage
from ax_doclayout.contract import MAX_PAGE_PIXELS
MODEL_ID = "AutomatosX/AXDocLayout-M-v1.3-CUDA-TF32"
REVISION = "d2725e733fa857100fe75781715276cee4e5a84f"
def load_page(path: Path, *, page_index: int) -> PageImage:
"""Decode a raster without recording its filename or pixels in the output."""
try:
with path.open("rb") as handle:
if handle.read(5) == b"%PDF-" or path.suffix.lower() == ".pdf":
raise InvalidPageImageError("provide a page raster image")
with warnings.catch_warnings():
warnings.simplefilter("error", Image.DecompressionBombWarning)
with Image.open(path) as image:
if image.width * image.height > MAX_PAGE_PIXELS:
raise InvalidPageImageError("page raster exceeds pixel limit")
rgb = np.asarray(image.convert("RGB"), dtype=np.uint8)
except (OSError, ValueError, Image.DecompressionBombError, Image.DecompressionBombWarning):
raise InvalidPageImageError("page raster could not be decoded") from None
return PageImage(rgb=rgb, page_index=page_index)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("image", type=Path)
parser.add_argument("--backend", choices=("onnx", "pytorch"), default="onnx")
parser.add_argument("--page-index", type=int, default=0)
args = parser.parse_args(argv)
try:
page = load_page(args.image, page_index=args.page_index)
model = AXDocLayout.from_pretrained(
MODEL_ID, revision=REVISION, backend=args.backend,
)
print(json.dumps(model.predict(page).to_json(), indent=2, allow_nan=False))
except AXDocLayoutError as error:
print(f"ax-doclayout: {error}", file=sys.stderr)
return 2
return 0
if __name__ == "__main__":
raise SystemExit(main())
|