腾讯云OCR服务二次开发

前言

因为腾讯云账户中还剩一点点钱,刚刚好够买腾讯云里文字识别服务,想着自己平时看PDF比较多,可以用这个服务来便捷的进行图像文字转换。我购买的是通用印刷体识别,即可以对图片进行识别,也可以对PDF文件进行识别。需要注意的的是,图片识别需要将图片转为Base64,PDF识别时每次只能识别一张。

本文记录了对腾讯云OCR服务二次开发的代码和开发过程中遇到的问题。

安装SDK

我使用的是Python 3.6,要使用腾讯云的OCR服务,要先在本地环境中安装腾讯云的SDK。安装方式见:Python - SDK 中心 - 腾讯云 (tencent.com)

调用API

学习API文档

安装好SDK后,调用相应的接口就ok了,可以参考:文字识别 API 概览 - 服务端 API 文档 - 文档中心 - 腾讯云 (tencent.com)

因为主要需求是对PDF以及其截图进行识别,我购买的是GeneralBasicOCR-通用印刷体识别,腾讯可以在API Explorer - 云 API - 控制台 (tencent.com)中进行调试,比较方便。

通用印刷体识别API

通用印刷体识别主要支持以下参数:

参数名称 必选 类型 描述
Action String 公共参数,本接口取值:GeneralBasicOCR。
Version String 公共参数,本接口取值:2018-11-19。
Region String 公共参数,详见产品支持的 地域列表,本接口仅支持其中的: ap-beijing, ap-guangzhou, ap-hongkong, ap-seoul, ap-shanghai, ap-singapore, na-toronto
ImageBase64 String 图片/PDF的 Base64 值。 要求图片/PDF经Base64编码后不超过 7M,分辨率建议600*800以上,支持PNG、JPG、JPEG、BMP、PDF格式。 图片的 ImageUrl、ImageBase64 必须提供一个,如果都提供,只使用 ImageUrl。
ImageUrl String 图片/PDF的 Url 地址。 要求图片/PDF经Base64编码后不超过 7M,分辨率建议600*800以上,支持PNG、JPG、JPEG、BMP、PDF格式。 图片存储于腾讯云的 Url 可保障更高的下载速度和稳定性,建议图片存储于腾讯云。非腾讯云存储的 Url 速度和稳定性可能受一定影响。
Scene String 保留字段。
LanguageType String 识别语言类型。 支持自动识别语言类型,同时支持自选语言种类,默认中英文混合(zh),各种语言均支持与英文混合的文字识别。 可选值: zh:中英混合 zh_rare:支持英文、数字、中文生僻字、繁体字,特殊符号等 auto:自动 mix:混合语种 jap:日语 kor:韩语 spa:西班牙语 fre:法语 ger:德语 por:葡萄牙语 vie:越语 may:马来语 rus:俄语 ita:意大利语 hol:荷兰语 swe:瑞典语 fin:芬兰语 dan:丹麦语 nor:挪威语 hun:匈牙利语 tha:泰语 hi:印地语 ara:阿拉伯语
IsPdf Boolean 是否开启PDF识别,默认值为false,开启后可同时支持图片和PDF的识别。
PdfPageNumber Integer 需要识别的PDF页面的对应页码,仅支持PDF单页识别,当上传文件为PDF且IsPdf参数值为true时有效,默认值为1。
IsWords Boolean 是否返回单字信息,默认关

考虑到我的实际使用需求,主要会使用到ImageBase64ImageUrlIsPdfPdfPageNumber这几个参数。

代码

我主要使用了argparsebase64json这几个python内置模块。

我希望能够在CLI中便捷的使用这个工具,但是由于有很多不同的情况,所以使用argparse模块,覆盖不同的情况。同时,又因为对图片识别时,参数是base64,所以需要使用base64模块将图片转化为base64格式。

main.py

# -*- coding: UTF-8 -*-
# 参考:https://cloud.tencent.com/document/product/866/33515
# Author:Zhangyifei 2022年4月10日 import pyperclip from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException from ocrtool import MyOcrTool, ReqObj
from parse_args import parse_args if __name__ == '__main__': try: # 实例化Ocr工具
my_ocr_tool = MyOcrTool()
client = my_ocr_tool.client
req = ReqObj() # 获取命令行参数
args = parse_args() if args.local:
if args.isPdf:
req.req_local_img(args.local, args.page)
else:
req.req_local_img(args.local)
elif args.url:
if args.isPdf:
req.req_url_img(args.url, args.page)
else:
req.req_url_img(args.url) # 获取输出
resp = client.GeneralBasicOCR(req) ans = ''
if args.newline:
for i in resp.TextDetections:
ans += (i.DetectedText + '\n')
else:
for i in resp.TextDetections:
ans += (i.DetectedText) print(ans) if args.clip:
pyperclip.copy(ans) except TencentCloudSDKException as err:
print(err)

parse_args.py

import argparse
import sys def parse_args():
# 设置命令行参数
parser = argparse.ArgumentParser(description='OCR解析方式')
parser.add_argument('-u', '--url', type=str, required=False, help='图片的url')
parser.add_argument('-l', '--local', type=str, required=False, help='本地图片的地址')
parser.add_argument('-p', '--isPdf', required=False, action='store_true', help='是否是Pdf')
parser.add_argument('-n', '--page', type=int, required=False, help='识别哪一页PDF')
parser.add_argument('-s', '--newline', required=False, action='store_true', help='Ocr识别结果是否换行')
parser.add_argument('-c', '--clip', required=False, action='store_true', help='输出结果是否粘贴到剪切板中') # 当未输入命令行参数时,打印帮助
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1) # 获取命令行参数
args = parser.parse_args() # page参数和isPdf参数存在依赖
if args.isPdf and not args.page:
parser.print_help()
parser.error('The --isPdf argument requires the --page argument.') # url参数和local参数只能有一个 if args.url and args.local:
parser.error('There can only be one argument --url and argument --local') return args

ocrtool.py

# -*- coding: UTF-8 -*-
# 参考:https://cloud.tencent.com/document/product/866/33515
# Author:Zhangyifei 2022年4月10日 import base64
import json from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.ocr.v20181119 import ocr_client, models def image_to_base64(file_path):
"""
将pdf转为Base64流
:param pdf_path: PDF文件路径
:return:
"""
with open(file_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
return str(encoded_string, 'UTF-8') class MyOcrTool(object):
def __init__(self):
# 参考https://cloud.tencent.com/document/product/866/33515
self.region = "ap-guangzhou"
self.cred = credential.Credential("xxx", "xxx")
self.httpProfile = HttpProfile()
self.httpProfile.endpoint = "ocr.tencentcloudapi.com"
self.clientProfile = ClientProfile()
self.clientProfile.httpProfile = self.httpProfile
self.client = ocr_client.OcrClient(self.cred, self.region, self.clientProfile)
self.params = {} class ReqObj(models.GeneralBasicOCRRequest): def __init__(self):
models.GeneralBasicOCRRequest.__init__(self) def update_req_params(self, params):
# 更新req中的params
self.from_json_string(json.dumps(params)) def req_local_img(self, file_path, page=None):
# 请求本地的image文件
imagebase64 = image_to_base64(file_path) # 由于page和isPdf存在依赖,当page存在时,说明是对pdf进行处理
if not page:
params = {
"ImageBase64": imagebase64,
}
self.update_req_params(params)
else:
params = {
"ImageBase64": imagebase64,
"IsPdf": True,
"PdfPageNumber": page
}
self.update_req_params(params) def req_url_img(self, url_path, page=None):
# 请求url中的image文件 # 由于page和isPdf存在依赖,当page存在时,说明是对pdf进行处理
if not page:
params = {
"ImageUrl": url_path
}
self.update_req_params(params)
else:
params = {
"ImageUrl": url_path,
"IsPdf": True,
"PdfPageNumber": page
}
self.update_req_params(params)

运行结果

本地图片

使用-l参数(或者--local)表示对本地图片进行处理,使用-s(或者--newline)表示对图片中每行识别出来的内容进行换行。不使用-s时默认表示不换行。使用-c(或者--clip)表示将输出结果复制到粘贴板上,此时就可以方便的将输出的内容直接进行文本粘贴。

本地PDF

使用-p或者(--pdf)表示该文件是pdf文件,此时需要记得使用-n或者(--page)表示对哪一页进行OCR识别。否则的化会有报错提醒。

PS:如果需要对整个pdf进行识别和输出,可以重新进行函数封装,本文没有相关需求,暂不涉及。

网络图片

以下图为例:

它的url是:https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fww2.sinaimg.cn%2Fmw690%2F001SRYirly1h0czgvocbqj60uj0u043f02.jpg&refer=http%3A%2F%2Fwww.sina.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652184476&t=f35c29a812ee6a9a8e8d8fd582e0b60f

我们复制图片url,使用-u(或者--url)表示对url进行处理,使用-s(或者--newline)表示对图片中每行识别出来的内容进行换行。

问题整理

问题1:argparse模块参数之间如何生成依赖?

使用if语句进行判断,不符合依赖条件则抛出错误。

    # page参数和isPdf参数存在依赖
if args.isPdf and not args.page:
parser.print_help()
parser.error('The --isPdf argument requires the --page argument.')

问题2:argparse模块parser的参数type是bool时,CLI中传入参数即使是False,也会认为是True

这是因为命令行传入的参数默认会认为是字符串格式,因此传参是False仍会认为是True。这个问题在argparse bool python - CSDN中有说明解决办法。我的解决办法是涉及到type是bool格式的,使用action参数进行判断。

parser.add_argument('-c', '--clip', required=False, action='store_true', help='输出结果是否粘贴到剪切板中')

问题3:bytes格式转化为str格式的方法:

str(encoded_string, 'UTF-8')

后续想法

  • 封装函数对整个pdf进行处理并输出成文档(或EXCEL)

  • 部署web服务器,在网页中进行操作OCR识别操作。

腾讯云OCR服务二次开发的更多相关文章

  1. 云+社区分享——腾讯云OCR文字识别

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云+社区运营团队发布在腾讯云+社区 前言 2018年3月27日腾讯云云+社区联合腾讯云智能图像团队共同在客户群举办了腾讯云OCR文字识 ...

  2. 腾讯云OCR图片文字识别

    一. OCR OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别 ...

  3. JavaWeb-SpringBoot_(下)腾讯云点播服务之视频的显示-demo

    腾讯视频云点播 传送门 项目在腾讯云点播服务之视频的上传(上)[附源码]的基础上添加了两个html页面 此视频  播放传送门 (播放视频GIF会超过10M...) package com.Gary.v ...

  4. JavaWeb-SpringBoot_(上)腾讯云点播服务之视频的上传-demo

    使用Gradle编译项目 传送门 腾讯视频云点播 传送门 项目已托管到Github上 传送门 腾讯云点播服务之视频的显示(下) 传送门 个人腾讯云控制台中的视频管理 IndexController.j ...

  5. 腾讯云容器服务 TKE 拿下新加坡 MTCS 最高级别安全认证

    近日,腾讯云容器服务 TKE 荣获新加坡 MTCS 最高级安全认证,标志着腾讯云 TKE 在为用户提供可靠.易部署.灵活扩展等基础服务上,已经全面满足了新加坡监管机构以及多个行业客户对服务安全的要求. ...

  6. asp.net core使用serilog将日志推送到腾讯云日志服务

    为什么是serilog? Serilog是 .NET 中最著名的结构化日志类库. 基于日志事件log events,而不是日志消息log message. 你可以将日志事件格式化为控制台的可读文本或者 ...

  7. 腾讯云容器服务 TKE 推出新一代零损耗容器网络

    随着容器技术的发展成熟,越来越多的组件迁移到容器,在技术迁移过程中,数据库,游戏,AI 这些组件对容器网络性能(时延,吞吐,稳定性)提出了更高的要求.为了得到更优的时延和吞吐表现,各大云厂商都在致力于 ...

  8. 在腾讯云容器服务 TKE 中利用 HPA 实现业务的弹性伸缩

    在 TKE 上利用 HPA 实现业务的弹性伸缩 概述 Kubernetes Pod 水平自动扩缩(Horizontal Pod Autoscaler,以下简称 HPA)可以基于 CPU 利用率.内存利 ...

  9. 腾讯云快速完成python3.6开发环境搭建与django应用部署

    [本文出自天外归云的博客园] 部署python3.6.5 腾讯云服务器安装python3竟然要3个多小时!而且一度速度为0…… 于是网查据说是腾讯云服务器连python官网缓慢导致的,所以想找个国内的 ...

随机推荐

  1. Golang 语言特性

    1. 函数 与c 语言不同,go 语言中,函数的参数和返回值都由栈来存储. 传值:函数调用时会复制参数,被调用方和调用方持有两份不相关的两份数据 传引用:函数调用时会传递参数指针,被调用方和调用方持有 ...

  2. 【Vulnhub靶场】RED: 1

    环境准备 下载靶机导入到vmware 但是获取不到地址,可以根据我博客里的方法修改网卡来获取IP地址 信息收集 我们改好网卡之后,我们使用arp-scan命令来探测靶机的IP地址 靶机IP地址为:19 ...

  3. Java案例——字符串中的数据排序

    需求:有一个字符串"9 1 2 7 4 6 3 8 5 0",请编写程序实现从小到大数据排序 分析:最重要的部分是如何将字符串中的数据取出来 1.定义一个字符串为"9 1 ...

  4. 遇到REMOTE HOST IDENTIFICATION HAS CHANGED怎么办?

    今日遇到如下问题: 警告的大概意思就是,主机密钥发生变更,并提示安全风险(可能存在中间人攻击) 但是事实是,这是因为我重装系统之后遇到的问题.重装系统后,指纹当然会发生变化了...在Xshell实验中 ...

  5. ctf之计算器

    题目信息如下: 打开环境,发现是一道简单的计算题 只能输入一位数字 F12查看源码发现作者将最大长度设置为1,我们将最大长度修改了即可 输入答案即可得到flag

  6. json知识点总结(二)--JSONObject详解

    JSONObject只是一种数据结构,可以理解为JSON格式的数据结构(key-value 结构),可以使用put方法给json对象添加元素.JSONObject可以很方便的转换成字符串,也可以很方便 ...

  7. luoguP6623 [省选联考 2020 A 卷] 树(trie树)

    luoguP6623 [省选联考 2020 A 卷] 树(trie树) Luogu 题外话: ...想不出来啥好说的了. 我认识的人基本都切这道题了. 就我只会10分暴力. 我是傻逼. 题解时间 先不 ...

  8. MM32F0140的复位脚nRST复用成普通GPIO PA10功能

    目录: 1.MM32F0020简介 2.MM32F0020的复位脚nRST和PA10的说明 3.MM32F0020的选项字节说明 4.MM32F0020的FLASH_OBR选项字节寄存器说明 5.MM ...

  9. Oracle 11G DBMS包和类型参考

    参阅:https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_lob.htm#ARPLS66712

  10. 简述synchronized和java.util.concurrent.locks.Lock的异同 ?

    主要相同点:Lock能完成synchronized所实现的所有功能 主要不同点:Lock有比synchronized更精确的线程语义和更好的性能.synchronized会自动释放锁,而Lock一定要 ...