很多pdf文件文字识别软件都会收费,免费的网页版可能会带来信息泄露,还有一些类似于腾讯AI
和百度AI
的接口都有调用次数限制,因此,利用识别正确率极高且免费的cnocr
库来自己动手做个pdf
文件文字识别程序就是一个很不错的选择。以下程序利用pymupdf
打开pdf
文件并将页面图像数据读出,然后用numpy
将pymupdf
读取的页面图像转换为cnocr
能够接受的np.ndarray
格式的图像数据,再由cnocr
进行文字识别。numpy
、pymupdf
和cnocr
库的安装都可以用pip install
指令简单完成,不多赘述。
python
import numpy as np
from cnocr import CnOcr
from pymupdf import pymupdf
def pdf2txt(input_file, output_file, start_page=0, page_count=-1):
"""
将扫描的pdf文件中指定的页面范围内的内容转换成文本文件
:param input_file: 要识别的pdf文件的相对或绝对路径,包含文件名的字符串
:param output_file: 保存识别结果的txt文件的相对或绝对路径
:param start_page: 识别起始页面,默认为第1页
:param page_count: 识别的页数,默认为所有页面
:return:
"""
pdf = pymupdf.open(input_file)
count = pdf.page_count
if start_page < 0:
start_page = 0
if page_count < 0 or page_count + start_page > count:
end_page = count
else:
end_page = page_count + start_page
# 如CnOcr的识别模型尚未下载,以下语句执行时CnOcr会自动下载模型并解压到用户目录下的AppData\\Roaming\\cnocr\\cnocr版本号下
# 也可以在初始化时指定rec_model_fp参数给出模型所在的相对路径或绝对路径指定识别模型,如以下示例(因以下路径是我的电脑上的默认路径,
# 因此下面两行代码与ocr = CnOcr()完全等价
ocr = CnOcr(rec_model_fp='C:\\Users\\asus\\AppData\\Roaming\\cnocr\\2.3\\densenet_lite_136-gru'
'\\cnocr-v2.3-densenet_lite_136-gru-epoch=004-ft-model.onnx')
print(start_page, end_page)
with open(output_file, 'w', encoding='utf-8') as f:
for i in range(start_page, end_page):
page = pdf[i]
pix = page.get_pixmap()
width = pix.width
height = pix.height
# pixmap转换为nympy.ndarray,供CnOcr识别
image = np.frombuffer(pix.samples, dtype=np.uint8).reshape(height, width, pix.n)
res = ocr.ocr(image)
string_list = []
for val in res:
# 注意这是2.2版本以后的cnocr读取识别结果的方式与2.1版本已经不同
# 如果cnocr识别结果总是一些textscoreposition字符串,那就是用了老版的方式
string_list.append(val['text'])
ocr_result_string = '\n'.join(string_list)
f.write(ocr_result_string) # 这行代码自带文件关闭功能,不需要再写 f.close()
print(f'page{i + 1} finished.')
pdf.close()
input_file = f'test.pdf'
output_file = 'test.txt'
pdf2txt(input_file, output_file, 500, 522)
需要注意的是,在读取cnocr的识别结果时,如果安装的cnocr版本低于2.2,那么
以上代码中的
python
for val in res:
string_list.append(val['text'])
要改成下面这样:
python
for i in range(len(res)):
for j in res[i]:
string_list.append(j)
但是2.2版本以后的cnocr
如果仍然用以上方式,那么取出的识别结果将是一串"textscoreposition
"。
下面是以上程序识别曹植集校注中一页的结果:
tex
(本冥指隐蔽偏鲜之处。此言卡太后即使在独处之时也很谨慎,在隐
游之处电依礼行。
5〔诚(juon))洁也。〔荐)进献。〔三牲)牛、羊、猪,指祭
品。此吉请净地进献祭品。(视)条配时主持条礼之人。
3〔宜享斯祜]应该享受知此之服。精:棋。宋本作""。〔煤
社〕即受桶。(肉特)锅奖。(勉)月"免。即超免
四〔会街尽礼)条祀折特时湖尽礼数。笃)厚,指调情加重。
[密)痊愈。(终)指生命到终点。
等〔遗州)南植自指。(在收)指在优伤久病之中。(部)指下太
后去世的内信。〔东藩)洛阳东面的藩国。曹植时时东阿王。东阿在洛
阳东。[郊甸)郊野。丁本:《艺文类聚》作"晗。"家本亦作"除"。
哈指田地里的小路、与筹义同。(中原)原野之中。
中(皇址]望号。[迁)肉去。[峡复) 经常来看我。
等〔岁字)空貌,即人去限空。(巡省阶除)在宫中的小道上巡视。
(仿佛碳轩在窗户间仿佛着见了下太行的身影容舰。银轩:窗户。
就【韩梨)指下太后的居室。(儿益)儿席。座席。〔效故)改变
原承的样子。
2〔酷指您伤全做。斯)如此。(墙)。(魏部)指邺。曹操
界于都,下太后的是权专运到部与曹操合养。(日包)指邺。〔隧)&
道。〔魄)《艺文类聚》、宋本俱作"将"。
3(叹息露兴)叹息之气粥如雾气兴起,形容送师人之多。〔幅
(r而))灵车。
容车饰驾,以合北展®
0丁本:"《文选》颜廷年《宋元泉后哀策文》李注引《上宜后请
&》.
-469.
原始扫描页面100%缩放图像如下:
可见准确率也还勉强可以接受。如果将图像做个对比度增强并适当放大再识别,还可以进一步提高准确率。下面是使用OpenCV将图片放大2倍后的识别结果,对比可以看出准确率有所提高:
tex
(本冥〕指隐蔽偏解之处。此言卡太后即使在独处之时也很谨慎,在隐
游之处也依礼间行。
S(砖(juon))洁也。〔荐〕进献。(三牲〕牛、羊、猪.指祭
品。此言洁净地进献祭品。(祝〕祭祀时主持祭礼之人。
3(宜享斯祜)应该享受知此之福。精:摄、宋本作"猪"。〔蒙
社〕即受福。〔凶咎)祸火。〔勉)月"免".即避免。
四〔云传尽礼)条祀祈传时湖尽礼数。笃)厚,指病情加重。
(疮)经。〔终)指生命到终点。
多〔逸弧)曹植自指。(在款)指在优伤久病之中。(讳)指下太
后去世的内信。〔东洛)洛阳东面的等国。、曹植时村东阿王。东阿在洛
阳东。(郊甸)郊野。丁本:《艺文类聚》作"峰。"宋本亦作"时"。
哈指田地里的小路。与年义同。(中原)原野之中。
9(皇址)皇号。[迁〕肉去。[峡复〕经常来看我。
0〔岁凯)空貌,即人去屋空。〔巡省阶涂)在宫中的小道上巡视。
(仿佛候轩)在窗户间仿佛看见了卡太后的身影容颜。领轩:窗户。
就〔韩蟹)指下太后的店室。〔儿流)儿席。座席。〔烫故)改变
原来的样子。
心〔酷)指悲伤至极。〔斯)如此。(秦)到。〔魏都)指邺。曹操
养于郎,下太后的是框要运到第与曹操合养。(旧色)指邺。(能)众
道。〔魄)《艺文类聚》、宋木供作"将"。
3(叹息露兴)叹息之气宛如雾气兴起,形容送葬人之多。〔幅
(r而))灵车。
容车饰驾,以合北辰®
0丁本:"《文选》颜廷年《宋元皇后哀策文》李注引《上宣后请
表."
.469.