文章目录
本文内容来自网络资料与对GhatGPT的答案整理
1.背景
目前在做知识图谱相关的前期工作,需要对已有数据文件进行结构拆分,并形成知识卡片录入到数据库系统中以便开发使用,数据形式包括PDF和Word文档.
2.知识图谱
3.LabelBox介绍
LabelBox是一款专业的在线标注工具,支持图像标注和文本标注,可以进行分类、边界框、实体、关系等多种标注类型。Labelbox提供了许多先进的功能,如自动标注、质量控制、标注审核等,可以大大提高标注效率和标注结果的准确度。Labelbox还提供了API接口,可以与其他自然语言处理工具和机器学习平台无缝集成。
Labelbox是一种基于云的SaaS(软件即服务)平台,提供各种功能和服务。
以下是Labelbox的付费和免费功能的概述:
免费功能:
注册和创建账户
创建项目和数据集
上传、存储和下载数据
标注数据
导出标注数据
API访问
付费功能:
高级用户和数据管理功能,如多用户协作、团队管理、数据共享和数据安全性。
个性化标注工具和流程的开发和集成
自定义机器学习模型的集成和部署
管理和监视机器学习模型的训练和推理
4.使用LabelBox结构化PDF思路
- 上传PDF文档到LabelBox
- 使用box对图像进行文本结构的划分(即划框框的形式)
- 将标注好的PDF的Json信息文件导出
- 从Json中获取想要数据,组成新Json或其他数据存储形式
其中,Json中存有用box划出的内容的所在的page,top,left,height,width
便于定位.可利用该信息对内容进行图片保存或标记以及文本提取.
以下要讲的就是如何利用LabelBox返回后的Json对PDF内容进行图片和文本提取,主要用到
python
其中的pymupdf库和Json库
4.1实例
4.1.1Json文件内容(部分)
[
{
"ID": "clfj6ab7l05jh07yl3w4x4k2w",
"DataRow ID": "clfg6ups05f2t07a7h1xvemuo",
"Labeled Data": "https://storage.labelbox.com/clexq07141apd072r1m1ifq8s%2Ff0bfa415-4fed-cf00-d446-bfb876da3d54-%E4%B8%8A%E4%BD%8D%E6%9C%BA%E8%B0%83%E8%AF%95%E8%BD%AF%E4%BB%B6%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C.pdf?Expires=1680668784197&KeyName=labelbox-assets-key-3&Signature=0P73ytvWOhfrvMGNKsjCSDSBGjM",
"Label": {
"objects": [
{
"featureId": "clfj6l1mf00013b672tusfse0",
"schemaId": "clfj3ok5p1su607ygc19t4mnt",
"color": "#FF4A46",
"title": "选择产品对应的调试通讯方式",
"value": "选择产品对应的调试通讯方式",
"bbox": {
"top": 616.364,
"left": 62.53,
"height": 94.432,
"width": 419.842
},
"page": 1,
"unit": "POINTS",
"instanceURI": "https://api.labelbox.com/masks/feature/clfj6l1mf00013b672tusfse0?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjbGV4cTA3MWwxYXBlMDcycjg0ZHFibmtuIiwib3JnYW5pemF0aW9uSWQiOiJjbGV4cTA3MTQxYXBkMDcycjFtMWlmcThzIiwiaWF0IjoxNjc5NDU5MTg0LCJleHAiOjE2ODIwNTExODR9.ZzvQvZnmgY050UpT0d-cipsTjXfyB9hvUheJl283TUY",
"classifications": [
{
"featureId": "clfj6l64q00043b67yu0yu4kz",
"schemaId": "clfj6kihj03aa07zdgd8mfx3f",
"title": "类型",
"value": "类型",
"position": 0,
"answer": {
"featureId": "clfj6l64q00033b67ndj60oxu",
"schemaId": "clfj6kihj03ab07zdfsd2aqa4",
"title": "text",
"value": "text",
"position": 0
}
}
]
}]}}]
一般取object关键参数:
value,bbox,page,classifications.answer.value
4.1.2构造新JSON
即,将相同value的若干字典存储为新JSON.
4.1.2.1 Code
#读取pdf
import fitz
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageDraw
import json
#读取json文件,取出需求键值对
def read_json(path):
# 从文件中读取JSON数据并将其解码为Python对象
with open(path, 'r',encoding='utf-8') as f:
data = json.load(f)
# 输出读取的Python对象
# print(data)
data_json=json.dumps(data, indent=4)
# print(data_json)#参数应该是一个整数,指定输出 JSON 字符串时缩进的空格数
# print(type(json.loads(data_json)))
useful_dict =json.loads(data_json)[0]["Label"]["objects"]
print(type(useful_dict),len(useful_dict))
return useful_dict
# 通过坐标提取pdf文本
def get_text(path: str, page_num: int, box: dict) -> str:
# 打开 PDF 文件
with fitz.open(path) as doc:
# 获取第一页
page = doc[page_num - 1]
# print(page)
# 设置要查找的文本范围(左上角和右下角坐标)
x1, y1 = box["left"], box["top"]
x2, y2 = box["left"] + box["width"], box["top"] + box["height"]
bbox = fitz.Rect(x1, y1, x2, y2)
# print(bbox)
# # 使用 Fitz 库的 get_pixmap() 方法将页面转换为像素图像
# pixmap = page.get_pixmap()
# # 使用 PIL 库将图像转换为 Image 对象
# image = Image.frombytes("RGB", [pixmap.width, pixmap.height], pixmap.samples)
# print(pixmap)
# # 在图像上绘制矩形框来突出显示标题
# draw = ImageDraw.Draw(image)
# draw.rectangle([x1, y1, x2, y2], outline="red", width=3)
# # 显示图像
# image.show()
# 使用 Fitz 库的 TextPage 类提取指定区域的文本
text = page.get_text("text", clip=bbox)
# 输出提取的文本
# print(text)
return text
# 整理
def integrate_title(list_dict: list) -> list:
"""
计算object中相同title的字典
"""
dict_equal_title = []
for object_dict, index in zip(useful_dict, range(len(useful_dict))):
dict_equal_title.append((object_dict["title"]))
count_dict = {}
for item in dict_equal_title:
if item in count_dict:
count_dict[item] += 1
else:
count_dict[item] = 1
# print(list(count_dict.values()))
# return list(count_dict.values())
return count_dict
# 取字典(重要)
def reoutput_json(path, start, end):
dict_ = {} # 基本型
caculate = 0
dict_out_list = [] # 列表输出型
for j in range(start, end): # 此处的有问题,因该是递进索引关系,而不是重置索引
dict_output = {} # 输出型
dict_["title"] = useful_dict[j]["title"]
dict_["bbox"] = useful_dict[j]["bbox"]
dict_["page"] = useful_dict[j]["page"]
dict_["类型"] = useful_dict[j]["classifications"][0]["answer"]["value"]
# print(type(dict_),dict_,type(dict_["类型"]))
# print(dict_["类型"]=='image',dict_["类型"]=='gif', dict_["类型"]=='text')
if dict_["类型"] == 'image' or dict_["类型"] == 'gif':
dict_output["content"] = caculate
dict_output["abstract"] = ""
dict_output["tag"] = dict_["类型"]
caculate = caculate + 1
if dict_["类型"] == 'text':
text = get_text(path, dict_["page"], dict_["bbox"])
dict_output["content"] = text
dict_output["tag"] = "text"
dict_out_list.append(dict_output)
return dict_out_list
if __name__ =="__main__":
path ="上位机调试软件使用手册.pdf"
path_json ="模板.json"
start=0
end=0
useful_dict = read_json(path_json)
dict_for_index = integrate_title(useful_dict)
dict_for_index
for i,index in zip(list(dict_for_index.values()),range(len(list(dict_for_index.values())))):
end=sum(list(dict_for_index.values())[:index+1])
# print(end)
print(reoutput_json(path,start,end))#需要设置起始于终止参数用于for循环(start,end)
start = sum(list(dict_for_index.values())[:index+1])
output:
4.1.2.2代码说明
5.总结
- 优点
本文只是提供一种解构思路.LabelBox平台提供了一套自动化流程:
- 缺点
可能不一定高效,且对LabelBox平台要熟悉. - 其他
对于WORD文件可以转为HTML文件,通过提取节点关系即可解构文档.此方法处理的前提是文档本身就层级结构.
引用
[1]LabelBox说明文档:https://docs.labelbox.com/docs/text-annotations