如何基于Python代码实现高精度免费OCR工具


Posted in Python onJune 18, 2020

近期Github开源了一款基于Python开发、名为Textshot的截图工具,刚开源不到半个月已经500+Star。

这两天抽空看了一下Textshot的源码,的确是一个值得介绍的项目。

相对于大多数OCR工具复杂工程、差强人意的效果,Textshot具有明显的优势,

  • 项目简单
  • 技术点丰富

项目简单

Textshot整个项目只有1个Python文件、139行代码,没有复杂的第三方库应用,也不涉及过多后端算法的调用。

技术点丰富

Textshot这个项目虽然只有短短的139行代码,但是,却涉及Python中多个方面的知识应用,

  • UI开发
  • 截图工具开发
  • 后端引擎调用

通过这短短的项目,你不仅可以了解如何利用PyQt5实现一个用户界面,还可以学会如何使用pyscreenshot开发一款自己的截图工具。此外,还能够学会后端tesseract的调用。

换句话说,这短短的139行代码囊括了前端至后端的整个流程,而且涉及到截图和OCR两款工具的衔接。因此,Textshot虽然工程不大,却是一个非常完备、值得学习的项目。

本文就来剖析这个项目的源代码,教你一步一步实现自用且永久免费的截图&OCR工具!

tesseract

目前OCR工具数不胜数,但是大多数都是在相同的后端算法上面进行了不同的封装而已。而真正在OCR核心做的较好、值得大书特书的,那么一定非tesseract莫属

tesseract早在1985就已经开始由HP实验室开始研发,而在1995年更是被评为最为准确的3款OCR工具之一。此后,tesseract被开源,经过Google对其不断的进行优化和升级,它目前已经成为OCR方面一款标杆性的工具。很多开源或者付费的OCR工具,都是直接调用tesseract或者对其进行稍许优化。

而今天介绍的Textshot就是直接调用tesseract后端引擎进行OCR识别。因此,Textshot只是实现了一款截图工具,起到前后端的串联作用,在OCR识别算法方面并没有做任何工作。

tesseract安装

由于Textshot的OCR识别需要调用tesseract后端引擎,所以,首先需要安装tesseract。

Windows版安装可以直接访问下载链接[1].

Mac下可以使用Homebrew进行安装,

brew install tesseract 

Textshot

Textshot是一款截图识别文字的OCR工具,因此,它主要涉及2个环境,

截图

OCR识别

Textshot首先通过截图获取需要进行文字识别的图像,然后对这副图像进行OCR文字识别,输出识别结果。

前面已经介绍了,Textshot的OCR识别阶段调用的是tesseract,所以只需要1行代码即可完成。

因此,Textshot的工作主要是围绕前端窗口和截图工具的实现方面。

截图工具

截图工具是我们经常会用到的一种工具,如何实现一款截图工具?

很多人会把它想的非常复杂,其实,Python中有很多可以实现截图的库或者函数,例如,pyscreenshot或者pillow中的ImageGrab函数,它的调用方式如下,

shot = ImageGrab.grab(bbox=(x1, y1, x2, y2))

也就是说,我们只需要把鼠标框选的起点和终点坐标传给grab方法就可以实现截图功能。

那么,现在问题就转化为如何获取鼠标框选的起点和终点?

Textshot通过调用PyQt5并继承QWidget来实现鼠标框选过程中的一些方法来获取框选的起点和终点。

Textshot继承和重写QWidget方法主要包括如下几个,

  • keyPressEvent(self, event):键盘响应函数
  • paintEvent(self, event):UI绘制函数
  • mousePressEvent(self, event):鼠标点击事件
  • mouseMoveEvent(self, event):鼠标移动事件
  • mouseReleaseEvent(self, event):鼠标释放事件

可以看出,上面重写的方法以及囊括了截图过程中涉及的各个动作,

  • 点击鼠标
  • 拖动、绘制截图框
  • 释放鼠标
class Snipper(QtWidgets.QWidget):
  def __init__(self, parent=None, flags=Qt.WindowFlags()):
    super().__init__(parent=parent, flags=flags)
 
    self.setWindowTitle("TextShot")
    self.setWindowFlags(
      Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Dialog
    )
 
    self.is_macos = sys.platform.startswith("darwin")
    if self.is_macos:
      self.setWindowState(self.windowState() | Qt.WindowMaximized)
    else:
      self.setWindowState(self.windowState() | Qt.WindowFullScreen)
 
    self.setStyleSheet("background-color: black")
    self.setWindowOpacity(0.5)
 
    QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
 
    self.start, self.end = QtCore.QPoint(), QtCore.QPoint()
 
  def keyPressEvent(self, event):
    if event.key() == Qt.Key_Escape:
      QtWidgets.QApplication.quit()
 
    return super().keyPressEvent(event)
 
  def paintEvent(self, event):
    if self.start == self.end:
      return super().paintEvent(event)
 
    painter = QtGui.QPainter(self)
    painter.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255), 3))
    painter.setBrush(QtGui.QColor(255, 255, 255, 100))
 
    if self.is_macos:
      start, end = (self.mapFromGlobal(self.start), self.mapFromGlobal(self.end))
    else:
      start, end = self.start, self.end
 
    painter.drawRect(QtCore.QRect(start, end))
    return super().paintEvent(event)
 
  def mousePressEvent(self, event):
    self.start = self.end = QtGui.QCursor.pos()
    self.update()
    return super().mousePressEvent(event)
 
  def mouseMoveEvent(self, event):
    self.end = QtGui.QCursor.pos()
    self.update()
    return super().mousePressEvent(event)
 
  def mouseReleaseEvent(self, event):
    if self.start == self.end:
      return super().mouseReleaseEvent(event)
 
    x1, x2 = sorted((self.start.x(), self.end.x()))
    y1, y2 = sorted((self.start.y(), self.end.y()))

然后启动截图界面,

QtCore.QCoreApplication.setAttribute(Qt.AA_DisableHighDpiScaling)
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
snipper = Snipper(window)
snipper.show()

用户拖动、框选窗口,会获取窗口的起点和终点的坐标,这时候可以调用下面语句进行截图,获取需要OCR识别的文本图像,

shot = ImageGrab.grab(bbox=(x1, y1, x2, y2))

OCR文字识别

通过ImageGrab.grab截取到文本图像shot,下一步就是要把图像内容输入给后端的tesseract引擎,让它把图像转化为字符串

result = pytesseract.image_to_string(img, timeout=2, lang=(sys.argv[1] if len(sys.argv) > 1 else None))

到这里,就实现了一款准确度高、永久免费的OCR工具。

回顾一下Textshot的项目,我们会发现截图坐标范围内的图像、OCR识别只需要2行代码,大多数都是在围绕获取窗口起点和终点坐标在开发。换句话说,Textshot这个项目对OCR核心部分并没有做任何更改,只是在产品包装方面做了一些巧妙的工作。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中 ? : 三元表达式的使用介绍
Oct 09 Python
在GitHub Pages上使用Pelican搭建博客的教程
Apr 25 Python
Python中的集合类型知识讲解
Aug 19 Python
Python解惑之True和False详解
Apr 24 Python
Python中pygal绘制雷达图代码分享
Dec 07 Python
Django Admin实现三级联动的示例代码(省市区)
Jun 22 Python
Python决策树之基于信息增益的特征选择示例
Jun 25 Python
Python实现判断一个整数是否为回文数算法示例
Mar 02 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
Aug 02 Python
vscode 配置 python3开发环境的方法
Sep 19 Python
使用Keras实现Tensor的相乘和相加代码
Jun 18 Python
Python读写csv文件流程及异常解决
Oct 20 Python
python软件都是免费的吗
Jun 18 #Python
python中return如何写
Jun 18 #Python
python对一个数向上取整的实例方法
Jun 18 #Python
Python基于time模块表示时间常用方法
Jun 18 #Python
numpy 矩阵形状调整:拉伸、变成一位数组的实例
Jun 18 #Python
Numpy 多维数据数组的实现
Jun 18 #Python
python读取图像矩阵文件并转换为向量实例
Jun 18 #Python
You might like
PHP判断搜索引擎蜘蛛并自动记忆到文件的代码
2012/02/04 PHP
php 文本文件的读取效率
2012/02/10 PHP
ThinkPHP中url隐藏入口文件后接收alipay传值的方法
2014/12/09 PHP
php 自定义错误日志实例详解
2016/11/12 PHP
Yii2框架中使用PHPExcel导出Excel文件的示例
2017/08/09 PHP
Laravel框架实现多数据库连接操作详解
2019/07/12 PHP
ExtJS扩展 垂直tabLayout实现代码
2009/06/21 Javascript
jquery each()源代码
2011/02/14 Javascript
jquery的ajax请求全面了解
2013/03/20 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
js中方法重载如何实现?以及函数的参数问题
2013/08/01 Javascript
非常漂亮的JS+CSS图片幻灯切换特效
2013/11/20 Javascript
jQuery切换网页皮肤并保存到Cookie示例代码
2014/06/16 Javascript
jQuery+css实现的切换图片功能代码
2016/01/27 Javascript
JS Canvas定时器模拟动态加载动画
2016/09/17 Javascript
BootStrapValidator校验方式
2016/12/19 Javascript
jqGrid翻页时数据选中丢失问题的解决办法
2017/02/13 Javascript
Angular4 中内置指令的基本用法
2017/07/31 Javascript
详解处理Vue单页面应用SEO的另一种思路
2018/11/09 Javascript
js实现图片实时时钟
2020/01/15 Javascript
Python Web程序部署到Ubuntu服务器上的方法
2018/02/22 Python
python 多线程重启方法
2019/02/18 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
Python空间数据处理之GDAL读写遥感图像
2019/08/01 Python
Pytorch Tensor基本数学运算详解
2019/12/30 Python
win10安装tensorflow-gpu1.8.0详细完整步骤
2020/01/20 Python
python os模块在系统管理中的应用
2020/06/22 Python
基于HTML5陀螺仪实现ofo首页眼睛移动效果的示例
2017/07/31 HTML / CSS
求职自荐信格式
2013/12/04 职场文书
大学生自荐信
2013/12/11 职场文书
2014自主招生自荐信策略
2014/01/27 职场文书
2014年学校工会工作总结
2014/12/06 职场文书
同学聚会通知短信
2015/04/20 职场文书
旅游投诉信范文
2015/07/02 职场文书
2016年三八红旗手先进事迹材料
2016/02/26 职场文书
2016年主题党日活动总结
2016/04/05 职场文书