Augraphy Documentation

repository·dev·Indexed 20 days ago

https://github.com/sparkfish/augraphy

A Python library for creating realistic, noisy document images from clean originals. It simulates printing, scanning, faxing, and physical wear to generate synthetic training data for AI/ML document restoration, OCR, and form recognition. The library features a multi-stage pipeline (ink extraction, augmentation, paper generation, and merging) and supports both pixel-level and spatial-level augmentations, including interoperability with Albumentations and imgaug.

Tokens
55.4K
Snippets
130
Records
159
Agent score
66%

What's inside Augraphy

  1. Overview of Augraphy

    dev

    Augraphy is a Python library designed to create realistic, degraded copies of original documents through an augmentation pipeline. It simulates real-world paper-oriented distortions such as:

    • Synthetic paper printing: Simulating dirty laser or inkjet printers.
    • Scanning: Simulating dirty office scanners.
    • Faxing: Simulating low-resolution fax machines.
    • Copy machine processes: Simulating various copy machine distortions.

    By applying these random distortions, Augraphy acts as a factory that produces an almost infinite number of variations from a single source document. This is primarily used to generate large amounts of synthetic training data for AI/ML models to learn how to remove document noise and distortions.

  2. Understand the purpose and focus of Augraphy

    dev

    Augraphy is a data augmentation library specifically designed for document images. Unlike most augmentation libraries that focus on camera-oriented data (video and natural images), Augraphy targets distortions caused by paper-oriented processes such as printing, faxing, scanning, and copy machines.

    Use Augraphy to support tasks like:

    • OCR (Optical Character Recognition)
    • Form recognition and data extraction
    • Document classification
    • Barcode decoding
    • Denoising and document restoration
    • Identity document data extraction
    • Document cropping
  3. What is PaperFactory and how does it work?

    dev

    PaperFactory is an augmentation designed specifically for the 'paper phase' of an augmentation pipeline. It applies a texture to an image by randomly selecting an image from a specified directory and blending it with the input image. This is useful for simulating various paper surfaces and textures in document augmentation workflows.

    paper_phase = [PaperFactory(texture_path=paper_texture_dir, p=1)]
  4. Use AugmentationSequence to apply multiple augmentations sequentially

    dev

    The AugmentationSequence class allows you to group multiple augmentations into a single unit that is applied sequentially. This is useful for organizing complex augmentation pipelines into logical phases (like ink, paper, or post-processing).

    Each AugmentationSequence can take a list of augmentation objects and an optional probability parameter p. You can also nest AugmentationSequence objects inside other sequences to create complex, hierarchical augmentation patterns.

    from augraphy import *
    
    # A simple sequence of two augmentations
    ink_phase = [
        AugmentationSequence([
            InkBleed(p=1),
            WaterMark(p=1)
        ], p=1)
    ]
    
    # A nested sequence for complex post-processing
    post_phase = [
        AugmentationSequence([
            AugmentationSequence([
                BleedThrough(p=1),
                DirtyDrum(p=1)
            ], p=1),
            AugmentationSequence([
                Folding(p=1),
                DirtyRollers(p=1)
            ], p=1)
        ], p=1)
    ]
  5. How Augraphy's augmentation pipeline works

    dev

    Augraphy uses a multi-phase pipeline to transform a clean document image into a realistic, degraded version. The process follows these conceptual steps:

    1. Ink Phase: The pipeline extracts text and graphics from the source image into an "ink" layer (synonymous with toner). This layer is then distorted and degraded.
    2. Paper Phase: A paper texture is provided (either a white page or a randomly selected texture). This layer can also undergo its own augmentation pipeline to create realistic paper textures.
    3. Merging: The processed ink layer is applied to the processed paper layer.
    4. Post Phase: The merged document image undergoes final augmentations, such as physical deformations (folds) or distortions that involve the interaction between the paper and ink layers.

    The result is a single image that mimics a real, physical document.

  6. Compose multiple AugraphyPipelines using ComposePipelines

    dev

    The ComposePipelines utility allows you to chain multiple AugraphyPipeline instances together. Each pipeline in the sequence is applied to the output of the previous one.

    When you execute the composed pipeline on an image, it returns a dictionary containing the intermediate and final results. The keys for the outputs follow the naming convention pipeline(n-1)-output, where n is the total number of pipelines in the composition (using 0-based indexing for the pipeline number).

    from augraphy import *
    from augraphy.utilities.composepipelines import ComposePipelines
    
    # Define individual pipelines
    pipeline1 = AugraphyPipeline([InkBleed(p=1)], [DirtyRollers(p=1)], [WaterMark(p=1)])
    pipeline2 = AugraphyPipeline([BleedThrough(p=1)], [DirtyDrum(p=1)], [Faxify(p=1)])
    
    # Compose them
    compose_pipeline = ComposePipelines([pipeline1, pipeline2])
    
    # Apply to an image
    # The output is a dict. pipeline2 is the second pipeline (index 1).
    results = compose_pipeline(image)
    augmented_image = results["pipeline1-output"] # Output of the first pipeline
    final_image = results["pipeline2-output"]     # Output of the second pipeline
  7. Use the Rescale augmentation to adjust image DPI

    dev

    The Rescale augmentation adjusts an image to a specific target DPI. It is most effective when used in the pre_phase of an AugraphyPipeline combined with the fixed_dpi parameter.

    When fixed_dpi=1 is set in the pipeline, the input image is rescaled to the target_dpi for the augmentation process, and the resulting augmented image is automatically rescaled back to the original input DPI at the end of the pipeline. This ensures that the augmentation effects (like ink bleed or paper texture) are applied at a consistent scale regardless of the input image resolution.

    rescale = Rescale(target_dpi=300)
    
    # Using fixed_dpi=1 ensures the image is scaled back to original DPI after augmentation
    pipeline = AugraphyPipeline(
        pre_phase=[rescale],
        ink_phase=[InkBleed()],
        paper_phase=[ColorPaper()],
        post_phase=[BleedThrough()],
        fixed_dpi=1
    )
    
    augmented_image = pipeline(image)
  8. Use OverlayBuilder to overlay images

    dev

    The OverlayBuilder class is the base class used to overlay a foreground image onto a background image. It supports over 10 different overlaying methods and provides advanced manipulation features such as:

    • Scaling: Resizing the foreground image.
    • Duplication: Creating multiple instances of the foreground.
    • Offsetting: Shifting the position of the foreground image.
    from augraphy.utilities.overlaybuilder import OverlayBuilder
    
    # OverlayBuilder is used to overlay a foreground image onto a background image.
    # It supports various methods, scaling, duplication, and offsetting.
  9. Understand Per-process vs. In-process Randomness

    dev

    Setting a random seed in Augraphy guarantees identical results between different invocations of the same Python script (different processes).

    However, it does not guarantee identical results between successive pipeline executions within the same Python process. Because the pseudorandom number generator state advances with every call, running the same pipeline twice in a single script will produce different augmented images unless the seed is reset between runs.

    from augraphy import *
    import random
    import cv2
    
    # Setting the seed once at the start of the process
    random.seed(0)
    img = cv2.imread("image.png")
    
    # These two calls will produce DIFFERENT results because the RNG state has advanced
    augmented1 = default_augraphy_pipeline()(img)
    augmented2 = default_augraphy_pipeline()(img)
    
    # To get identical results, you would need to re-seed before the second call