Hugging Face TextImage Augmentation 管道发布

TL;DR

Hugging Face 和 Albumentations AI 发布了一个 TextImage Augmentation 管道,它同时修改文档图像及其嵌入的文本,实现了真实的合成数据生成,并在有限的文档数据集上对视觉‑语言模型进行稳健的微调。


动机:增强必须保留文本

文档图像包含密集的文本信息,因此传统的仅图像增强(例如,缩放、模糊、背景更改)常常会降低 OCR 性能。博客文章指出,对此类数据的有效数据增强必须 在多样化视觉外观的同时保持文本的完整性。当在小规模文档语料库上微调视觉‑语言模型(VLM)时,这一需求尤为关键,因为缺失或损坏的文本会阻碍学习。

介绍:多模态增强管线

该新管线由 Albumentations AI 共同开发,将文档增强视为一个 多模态 问题:它同步对图像像素和相关的文本标注进行变换。该方法基于之前的 Hugging Face 博客文章,假设文本‑图像联合增强能够提升 VLM 预训练。详细的参数规格和示例用例已在 Albumentations AI 网站上记录。

方法:从边界框到修补文本

  1. Line Selection – 随机选择文档行,依据 fraction_range 超参数控制要修改的边界框比例。
  2. Text Augmentation – 对选中的行应用多种 NLP 风格的操作之一:
    • 随机插入(停用词插入)
    • 随机删除
    • 随机交换
    • 停用词替换
  3. Image Update – 将原始文本区域涂黑,然后用新生成的文本进行修补。字体大小通过 font_size_fraction_range 根据边界框高度计算。管线返回修改后的图像和更新的文本元数据,使下游训练管线能够使用这些转换后的配对。

TextImage Augmentation 的主要特性

1. Synthetic Text Overlay

在任意背景图像上渲染任意文本,创建完全合成的文档样本。 这类似于 OCR‑free 文档理解 Transformer 中的 SynthDOG 技术。

2. Augmented Text Overlay

在保持视觉真实感的同时应用文本层面的扰动。 支持的操作包括:

  • Random Deletion – 随机删除单词。
  • Random Swapping – 在行内交换单词顺序。
  • Stop‑word Insertion – 插入常见停用词(例如 “the”、 “and”)。

这些增强可以与任何 Albumentations 图像变换(例如,颜色抖动、仿射扭曲)组合使用,转换后的文本可通过 overlay_data 字段提取。

注意: 早期版本的仓库包含同义词替换,但由于显著的运行时开销已被移除。

Installation

pip install -U pillow
pip install albumentations
pip install nltk
import albumentations as A, cv2, json, nltk
from matplotlib import pyplot as plt
nltk.download('stopwords')
from nltk.corpus import stopwords

Visualization Helper

def visualize(image):
    plt.figure(figsize=(20,15))
    plt.axis('off')
    plt.imshow(image)

Loading Document Data

该管线期望 行级边界框(归一化 Pascal VOC 格式)和相应的文本。示例数据集:

  • pixparse/idl-wds
  • pixparse/pdfa-eng-wds
bgr_image = cv2.imread('examples/original/fkhy0236.tif')
image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2RGB)
with open('examples/original/fkhy0236.json') as f:
    labels = json.load(f)
font_path = '/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf'
visualize(image)

元数据准备将归一化的框转换为绝对坐标:

def prepare_metadata(page, h, w):
    meta = []
    for txt, box in zip(page['text'], page['bbox']):
        left, top, w_norm, h_norm = box
        meta.append({
            'bbox': [left, top, left + w_norm, top + h_norm],
            'text': txt
        })
    return meta

page = labels['pages'][0]
metadata = prepare_metadata(page, *image.shape[:2])

Text Augmentation Examples

Random Swap

transform = A.Compose([
    A.TextImage(font_path=font_path, p=1, augmentations=['swap'],
                 clear_bg=True, font_color='red',
                 fraction_range=(0.5,0.8),
                 font_size_fraction_range=(0.8,0.9))
])
out = transform(image=image, textimage_metadata=metadata)
visualize(out['image'])

Random Deletion

transform = A.Compose([
    A.TextImage(font_path=font_path, p=1, augmentations=['deletion'],
                 clear_bg=True, font_color='red',
                 fraction_range=(0.5,0.8),
                 font_size_fraction_range=(0.8,0.9))
])
out = transform(image=image, textimage_metadata=metadata)
visualize(out['image'])

Random Insertion (Stop‑word Insertion)

stops = stopwords.words('english')
transform = A.Compose([
    A.TextImage(font_path=font_path, p=1, augmentations=['insertion'],
                 stopwords=stops, clear_bg=True, font_color='red',
                 fraction_range=(0.5,0.8),
                 font_size_fraction_range=(0.8,0.9))
])
out = transform(image=image, textimage_metadata=metadata)
visualize(out['image'])

Combining with Other Albumentations Transforms

复杂的管线可以将文本插入与图像层面的增强交叉使用,例如 PlanckianJitter(色彩平衡)和 Affine(缩放/旋转):

transform_complex = A.Compose([
    A.TextImage(font_path=font_path, p=1, augmentations=['insertion'],
                 stopwords=stops, clear_bg=True, font_color='red',
                 fraction_range=(0.5,0.8),
                 font_size_fraction_range=(0.8,0.9)),
    A.PlanckianJitter(p=1),
    A.Affine(p=1)
])
out = transform_complex(image=image, textimage_metadata=metadata)
visualize(out['image'])

Extracting the Altered Text

overlay_data 字段包含一个字典列表,包含:

  • bbox_coords:修改区域的像素坐标
  • text:新的增强文本
  • original_text:源行文本
  • bbox_index:原始元数据列表中的索引
  • font_color:渲染颜色
print(out['overlay_data'])

示例输出显示了交换或插入的单词,同时保持布局。

Synthetic Data Generation

除了扰动现有文档外,管线还能 在任意模板上渲染任意文本

template = cv2.imread('template.png')
image_template = cv2.cvtColor(template, cv2.COLOR_BGR2RGB)
transform = A.Compose([
    A.TextImage(font_path=font_path, p=1, clear_bg=True,
                 font_color='red', font_size_fraction_range=(0.5,0.7))
])
metadata = [
    {'bbox':[0.1,0.4,0.5,0.48], 'text':'Some smart text goes here.'},
    {'bbox':[0.1,0.5,0.5,0.58], 'text':'Hope you find it helpful.'}
]
out = transform(image=image_template, textimage_metadata=metadata)
visualize(out['image'])

此功能使得在无需人工标注的情况下大规模创建带标签的文档图像成为可能。

Conclusion

TextImage Augmentation 库为文档图像提供了统一的多模态增强工作流。通过将经典的 NLP 扰动(随机插入、删除、交换、停用词替换)与 Albumentations 强大的图像变换相结合,实践者可以生成多样且真实的训练数据,并提升在稀缺文档语料上的 VLM 微调效果。详细的参数文档和示例可在 Albumentations AI 网站上获取。


References

  • Kim, G., Hong, T., Yim, M., 等. OCR‑free Document Understanding Transformer,ECCV 2022。

Installation Summary

pip install -U pillow albumentations nltk

Sources