1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 对pdf指定区域截图并提取文字

对pdf指定区域截图并提取文字

时间:2021-12-12 03:13:54

相关推荐

对pdf指定区域截图并提取文字

作者:小小明

截图PDF指定区域并提取文件

需求:PDF文件结构都一致,对于下图红框区域截图并提取文本

测试pdfplumber库

先试用一下pdfplumber看看能否提取出文本

import pdfplumberwith pdfplumber.open("测试文档.pdf") as p:page = p.pages[0]print(page.extract_text())

运行结果:

Date of Test : -11-05 RTest Engineer : ? esKAYSER-THREDE Contact Name : WX ul00 EVAluation Version: 2.1.7 sample.def ta1 nt08Z0Y, 6X, g] 40 1n [ . Poati20 agre ecel oac0 f J071H 7-20 .0; Vo = 15 / -11HEAD00ead Acce 822-750-40 3.889 m1-0500E2ACleration -HFC1080 /s; M = 11 RA / CFC SP 1 Res A_202g]60 60 kg 1000ultant 0_11_t [ 0n 5ulta40 13se _r0 22 5000 F-200 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 ridatime [ms] y, 6.1A1Analysis Interval: 0 - 1000 [ms] naly.202Max(61 ms) = 72 g; Min(4.3 ms) = 0.04043 g s0cHoICn t=. A330m7 (s5(55.64. 6-1 6 -6 .539 m.61s )m; Hs)IC =3 665 =.7 340 g7; ( c5u5.m4 .- A 636m.3s m =s 7);0 H.1I8C g15 = 307 (55.4 - 66.3 ms) is: IA 11:2T3

试用后发现,pdfplumber提取对这种存在旋转文字的pdf文字提取效果非常糟糕,即使是正常顺序的位置,也出现了交错现象。

通过PyMuPDF实现区域截图和区域文字提取

官方文档:https://pymupdf.readthedocs.io/en/latest/index.html

Github:/pymupdf/PyMuPDF

安装:

pip install pymupdf

截图

先测试截取左下角的部分:

from IPython.display import Imageimport fitzpdfDoc = fitz.open("测试文档.pdf")page = pdfDoc[0]mat = fitz.Matrix(1, 1) # 1.5表示放大1.5倍rect = page.rectclip = fitz.Rect(0, 0.87*rect.height,rect.width*0.8, rect.height)pix = page.getPixmap(matrix=mat, alpha=False, clip=clip)display(Image(pix.getImageData()))

fitz.Matrix(1, 1)的两个参数表示宽度和高度的放大系数,上面的截的图较小可以通过该参数放大fitz.Rect有好几种坐标模式,我选择了(x0, y0, x1, y1)这种坐标模式来定位要截取的区域page.getPixmap传入放大系数和区域即可获取图片对象,可直接获取图片的数据也可以写入到文件保存起来

再测试截取右上角部分:

clip = fitz.Rect(0.8*rect.width, 0.27*rect.height,rect.width*0.9, rect.height)pix = page.getPixmap(matrix=mat.preRotate(-90), alpha=False, clip=clip)display(Image(pix.getImageData()))

mat.preRotate(-90)实现了截取区域逆时针旋转90度。

保存图片很简单,只需调用writeImage即可:

pix.writeImage("tmp.png")

文字提取

通过fitz.Rect要提取文字的区域即可:

a_text = page.getText(clip=clip)print(a_text)

1. Page of J7822-75-HFCA__11_05 13_25Head Acceleration SP 1 Resultant11HEAD0000E2ACRA / CFC100075 / -11-050.0; Vo = 13.889 m/s; M = 1160 kgFriday, 6.11. 11:23Analysis: IAT

这段文本提取的效果还不错!

再测试一下左下角部分:

clip = fitz.Rect(0, 0.87*rect.height,rect.width*0.8, rect.height)b_text = page.getText(clip=clip)print(b_text)

Max(61 ms) = 72 g; Min(4.3 ms) = 0.04043 gcont. A3ms(56.61 - 59.61 ms) = 65.74 g; cum. A3ms = 70.18 gHIC = 307 (55.4 - 66.3 ms); HIC36 = 307 (55.4 - 66.3 ms); HIC15 = 307 (55.4 - 66.3 ms)Analysis Interval: 0 - 1000 [ms]

文本行顺序处理

文字的行顺序似乎与原始图片的文本顺序不一致。不过我们可以借助pandas自定义排序,还原到一致的顺序。

import pandas as pdtmp = pd.DataFrame(b_text.splitlines(), columns=["a"])tmp["b"] = (tmp.a.str[:2]).astype("category")tmp.b.cat.set_categories(['An', 're', 'vi', 'Ma', 'co', 'VC', 'ES'], inplace=True)tmp.sort_values('b', inplace=True)b_text = '\n'.join(tmp.a.to_list())print(b_text)

Analysis Interval: 0 - 1000 [ms]Max(61 ms) = 72 g; Min(4.3 ms) = 0.04043 gcont. A3ms(56.61 - 59.61 ms) = 65.74 g; cum. A3ms = 70.18 gHIC = 307 (55.4 - 66.3 ms); HIC36 = 307 (55.4 - 66.3 ms); HIC15 = 307 (55.4 - 66.3 ms)

完整代码

import fitz # pip install PyMuPDFimport osfrom IPython.display import Imageimport pandas as pdpdf_path = "测试文档.pdf"if not os.path.exists("imgs"):os.mkdir("imgs")result = []with fitz.open(pdf_path) as pdfDoc:for i in range(pdfDoc.pageCount):page_num = i+1print("--------------", page_num, "--------------")page = pdfDoc[i]mat = fitz.Matrix(1.3, 1.3) # 1.5表示放大1.5倍rect = page.rectclip = fitz.Rect(0.8*rect.width, 0.27*rect.height,rect.width*0.9, rect.height) # 想要截取的区域pix = page.getPixmap(matrix=mat.preRotate(-90),alpha=False, clip=clip) # 将页面转换为图像pix.writeImage(f"imgs/{page_num}_a.png")img1 = pix.getImageData()display(Image(img1))a_text = page.getText(clip=clip)print(a_text)clip = fitz.Rect(0, 0.87*rect.height,rect.width*0.8, rect.height)pix = page.getPixmap(matrix=mat.preRotate(90), alpha=False, clip=clip)pix.writeImage(f"imgs/{page_num}_b.png")img2 = pix.getImageData()display(Image(img2))b_text = page.getText(clip=clip)tmp = pd.DataFrame(b_text.splitlines(), columns=["a"])tmp["b"] = (tmp.a.str[:2]).astype("category")tmp.b.cat.set_categories(['An', 're', 'vi', 'Ma', 'co', 'VC', 'ES'], inplace=True)tmp.sort_values('b', inplace=True)b_text = '\n'.join(tmp.a.to_list())print(b_text)result.append((a_text, b_text))df = pd.DataFrame(result, columns=["A", "B"])df.to_excel("result.xlsx", index=False)

前5页运行结果展示:

-------------- 1 --------------

1. Page of J7822-75-HFCA__11_05 13_25Head Acceleration SP 1 Resultant11HEAD0000E2ACRA / CFC100075 / -11-050.0; Vo = 13.889 m/s; M = 1160 kgFriday, 6.11. 11:23Analysis: IAT

Analysis Interval: 0 - 1000 [ms]Max(61 ms) = 72 g; Min(4.3 ms) = 0.04043 gcont. A3ms(56.61 - 59.61 ms) = 65.74 g; cum. A3ms = 70.18 gHIC = 307 (55.4 - 66.3 ms); HIC36 = 307 (55.4 - 66.3 ms); HIC15 = 307 (55.4 - 66.3 ms)

-------------- 2 --------------

2. Page of J7822-75-HFCA__11_05 13_25Head Acceleration X SP 111HEAD0000E2ACXA / CFC100075 / -11-050.0; Vo = 13.889 m/s; M = 1160 kgFriday, 6.11. 11:23Analysis: IAT

Analysis Interval: 0 - 1000 [ms]Max(65.5 ms) = 8.15 g; Min(52.2 ms) = -7.426 g

-------------- 3 --------------

3. Page of J7822-75-HFCA__11_05 13_25Head Acceleration Y SP 111HEAD0000E2ACYA / CFC100075 / -11-050.0; Vo = 13.889 m/s; M = 1160 kgFriday, 6.11. 11:23Analysis: IAT

Analysis Interval: 0 - 1000 [ms]Max(59.4 ms) = 71.87 g; Min(52 ms) = -9.89 g

-------------- 4 --------------

4. Page of J7822-75-HFCA__11_05 13_25Head Acceleration Z SP 111HEAD0000E2ACZA / CFC100075 / -11-050.0; Vo = 13.889 m/s; M = 1160 kgFriday, 6.11. 11:23Analysis: IAT

Analysis Interval: 0 - 1000 [ms]Max(56.5 ms) = 20.39 g; Min(63.6 ms) = -23.43 g

-------------- 5 --------------

5. Page of J7822-75-HFCA__11_05 13_25Rib Left Upper Displacement Y SP 111RIBSLEUPE2DSYC / CFC18075 / -11-050.0; Vo = 13.889 m/s; M = 1160 kgFriday, 6.11. 11:23Analysis: IAT

Analysis Interval: 0 - 1000 [ms]Max(314.8 ms) = 0.2821 mm; Min(52.9 ms) = -33.24 mm

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。