引入文件影像的多模態文字-影像增強
在這篇博文中,我們將提供一個關於如何使用與 Albumentations AI 協作開發的新文件影像資料增強技術的教程。
動機
視覺語言模型(VLM)具有廣泛的應用範圍,但通常需要針對特定用例進行微調,尤其是對於包含文件影像(即具有大量文字內容的影像)的資料集。在這種情況下,文字和影像在模型訓練的所有階段進行互動至關重要,而對兩種模態應用增強確保了這種互動。本質上,我們希望模型學會正確閱讀,這在資料缺失的常見情況下極具挑戰性。
因此,在解決有限資料集模型微調的挑戰時,有效的文件影像資料增強技術的需求變得顯而易見。一個普遍的擔憂是,常見的影像變換,如調整大小、模糊或更改背景顏色,可能會對文字提取精度產生負面影響。
我們認識到需要資料增強技術來在增強資料集的同時保持文字的完整性。這種資料增強可以促進新文件的生成或現有文件的修改,同時保持其文字質量。
介紹
為了解決這個需求,我們引入了與 Albumentations AI 協作開發的新資料增強流水線。該流水線同時處理影像及其中的文字,為文件影像提供了全面的解決方案。這類資料增強是多模態的,因為它同時修改影像內容和文字註釋。
正如之前一篇部落格文章所討論的,我們的目標是驗證在 VLM 預訓練期間整合文字和影像增強的有效性。詳細引數和用例示例可以在Albumentations AI 文件中找到。Albumentations AI 使得動態設計這些增強並將其與其他型別的增強整合成為可能。
方法
為了增強文件影像,我們首先隨機選擇文件中的行。超引數 `fraction_range` 控制要修改的邊界框分數。
接下來,我們對相應的文字行應用幾種文字增強方法之一,這些方法常用於文字生成任務。這些方法包括隨機插入、刪除和交換,以及停用詞替換。
修改文字後,我們用黑色塗抹影像中插入文字的部分並進行修補,使用原始邊界框大小作為新文字字型大小的代理。字型大小可以用引數 `font_size_fraction_range` 指定,它決定了選擇字型大小作為邊界框高度分數範圍。請注意,修改後的文字和相應的邊界框可以被檢索並用於訓練。這個過程產生了一個語義相似文字內容和視覺扭曲影像的資料集。
文字影像增強的主要功能
該庫主要用於兩個目的:
在影像上插入任意文字:此功能允許您在文件影像上疊加文字,有效地生成合成資料。透過使用任意隨機影像作為背景並渲染全新的文字,您可以建立多樣化的訓練樣本。OCR-free 文件理解轉換器中引入了類似的技術,稱為 SynthDOG。
在影像上插入增強文字:這包括以下文字增強:
- 隨機刪除:隨機從文字中刪除單詞。
- 隨機交換:交換文字中的單詞。
- 停用詞插入:將常用停用詞插入文字中。
將這些增強與 Albumentations 的其他影像變換結合,可以同時修改影像和文字。您也可以檢索增強後的文字。
注意:此倉庫中介紹的資料增強流水線的初始版本包含同義詞替換。此版本中已將其刪除,因為它會導致顯著的時間開銷。
安裝
!pip install -U pillow
!pip install albumentations
!pip install nltk
import albumentations as A
import cv2
from matplotlib import pyplot as plt
import json
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
視覺化
def visualize(image):
plt.figure(figsize=(20, 15))
plt.axis('off')
plt.imshow(image)
載入資料
請注意,對於這種型別的增強,您可以使用 IDL 和 PDFA 資料集。它們提供了您想要修改的行的邊界框。對於本教程,我們將重點關注 IDL 資料集中的樣本。
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)
我們需要正確預處理資料,因為邊界框的輸入格式是標準化的 Pascal VOC。因此,我們構建元資料如下:
page = labels['pages'][0]
def prepare_metadata(page: dict, image_height: int, image_width: int) -> list:
metadata = []
for text, box in zip(page['text'], page['bbox']):
left, top, width_norm, height_norm = box
metadata.append({
"bbox": [left, top, left + width_norm, top + height_norm],
"text": text
})
return metadata
image_height, image_width = image.shape[:2]
metadata = prepare_metadata(page, image_height, image_width)
隨機交換
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))])
transformed = transform(image=image, textimage_metadata=metadata)
visualize(transformed["image"])
隨機刪除
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))])
transformed = transform(image=image, textimage_metadata=metadata)
visualize(transformed['image'])
隨機插入
在隨機插入中,我們向文字中插入隨機單詞或短語。在這種情況下,我們使用停用詞,這些詞是語言中常見的詞,在自然語言處理(NLP)任務中經常被忽略或過濾掉,因為它們與其他詞相比攜帶的意義資訊較少。停用詞的例子包括“is”、“the”、“in”、“and”、“of”等。
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))])
transformed = transform(image=image, textimage_metadata=metadata)
visualize(transformed['image'])
我們可以與其他變換結合嗎?
讓我們使用 A.Compose
定義一個複雜的變換流水線,其中包括指定字型屬性和停用詞的文字插入、普朗克抖動和仿射變換。首先,我們使用 A.TextImage
將文字插入影像,並使用指定的字型屬性,清晰的背景和紅色字型顏色。還指定了要插入文字的分數和大小。然後使用 A.PlanckianJitter
改變影像的顏色平衡。最後,使用 A.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)
])
transformed = transform_complex(image=image, textimage_metadata=metadata)
visualize(transformed["image"])
如何獲取更改後的文字?
要提取文字更改所在的邊界框索引資訊以及相應的轉換文字資料,請執行以下單元格。這些資料可以有效地用於訓練模型識別和處理影像中的文字更改。
transformed['overlay_data']
[{'bbox_coords': (375, 1149, 2174, 1196),
'text': "Lionberger, Ph.D., (Title: if Introduction to won i FDA's yourselves Draft Guidance once of the wasn't General Principles",
'original_text': "Lionberger, Ph.D., (Title: Introduction to FDA's Draft Guidance of the General Principles",
'bbox_index': 12,
'font_color': 'red'},
{'bbox_coords': (373, 1677, 2174, 1724),
'text': "After off needn't were a brief break, ADC member mustn Jeffrey that Dayno, MD, Chief Medical Officer for at their Egalet",
'original_text': 'After a brief break, ADC member Jeffrey Dayno, MD, Chief Medical Officer at Egalet',
'bbox_index': 19,
'font_color': 'red'},
{'bbox_coords': (525, 2109, 2172, 2156),
'text': 'll Brands recognize the has importance and of a generics ADF guidance to ensure which after',
'original_text': 'Brands recognize the importance of a generics ADF guidance to ensure',
'bbox_index': 23,
'font_color': 'red'}]
合成數據生成
這種增強方法可以擴充套件到合成數據的生成,因為它能夠在任何背景或模板上渲染文字。
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.",
}]
transformed = transform(image=image_template, textimage_metadata=metadata)
visualize(transformed['image'])
結論
與 Albumentations AI 合作,我們引入了文字影像增強,這是一種修改文件影像及其文字的多模態技術。透過結合隨機插入、刪除、交換和停用詞替換等文字增強與影像修改,該流水線可以生成多樣化的訓練樣本。
有關詳細引數和用例說明,請參閱Albumentations AI 文件。我們希望這些增強能對您改進文件影像處理工作流程有所幫助。
參考
@inproceedings{kim2022ocr,
title={Ocr-free document understanding transformer},
author={Kim, Geewook and Hong, Teakgyu and Yim, Moonbin and Nam, JeongYeon and Park, Jinyoung and Yim, Jinyeong and Hwang, Wonseok and Yun, Sangdoo and Han, Dongyoon and Park, Seunghyun},
booktitle={European Conference on Computer Vision},
pages={498--517},
year={2022},
organization={Springer}
}