知识图谱数据准备:使用LabelBox进行PDF进行文本结构拆分

本文内容来自网络资料与对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
bbox
page
classifications
answer
value

即,将相同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代码说明
read_json:读取json文件
integrate_title:拿object中的title,等同于value
reoutput_json:整合输出新的json
get_text:用于提取json类别中的text类的文本内容

5.总结

  • 优点
    本文只是提供一种解构思路.LabelBox平台提供了一套自动化流程:
设置标注实体与关系
以及标注任务分发
标注人员标注
检查标注结果
修改
下载或自动接收数据JSON文件
接收JSON文件并处理
导入数据库
  • 缺点
    可能不一定高效,且对LabelBox平台要熟悉.
  • 其他
    对于WORD文件可以转为HTML文件,通过提取节点关系即可解构文档.此方法处理的前提是文档本身就层级结构.

引用

[1]LabelBox说明文档:https://docs.labelbox.com/docs/text-annotations

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腹有诗书,何患无辞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值