基于tesseract实现文档OCR识别

导入环境

导入必要的库
numpy: 用于处理数值计算。
argparse: 用于处理命令行参数。
cv2: OpenCV库,用于图像处理。

import numpy as np
import argparse
import cv2

设置命令行参数

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="images/page.jpg", help="Path to the image to be scanned")
args = vars(ap.parse_args())

定义坐标排序函数

对四个坐标点进行排序,确定文档的四个角(左上,右上,右下,左下)。
使用欧氏距离来计算和排序点。

def order_points(pts):# 一共4个坐标点rect = np.zeros((4, 2), dtype = "float32")# 按顺序找到对应坐标0123分别是 左上,右上,右下,左下# 计算左上,右下s = pts.sum(axis = 1)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]# 计算右上和左下diff = np.diff(pts, axis = 1)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rect
  • 此函数用于排序提供的四个点,确保点的顺序为左上、右上、右下和左下,这对后续的透视变换非常重要。

定义透视变换函数

使用cv2.getPerspectiveTransform和cv2.warpPerspective来计算变换矩阵并应用

def four_point_transform(image, pts):# 获取输入坐标点rect = order_points(pts)(tl, tr, br, bl) = rect# 计算输入的w和h值widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA), int(widthB))heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))maxHeight = max(int(heightA), int(heightB))# 变换后对应坐标位置dst = np.array([[0, 0],[maxWidth - 1, 0],[maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype = "float32")# 计算变换矩阵M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))# 返回变换后结果return warped
  • 接收原始图像和四个顶点坐标,然后应用透视变换,从而获取图像的正视图。

定义图像缩放函数

def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))resized = cv2.resize(image, dim, interpolation=inter)return resized
  • 用于调整图像尺寸,使图像处理过程中的操作更加高效。

主逻辑部分

  • 图像预处理:

    • 读取图像,调整大小,并转换为灰度图。
    • 应用高斯模糊和Canny边缘检测准备图像进行轮廓检测。
  • 轮廓检测:

    • 使用cv2.findContours寻找边缘,这是寻找文档轮廓的关键步骤。
    • 选择轮廓面积最大的前五个轮廓。
  • 透视变换:

    • 对检测到的轮廓(如果准确地检测到四点)应用透视变换。
    • 将图像从斜视角转换为正视图,便于文档的进一步处理和分析。
  • 结果保存和显示:

    • 应用二值化处理,并保存变换后的扫描图像。
    • 显示原始和扫描后的图像。

关键知识点

  • 高斯模糊 (GaussianBlur): 用于去除图像噪声并平滑图像。
  • Canny边缘检测 (Canny): 用于在图像中检测边缘,是轮廓检测的关键步骤。
  • 轮廓检测 (findContours): 在二值图像中寻找轮廓,用于图形、图像和物体的形状分析。
  • 透视变换 (getPerspectiveTransform, warpPerspective): 在进行文档扫描或修正图像视角时非常有用。
if __name__ == '__main__':# 读取输入image = cv2.imread(args["image"])#坐标也会相同变化ratio = image.shape[0] / 500.0orig = image.copy()image = resize(orig, height = 500)# 预处理gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (5, 5), 0)edged = cv2.Canny(gray, 75, 200)# 展示预处理结果print("STEP 1: 边缘检测")cv2.imshow("Image", image)cv2.imshow("Edged", edged)cv2.waitKey(0)cv2.destroyAllWindows()# 轮廓检测 opencv3# cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1][0]# cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]# 使用OpenCV 4.x的方式来调用findContourscontours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# 确保轮廓是适当的数据类型cnts = [np.array(cnt, dtype='float32') for cnt in contours]# 排序并选择最大的5个轮廓cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]# 遍历轮廓screenCnt  =  Nonefor c in cnts:# 计算轮廓近似peri = cv2.arcLength(c, True)# C表示输入的点集# epsilon表示从原始轮廓到近似轮廓的最大距离,它是一个准确度参数# True表示封闭的approx = cv2.approxPolyDP(c, 0.02 * peri, True)# 4个点的时候就拿出来if len(approx) == 4:screenCnt = approx.astype(int)breakif screenCnt is not None:# 展示结果print("STEP 2: 获取轮廓")# print(screenCnt)cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)cv2.imshow("Outline", image)cv2.waitKey(0)cv2.destroyAllWindows()# 透视变换warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)# 二值处理warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)ref = cv2.threshold(warped, 100, 255, cv2.THRESH_BINARY)[1]cv2.imwrite('scan.jpg', ref)# 展示结果print("STEP 3: 变换")cv2.imshow("Original", resize(orig, height = 650))cv2.imshow("Scanned", resize(ref, height = 650))cv2.waitKey(0)
  • Canny算子检测结果图:
    在这里插入图片描述

  • 定 四个顶点
    在这里插入图片描述

  • 仿射变换结果

  • 在这里插入图片描述

OCR识别

Tesseract 是一个开源的光学字符识别(OCR)引擎,最初由惠普实验室于1985年开发,并在2006年由Google赞助成为一个开源项目。Tesseract 能够识别多种格式的图像文件并将它们转换成文本。它支持多种语言的识别,并且可以通过训练来识别新的语言或优化现有语言的识别效果。

主要特点:

  1. 多语言支持:Tesseract 支持100多种语言的识别。
  2. 高度可定制:用户可以训练Tesseract来识别新的字体或优化特定语言的识别。
  3. 多种输出格式:Tesseract 可以输出普通文本、hOCR(带有布局信息的HTML)、PDF等格式。
  4. 集成易用:可以通过命令行使用,也可通过其API集成到其他应用程序中,比如通过pytesseract在Python中使用。

使用方法:

在命令行中,Tesseract 可以简单地通过指定输入图像和输出文件名来使用,如:

tesseract image.png output -l eng

这里-l eng指定了使用英语语言包。

pytesseract:

在Python中,pytesseract是一个将Tesseract引擎功能封装的库,允许Python直接调用Tesseract进行图像到文本的转换。使用前需要确保Tesseract已安装在系统上,并且正确配置了环境变量或在pytesseracttesseract_cmd属性中指定了Tesseract的路径。

应用场景:

  • 文档数字化:将纸质文档扫描后识别为数字文本。
  • 自动化表单处理:从填写的表单中提取信息。
  • 车牌识别:用于交通监控或自动收费系统。
  • 辅助技术:帮助视觉障碍人士阅读印刷材料。

Tesseract是一个功能强大的工具,因其开源和高效被广泛用于商业和研究领域。

1. 导入必要的库

  • PIL (Python Imaging Library): 用于图像的打开和处理。
  • pytesseract: 是Google的Tesseract-OCR引擎的Python封装,用于识别图像中的文字。
  • cv2 (OpenCV): 用于图像处理的库,这里用于读取和预处理图像。
from PIL import Image
import pytesseract
import cv2
import os

2. 图像预处理

  • 读取图像: 使用cv2.imread读取图像文件。
  • 转换为灰度图: 使用cv2.cvtColor将读取的彩色图像转换为灰度图,因为OCR通常在灰度图上进行。
  • 应用阈值或模糊处理:
    • 如果预处理方式为"thresh"(阈值),使用cv2.threshold应用阈值化处理,这可以帮助去除背景噪声并突出文本。
    • 如果预处理方式为"blur"(模糊),使用cv2.medianBlur应用中值模糊,以减少图像噪声。
preprocess = 'blur' #threshimage = cv2.imread('scan.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)if preprocess == "thresh":gray = cv2.threshold(gray, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]if preprocess == "blur":gray = cv2.medianBlur(gray, 3)

3. 保存处理后的图像

  • 保存文件: 使用cv2.imwrite将处理后的灰度图像临时保存为一个新文件,文件名由当前进程ID命名。

4. 文本识别

  • 使用pytesseract.image_to_string函数读取步骤3中保存的灰度图像文件,识别其中的文本。
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)text = pytesseract.image_to_string(Image.open(filename))
print(text)
os.remove(filename)cv2.imshow("Image", image)
cv2.imshow("Output", gray)
cv2.waitKey(0)                                   

5. 输出和清理

  • 打印识别的文本
  • 删除临时文件: 使用os.remove删除保存的临时图像文件。
  • 显示图像: 使用cv2.imshow展示原始图像和处理后的图像。
  • 等待按键: 使用cv2.waitKey(0)暂停程序,等待用户按键继续。

知识点总结

  • OpenCV的灰度转换和图像滤波:灰度转换有助于简化数据,滤波有助于减少噪声,这两者都是提高OCR准确性的关键步骤。
  • 阈值处理与模糊处理的选择:不同的图像预处理方法适用于不同类型的图像和需求,阈值处理适用于高对比度图像,而模糊处理适用于噪声较多的图像。
  • pytesseract的使用:封装了Tesseract-OCR引擎,能够从图像中识别和提取文字。

通过仿射变换矫正后图像为:

在这里插入图片描述

识别结果为:
在这里插入图片描述

源码上传地址

链接 ----------------上传地址 文档OCR识别(tesseract)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/416240.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频集中存储智能边缘计算网关软硬一体机智能边缘计算网关应用场景

在信息化飞速发展的今天,数据处理的速度和效率直接影响到各行各业的运作和发展。传统的云计算模式虽然强大,但在面对实时性和带宽要求越来越高的应用场景时,往往显得力不从心。此时,智能边缘计算网关的出现,为我们带来…

长效静态代理IP推荐:天启代理IP的优势与应用

在如今这个互联网的时代,代理IP已成为许多网络活动的必备工具。相比动态代理IP,长效静态代理IP以其稳定性和长时间有效性,成为了许多用户的首选。今天,我们将深入探讨长效静态代理IP的优势,并重点推荐天启代理IP。 什…

Docker compose 安装 ELK

1. 简介 方案概述 我们使用 Filebeat 作为日志收集器,接入到 Redis 队列,然后消费队列中的日志数据流转到 Logstash 中进行解析处理,最后输出到 Elasticsearch 中,再由 Kibana 展示到页面上。我们采用 Elasticsearch 3 节点集群…

web前端-网页

一、网页 1.网页 网站是指在因特网上根据一定的规则,使用 HTML等制作的用于展示特定内容相关的网页集合。 网页是网站中的一“页”,通常是 HTML格式的文件,它要通过浏览器来阅读。 网页是构成网站的基本元素,它通常由图片、链接、文字、声…

婚宴时扫码查桌号

如何通过关键词查询信息? 在婚宴这一喜庆的时刻,确保每位宾客都能迅速找到自己的座位是至关重要的。为了使这一过程更加流畅和高效,我们特别引入了扫码查桌号服务。以下是详细的操作指南,帮助您快速掌握如何使用此服务&#xff0c…

缓存:浅谈双写导致的数据一致性问题

从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力更新即可。也就是说如果数据库写成功,缓…

C++11新增特性:列表初始化(std::initializer_list) decltype、auto、nullptr、范围for

C11新增特性:列表初始化(std::initializer_list)& decltype、auto、nullptr、范围for 一、C11新增统一初始化方式1.1 新增方式1.2 初始化容器底层原理(std::initializer_list) 二、新增声明2.1 decltype2.3 auto &…

网络安全服务基础Windows--第10节-FTP主动与被动模式

概述 将某台计算机中的⽂件通过⽹络传送到可能相距很远的另⼀台计算机中,是⼀项基本的⽹络应⽤,即⽂件传送。 ⽂件传送协议FTP (File Transfer Protocol)是因特⽹上使⽤得最⼴泛的⽂件传送协议。 FTP是⼀个⽼早的⽹络协议&…

VMware 虚拟化平台部分问题和优化措施汇总

本文整理记录了VMware 虚拟化平台部分问题和优化措施。 1、vCLS虚拟机无法启动: 修改办法,参照本人下文: vCLS报错处理(缺少功能“MWAIT”,没有与虚拟机兼容的主机) 2、优化存储卷的路径选择策略 ESXi…

可以进行非机动车违停、人员聚集、临街摆摊、垃圾满溢、烟雾火情等城市治理场景的智能识别的智慧城管开源了

智慧城管视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。 基于深度学习技…

Redis 篇-深入了解查询缓存与缓存所带来的问题(读写不一致、缓存穿透、缓存雪崩、缓存击穿)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 本章目录 1.0 什么是缓存 2.0 项目中具体如何添加缓存 3.0 添加缓存后所带来的问题 3.1 读写不一致问题 3.1.1 缓存更新策略 3.1.2 具体实现缓存与数据库的双写一致 3.2 缓存穿…

vue2———组件

一个简单的组件 组件进行注册并使用 结果: 在进行对组件的学习时遇见一些问题: 1、组件的命名 解决方法: 组件的命名 Vue.js 组件的命名遵循一些最佳实践,这些实践有助于保持代码的清晰和一致性。 多单词命名:Vue 官…

Robotics: computational motion planning 部分笔记—— week 2 Configuration Space 构型空间

基本概念 构型(Configuration):构型是机器人上所有点的完整描述。它提供了机器人在特定时刻状态的简洁表示。 构型空间(Configuration Space):也称为C-Space,指的是机器人可以到达的所有可能构型的集合。它考虑了空间限制范围和机器人的物理…

期权交易方式和基本策略有哪几种?期权交易要注意什么?

今天带你了解期权交易方式和基本策略有哪几种?期权交易要注意什么?期权,作为一种金融衍生品,它赋予了持有人在未来某个时间内购买或出售特定资产的权利,近年来在全球范围内得到了广泛的关注和应用。 期权交易方式 期…

Latex安装--新手教程、遇到的问题

第一个LaTeX文件的编写 1.tex文件:自己创建后缀为.tex的文件 2.在VScode中打开1.tex文件(图1),然后双击打开1.tex文件(图2),VScode左侧工具栏出现TEX插件,点击TEX即可 3.写第一个1.t…

SpringBoot-读取配置文件方式

目录 前言 一. 使用 ConfigurationProperties 注解读取 二. 使用 Value 注解读取配置文件 三. 使用 Environment 类获取配置属性 前言 Spring Boot提供了多种灵活的方式来读取配置文件,以适应不同的开发和部署需求,SpringBoot启动的时候,…

[Linux] 项目自动化构建工具-make/Makefile

标题:[Linux] 项目自动化构建工具-make/Makefile 水墨不写bug 目录 一、什么是make/makefile 二、make/makefile语法 补充(多文件标识): 三、make/makefile原理 四、make/makefile根据时间对文件选择操作 正文开始&#xff…

在安卓和Windows下使用Vizario H264 RTSP

Unity2021.3.35f1,运行模式为ENGINE_SERVER 1.环境设置 Windows设置 安卓设置 2.代码修改 ConnectionProperties中的server必须与真实IP一样,所以需要新增一个获取IP的函数 public string GetLocalIPAddress(){IPHostEntry host;string localIP &quo…

codesys进行控制虚拟轴运动时出现的一些奇怪bug的解释

codesys进行控制虚拟轴运动时出现的一些奇怪bug的解释 问题描述第一个奇怪的bug:新建的工程没有SoftMotion General Axis Pool选项第二个奇怪的bug:在新建工程SoftMotion General Axis Pool选项时,无法手动添加第三个奇怪的bug:虚…

Postgresql碎片整理

创建pgstattuple 扩展 CREATE EXTENSION pgstattuple 获取表的元组(行)信息,包括空闲空间的比例和行的平均宽度 SELECT * FROM pgstattuple(表名); 查看表和索引大小 SELECT pg_relation_size(表名), pg_relation_size(索引名称); 清理碎片方…