基于tesseract实现文档OCR识别

news2024/12/24 8:13:29

导入环境

导入必要的库
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 image
	if 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.0
	orig = 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的方式来调用findContours
	contours, 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  =  None
	for 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)
			break

	if 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' #thresh

image = 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.coloradmin.cn/o/2103404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国各省份-环境规制相关数据(2000-2022年)

环境规制,也称为环保政策和污染治理,是一系列由政府制定的旨在解决环境问题、保护生态环境和促进可持续发展的政策措施。这些措施包括法律法规、行政命令、经济激励和市场机制等,目的是约束和指导企业和个人行为,减少对环境的负面…

【吊打面试官系列-Redis面试题】Redis 的同步机制了解么?

大家好,我是锋哥。今天分享关于 【Redis 的同步机制了解么?】面试题,希望对大家有帮助; Redis 的同步机制了解么? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 可以使用主从同步,从从同…

Linux运维--iptables防火墙命令以及端口号等详解(全)

Linux之iptable防火墙命令以及端口号等详解(全) 在Linux系统中,你可以使用firewalld和iptables来管理和设置防火墙规则。Firewalld是一个动态管理防火墙的工具,而iptables是一个更底层的工具,可以直接配置Linux内核的…

经典卷积神经网络 (CNN) 架构模型详解:LeNet、AlexNNet、GoogleNet、ResNet、DenseNet

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 👍感谢小伙伴们点赞、关注! 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

文字转视频软件哪个好用?揭秘创意新工具

最近,我在筹备一个小型的个人项目,需要制作一系列的教学视频,但我对视频编辑一窍不通。就在我快要放弃的时候,我发现了一些神奇的工具,它们能自动把文字变成视频! 想知道自动生成视频的软件有哪些吗&#…

Docker 安装FileBeat、Elasticsearch及Kibana详细步骤

一、ELK简介 二、docker安装Elasticsearch 2.1 创建Docker网络 2.2 拉取镜像 2.3 创建挂载目录 2.4 添加配置文件 2.5 创建es容器 2.6 测试Elasticsearch是否安装成功 三、docker安装Logstash 3.1 拉取镜像 3.2 创建挂载目录 3.3 添加配置文件 3.4 创建Logstash容…

如何更新我的SSL证书到期日期?

续订SSL证书需要获取新证书来替换即将过期的证书。该过程可能略有不同,具体取决于Gworg获取证书的方法。以下是有关如何续订SSL证书的一般指南: 检查有效期: 在开始续订流程之前,请检查SSL证书的当前到期日期。您通常可以在SSL证…

【PyTorch】深入解析 `with torch.no_grad():` 的高效用法

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言一、with torch.no_grad(): 的作用二、with torch.no_grad(): 的原理三、with torch.no_grad(): 的高效用法3.1 模…

24 初识C++

目录 一、C概念 (一)C是什么 (二)C的历史 (三)C参考文档 二、第一个C程序 三、C的域 四、命名空间 namespace (一)namespace 的作用 (二)namespace 的…

如何从 SIM 卡恢复短信?这篇专业教程文章会帮到你

您是 Android 手机的忠实用户吗?您是否定期通过打电话、发送短信或在 WeChat 上聊天来与朋友和家人保持联系?如果你这样做,我相信你的手机上一定有很多短信,这些短信对于保存你与他人聊天的内容非常重要。您是否有这样的经验&…

碧桂园服务上海项目获评“2024年度上海市物业管理优秀示范项目”

近日,上海市物业管理行业协会发布《关于2024年度上海市物业管理优秀示范项目评定结果的公示》官方红头文件。文件对上海市393个物业管理优秀示范项目进行公示。 上海联源物业发展有限公司露香园项目、静鼎安邦府邸项目、佘山东郡项目和上海金晨物业经营管理有限公司…

mac 安装brew并配置国内源

​ 前置条件 - Xcode 命令行工具 一行代码安装Homebrew 添加到路径(PATH) - zsh shell为例 背景介绍 最近重装了我的MAC mini (m1 芯片), 很多软件都需要重新安装,因为后续还需要安装一些软件,所以想着安装个包管理软件 什么…

苹果手机通话记录怎么恢复?已总结了4个方法,快速恢复

苹果手机的通话记录是我们联系好友与家人的重要方式之一。如果我们忘记储存重要好友或家人的联系方式,但是曾经有过通话,那我们就可以在苹果手机的通话记录中找到重要的联系人。但是,如果这些通话记录不小心被删除了,那苹果手机通…

ArkUI-状态管理最佳实践

ArkUI-状态管理最佳实践 概述合理选择装饰器使用监听和订阅精准控制组件刷新Watch装饰器监听数据源使用自定义事件发布订阅 概述 在声明式UI编程范式中,UI是应用程序状态的函数,应用程序状态的修改会更新响应的UI界面。ArkUI采用了MVVM模式。 ArkUI提…

2024年第十届数维杯国际大学生数学建模挑战赛

竞赛介绍 为了培养学生的创新意识及运用数学方法和计算机技术解决实际问题的能力,内蒙古创新教育学会、内蒙古基础教育研究院决定主办2024年第十届数维杯国际大学生数学建模挑战赛(国际赛)。 数维杯大学生数学建模挑战赛每年分为两场&#…

uniapp开发鸿蒙,是前端新出路

uniapp开发鸿蒙,是前端新出路吗? 相信不少前端从业者一听uniapp支持开发鸿蒙Next后非常振奋。小编作为7年前端也是非常激动,第一时间体验了下。在这里也给大家分享一下我的看法 uniapp开发鸿蒙优势 1.对于前端开发者而言,几乎无需…

基于51单片机的跑马串口调试波形发生器proteus仿真

地址: https://pan.baidu.com/s/1WTjU_hRJ-fLMTT5g1q-NlA 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectro…

嵌入式全栈开发学习笔记---C++(多态)

目录 多态polymorphic 多态成立的三个条件 1、要有继承 2、要有虚函数重写 3、用父类指针(父类引用)指向子类对象 重载与重写区别 动态联编和静态联编 多态原理 构造函数中调用虚函数能否实现多态? 用父类指针指向子类数组 虚析构函数 动态类型识别 第…

【免越狱】iOS任意版本号APP下载

下载地址 https://pan.quark.cn/s/570e928ee2c4 软件介绍 下载iOS旧版应用,简化繁琐的抓包流程。一键生成去更新IPA(手机安装后,去除App Store的更新检测)。 软件界面 使用方法 一、直接搜索方式 搜索APP,双击选…

Vue3 + Ts + Vite项目 websoket封装使用

文章目录 一、安装二、封装三、请求地址配置3.1 将接口地址放到 public3.2 引入 ipconfig.js 文件3.3 全局类型声明 四、页面使用4.1 引用4.2 注册 五、说明 一、安装 npm npm install websocket --save-devpnpm pnpm install websocket --save-dev二、封装 在 /src/utils …