利用cnocr库完成中文扫描pdf文件的文字识别

很多pdf文件文字识别软件都会收费,免费的网页版可能会带来信息泄露,还有一些类似于腾讯AI和百度AI的接口都有调用次数限制,因此,利用识别正确率极高且免费的cnocr库来自己动手做个pdf文件文字识别程序就是一个很不错的选择。以下程序利用pymupdf打开pdf文件并将页面图像数据读出,然后用numpypymupdf读取的页面图像转换为cnocr能够接受的np.ndarray格式的图像数据,再由cnocr进行文字识别。numpypymupdfcnocr库的安装都可以用pip install指令简单完成,不多赘述。

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,那么
以上代码中的

for val in res:
    string_list.append(val['text'])

要改成下面这样:

for i in range(len(res)):
    for j in res[i]:
        string_list.append(j)

但是2.2版本以后的cnocr如果仍然用以上方式,那么取出的识别结果将是一串“textscoreposition”。
下面是以上程序识别曹植集校注中一页的结果:

(本冥指隐蔽偏鲜之处。此言卡太后即使在独处之时也很谨慎,在隐
游之处电依礼行。
5〔诚(juon))洁也。〔荐)进献。〔三牲)牛、羊、猪,指祭
品。此吉请净地进献祭品。(视)条配时主持条礼之人。
3〔宜享斯祜]应该享受知此之服。精:棋。宋本作“”。〔煤
社〕即受桶。(肉特)锅奖。(勉)月“免。即超免
四〔会街尽礼)条祀折特时湖尽礼数。笃)厚,指调情加重。
[密)痊愈。(终)指生命到终点。
等〔遗州)南植自指。(在收)指在优伤久病之中。(部)指下太
后去世的内信。〔东藩)洛阳东面的藩国。曹植时时东阿王。东阿在洛
阳东。[郊甸)郊野。丁本:《艺文类聚》作“晗。”家本亦作“除”。
哈指田地里的小路、与筹义同。(中原)原野之中。
中(皇址]望号。[迁)肉去。[峡复) 经常来看我。
等〔岁字)空貌,即人去限空。(巡省阶除)在宫中的小道上巡视。
(仿佛碳轩在窗户间仿佛着见了下太行的身影容舰。银轩:窗户。
就【韩梨)指下太后的居室。(儿益)儿席。座席。〔效故)改变
原承的样子。
2〔酷指您伤全做。斯)如此。(墙)。(魏部)指邺。曹操
界于都,下太后的是权专运到部与曹操合养。(日包)指邺。〔隧)&
道。〔魄)《艺文类聚》、宋本俱作“将”。
3(叹息露兴)叹息之气粥如雾气兴起,形容送师人之多。〔幅
(r而))灵车。
容车饰驾,以合北展®
0丁本:“《文选》颜廷年《宋元泉后哀策文》李注引《上宜后请
&》.
-469.

原始扫描页面100%缩放图像如下:
在这里插入图片描述
可见准确率也还勉强可以接受。如果将图像做个对比度增强并适当放大再识别,还可以进一步提高准确率。下面是使用OpenCV将图片放大2倍后的识别结果,对比可以看出准确率有所提高:

(本冥〕指隐蔽偏解之处。此言卡太后即使在独处之时也很谨慎,在隐
游之处也依礼间行。
S(砖(juon))洁也。〔荐〕进献。(三牲〕牛、羊、猪.指祭
品。此言洁净地进献祭品。(祝〕祭祀时主持祭礼之人。
3(宜享斯祜)应该享受知此之福。精:摄、宋本作“猪”。〔蒙
社〕即受福。〔凶咎)祸火。〔勉)月“免”.即避免。
四〔云传尽礼)条祀祈传时湖尽礼数。笃)厚,指病情加重。
(疮)经。〔终)指生命到终点。
多〔逸弧)曹植自指。(在款)指在优伤久病之中。(讳)指下太
后去世的内信。〔东洛)洛阳东面的等国。、曹植时村东阿王。东阿在洛
阳东。(郊甸)郊野。丁本:《艺文类聚》作“峰。”宋本亦作“时”。
哈指田地里的小路。与年义同。(中原)原野之中。
9(皇址)皇号。[迁〕肉去。[峡复〕经常来看我。
0〔岁凯)空貌,即人去屋空。〔巡省阶涂)在宫中的小道上巡视。
(仿佛候轩)在窗户间仿佛看见了卡太后的身影容颜。领轩:窗户。
就〔韩蟹)指下太后的店室。〔儿流)儿席。座席。〔烫故)改变
原来的样子。
心〔酷)指悲伤至极。〔斯)如此。(秦)到。〔魏都)指邺。曹操
养于郎,下太后的是框要运到第与曹操合养。(旧色)指邺。(能)众
道。〔魄)《艺文类聚》、宋木供作“将”。
3(叹息露兴)叹息之气宛如雾气兴起,形容送葬人之多。〔幅
(r而))灵车。
容车饰驾,以合北辰®
0丁本:“《文选》颜廷年《宋元皇后哀策文》李注引《上宣后请
表.”
.469.

真正要提高识别准确率,需要出钱买它的专业版预训练模型,但对于我这种坚决的白嫖党来说,即使售价1分钱,花出去我也觉得掉面子——还不如忍受腾讯AI百度AI限制次数限制文件大小去搞免费识别,话说我用百度AI接口识别的同一页内容结果如下(代码参阅https://blog.youkuaiyun.com/yivifu/article/details/116836686):

〔幽冥〕指隐蔽偏僻之处。此言卞太后即使在独处之时也很谨慎,在隐
僻之处也依礼而行。
②〔蠲(juān)〕洁也。〔荐〕进献。〔三牲〕牛、羊、猪,指祭
品。此言洁净地进献祭品。〔祝〕祭祀时主持祭礼之人。
〔宜享斯祜〕应该享受如此之福。祜:福。宋本作“祐”。〔蒙
祉〕即受福。〔凶咎〕祸灾。〔勉〕同“免”,即避免。
②〔尝祷尽礼〕祭祀祈祷时竭尽礼数。〔笃〕厚,指病情加重。
〔痊〕痊愈。〔终〕指生命到终点。
②〔遗孤〕曹植自指。〔在疚〕指在忧伤久病之中。〔讳〕指卞太
后去世的凶信。〔东藩〕洛阳东面的藩国。曹植时封东阿王,东阿在洛
阳东。〔郊甸〕郊野。丁本:“《艺文类聚》作‘畛’。”宋本亦作“畛”,
畛指田地里的小路。与郊义同。〔中原〕原野之中。
②9〔皇妣〕皇母。〔迁〕离去。〔顾复〕经常来看我。
③〔寥廓〕空貌,即人去屋空。〔巡省阶涂〕在宫中的小道上巡视。
[仿佛棂轩〕在窗户间仿佛看见了卞太后的身影容颜。棂轩:窗户。
③〔帏幄〕指卞太后的居室。〔几筵〕几席,座席。〔毁故〕改变
原来的样子。
〔酷〕指悲伤至极。〔斯〕如此。〔臻〕到。〔魏都〕指邺。曹操
葬于邺,卞太后的灵柩要运到邺与曹操合葬。〔旧邑〕指邺。〔隧〕墓
道。〔魄〕《艺文类聚》、宋本俱作“将”。
③〔叹息雾兴〕叹息之气宛如雾气兴起,形容送葬人之多。〔輀
(ér而)〕灵车。
容车饰驾,以合北辰①。
①丁本:“《文选》颜延年《宋元皇后哀策文》李注引《上宣后诔
表》。”
·469.

几乎没有错误!用腾讯的ocrdemo(https://ocrdemo.cloud.tencent.com/)识别,更是连格式都能基本保持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yivifu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值