本章目标

  • OCR库概述
  • 处理格式规范的文字
  • 读取验证码与训练Tesseract
  • 获取验证码提交答案

一、OCR库概述

概述

  • 从 Google 的无人驾驶汽车到可以识别假钞的自动售卖机,机器视觉一直都是一个应用广泛且具有深远的影响和雄伟的愿景的领域。 在这一章里,重点介绍机器视觉的一个分支:文字识别,介绍如何用一些 Python 库来识别和使用在线图片中的文字。

场景

  • 1.当你不想让自己的文字被网络机器人采集时, 把文字做成图片放在网页上是常用的办法。在一些联系人通讯录里经常可以看到,一个邮箱地址被部分或全部转换成图片。人们可能觉察不出明显的差异, 但是机器人阅读这些图片会非常困难,这种方法可以防止多数垃圾邮件发送器轻易地获取你的邮箱地址。
  • 2.利用这种人类用户可以正常读取但是大多数机器人都没法读取的图片, 验证码(CAPTCHA)就出现了。验证码读取的难易程度也大不相同,有些验证码比其他的更加难读,后面我们会介绍这种问题。
  • 3.目前, 有很多文档都是简单地扫描后直接放到网上, 它们和互联网上的很多文档一样都没法儿直接使用, 尽管它们都“近在眼前”。如果无法将图像转为文字,要想使用这些文档的内容,就只能人工手敲了——没人愿意花时间干这事儿。

方案

将图像翻译成文字一般被称为光学文字识别( Optical Character Recognition, OCR)。可以实现 OCR 的底层库并不多,目前很多库都是使用共同的几个底层 OCR 库,或者是在上面进行定制。
在读取和处理图像、图像相关的机器学习以及创建图像等任务中, Python 一直都是非常出色的语言。虽然有很多库可以进行图像处理,但在这里我们只重点介绍两个库: Pillow 和Tesseract。

每个库都可以从它们的网站上下载并安装( http://pillow.readthedocs.org/installation.html 和https://pypi.python.org/pypi/pytesseract), 或者用第三方管理器( 像 pip) 通过“ pillow”和“ pytesseract”进行安装。

Pillow

  • 尽管 Pillow 算不上是图像处理功能最全的库,但是它拥有你需要使用的全部功能,除非你要用 Python 重写一个 Photoshop 或进行更加复杂的研究。它也是一个文档健全且十分易用的库。 http://pillow.readthedocs.org/
  • Pillow 是从 Python 2.x 版本的 Python 图像库( Python Imaging Library, PIL)分出来的,支持 Python 3.x 版本。和 PIL 一样, Pillow 也可以轻松地导入代码,并通过大量的过滤、修饰甚至像素级的变换操作处理图片。
from PIL import Image, ImageFilter
kitten = Image.open("f:/gitee/python-scraping/v1/chapter11/kitten.jpg")
blurryKitten = kitten.filter(ImageFilter.GaussianBlur)
blurryKitten.save("f:/gitee/python-scraping/v1/chapter11/kitten_blurred.jpg")
blurryKitten.show()

如果在vscode开发工具中,open和save的文件路径会以vscode 的项目文件夹作为根目录,如 F:\gitee\python-scraping
描述
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

注意: Python2.7 返回列表,Python3.x 返回迭代器对象,具体内容可以查看:Python3 filter() 函数

语法
以下是 filter() 方法的语法:

filter(function, iterable)
参数
function – 判断函数。
iterable – 可迭代对象。
返回值
返回列表。

filter(function,iterable)
function判断函数,iterable可迭代对象,返回值,返回列表‘

Tesseract

Tesseract 是目前公认最优秀、最精确的开源 OCR 系统。
除了极高的精确度, Tesseract 也具有很高的灵活性。它可以通过训练识别出任何字体(只要这些字体的风格保持不变就可以),也可以识别出任何 Unicode 字符。
Tesseract 是一个 Python 的命令行工具,不是通过 import语句导入的库。安装之后,要用 tesseract 命令在 Python 的外面运行。

安装

https://digi.bib.uni-mannheim.de/tesseract/
https://github.com/tesseract-ocr/tesseract/tags

设置

点击系统变量新建增加一个TESSDATA_PREFIX变量名,变量值还是安装路径F:\Program Files (x86)\Tesseract-OCR\tessdata,全部确定,重新打开开发工具,运行代码。
PATH中加入F:\Program Files (x86)\Tesseract-OCR

https://www.cnblogs.com/gl1573/p/9876397.html

如果在vscode开发工具中,open和save的文件路径会以vscode 的项目文件夹作为根目录,如 F:\gitee\python-scraping

NumPy

虽然 NumPy 并非解决 OCR 问题时必须使用的库,但是如果你想训练 Tesseract 识别本章后面提到的字符或字体, 那么就会用到它。 NumPy 是一个非常强大的库,具有大量线性代数以及大规模科学计算的方法。 因为 NumPy 可以用数学方法把图片表示成巨大的像素数组,所以它可以流畅地配合 Tesseract 完成任务。
和其他 Python 库一样, NumPy 可以通过第三方包管理器(比如 pip)来安装:

$pip install numpy

二、处理格式规范的文字

概述

要处理的大多数文字都是比较干净、格式规范的。格式规范的文字通常可以满足一些需求,不过究竟什么是“格式混乱”,什么算“格式规范”,确实因人而异。
通常,格式规范的文字具有以下特点:
• 使用一个标准字体(不包含手写体、草书,或者十分“花哨的”字体)
• 虽然被复印或拍照,字体还是很清晰,没有多余的痕迹或污点
• 排列整齐,没有歪歪斜斜的字
• 没有超出图片范围,也没有残缺不全,或紧紧贴在图片的边缘
文字的一些格式问题在图片预处理时可以进行解决。 例如,可以把图片转换成灰度图,调整亮度和对比度, 还可以根据需要进行裁剪和旋转。但是,这些做法在进行更具扩展性的训练时会遇到一些限制。

清晰图片识别

简介


输入如下命令进行识别:
KaTeX parse error: Expected 'EOF', got '#' at position 203: …ome symbols: !@#̲%"&’()
模糊图片识别

随着背景色从左到右不断加深,文字变得越来越难以识别。另外,经过 JPG 格式转换和模糊效果处理, Tesseract 更难识别小写“ i”和大写“ I”以及数字“ 1”。
遇到这类问题, 可以先用 Python 脚本对图片进行清理。利用 Pillow 库, 我们可以创建一个阈值过滤器来去掉渐变的背景色, 只把文字留下来,从而让图片更加清晰,便于 Tesseract读取。

实现

from PIL import Image
import subprocess
def cleanFile(filePath, newFilePath):image = Image.open(filePath)#Set a threshold value for the image, and saveimage = image.point(lambda x: 0 if x<143 else 255)image.save(newFilePath)#call tesseract to do OCR on the newly created imagesubprocess.call(["tesseract", newFilePath, "output"])    #Open and read the resulting data fileoutputFile = open("output.txt", 'r')print(outputFile.read())outputFile.close()cleanFile("f:/gitee/python-scraping/v1/chapter11/files/text_2.png", "f:/gitee/python-scraping/v1/chapter11/files/text_2_clean.png")

从网站图片中抓取文字

虽然亚马逊的 robots.txt 文件允许抓取网站的产品页面,但是图书的预览页通常不让网络机器人采集。图书的预览页是通过用户触发 Ajax 脚本进行加载的,预览图片隐藏在 div 节点下面;其实,普通的访问者会觉得它们看起来更像是一个 Flash 动画, 而不是一个图片文件。当然,即使我们能获得图片,要把它们读成文字也没那么简单。

import time
from urllib.request import urlretrieve
import subprocess
from selenium import webdriver
# driver = webdriver.PhantomJS()
driver = webdriver.Chrome()
driver.get("http://www.amazon.com/War-Peace-Leo-Nikolayevich-Tolstoy/dp/1427030200")
time.sleep(2)driver.find_element_by_id("img-canvas").click()
#The easiest way to get exactly one of every page
imageList = set()#Wait for the page to load
time.sleep(10)
print(driver.find_element_by_id("sitbReaderRightPageTurner").get_attribute("style"))

首先导航到托尔斯泰的《战争与和平》的大字号印刷版 1,打开阅读器, 收集图片的 URL 链接,然后下载图片,识别图片,最后打印每个图片的文字。因为这个程序很复杂, 利用了前面几章的多个程序片段,所以我增加了一些注释以让每段代码的目的更加清晰:

while "pointer" in driver.find_element_by_id("sitbReaderRightPageTurner").get_attribute("style"):#While we can click on the right arrow, move through the pagesdriver.find_element_by_id("sitbReaderRightPageTurner").click()time.sleep(2)#Get any new pages that have loaded (multiple pages can load at once)pages = driver.find_elements_by_xpath("//div[@class='pageImage']/div/img")for page in pages:image = page.get_attribute("src")imageList.add(image)
driver.quit()
#Start processing the images we've collected URLs for with Tesseract
for image in sorted(imageList):urlretrieve(image, "page.jpg")p = subprocess.Popen(["tesseract", "page.jpg", "page"], stdout=subprocess.PIPE,stderr=subprocess.PIPE)p.wait()f = open("page.txt", "r")print(f.read())

三、读取验证码与训练Tesseract

简介

  • 解决文字混乱的问题, 尤其是花一点儿时间训练Tesseract 的时候。通过给 Tesseract 提供大量已知的文字与图片映射集,经过训练 Tesseract就可以“学会”识别同一种字体,而且可以达到极高的精确率和准确率,甚至可以忽略图片中文字的背景色和相对位置等问题。
    CAPTCHA,全自动区分计算机和人类的图灵测试( Completely Automated Public Turing test to tell Computers andHumans Apart)。它的奇怪缩写似乎表示,它一直在扮演着十分奇怪的角色。其目的是为了阻止网站访问, 而不是让访问更通畅。
    图灵测试首次出现在阿兰·图灵( Alan Turing) 1950 年发表的论文“计算装置与智能”( Computing Machinery and Intelligence)中。他在论文中描述了这样一种场景:一个人可以和其他人交流, 也可以通过计算机终端和人工智能程序交流。如果一番对话之后这个人不能区分人和人工智能程序, 那么就认为这个人工智能程序通过了图灵测试,图灵认为这个人工智能程序就可以真正地“思考”所有的事情。

简单的验证码图片特点

• 字母没有相互叠加在一起, 在水平方向上也没有彼此交叉。也就是说,可以在每一个字母外面画一个方框,而不会重叠在一起。
• 图片没有背景色、线条或其他对 OCR 程序产生干扰的噪点。
• 虽然不能因一个图片下定论, 但是这个验证码用的字体种类很少, 而且用的是 sans-serif字体(像“ 4”和“ M”)和一种手写形式的字体(像“ m”“ C”和“ 3”)。
• 白色背景色与深色字母之间的对比度很高。

验证码图片特点

• 字母和数据都使用了,这会增加待搜索字符的数量。
• 字母随机的倾斜程度会迷惑 OCR 软件,但是人类还是很容易识别的。
• 那个比较陌生的手写字体很有挑战性, 在“ C” 和“ 3”里面还有额外的线条。另外这个非常小的小写“ m”,计算机需要进行额外的训练才能识别。

训练Tesseract

  • 要训练 Tesseract 识别一种文字,无论是晦涩难懂的字体还是验证码,你都需要向 Tesseract提供每个字符不同形式的样本。
  • 首先要把大量的验证码样本下载到一个文件夹里。下载的样本数量由验证码的复杂程度决定; 我在训练集里一共放了 100 个样本(一共 500 个字符,平均每个字符 8个样本; a~z 大小写字母加 0~9 数字,一共 62 个字符),应该足够训练的了。
  • 第二步是准确地告诉 Tesseract 一张图片中的每个字符是什么,以及每个字符的具体位置。这里需要创建一些矩形定位文件( box file),一个验证码图片生成一个矩形定位文件。
  • 提示:建议使用验证码的真实结果给每个样本文件命名(即 4MmC3.jpg)。 这样可以帮你一次性对大量的文件进行快速检查——你可以先把图片调成缩略图模式,然后通过文件名对比不同的图片。这样在后面的步骤中进行训练效果的检查也会很方便。

一个图片的矩形定位文件

4 15 26 33 55 0
M 38 13 67 45 0
m 79 15 101 26 0
C 111 33 136 60 0
3 147 17 176 45 0
  • 第一列符号是图片中的每个字符,后面的 4 个数字分别是包围这个字符的最小矩形的坐标(图片左下角是原点 (0,0), 4 个数字分别对应每个字符的左下角 x 坐标、左下角 y 坐标、右上角 x 坐标和右上角 y 坐标),最后一个数字“ 0”表示图片样本的编号。
  • 手工创建这些图片矩形定位文件很无聊,可以利用一些工具完成。
  • 矩形定位文件必须保存在一个 .box 后缀的文本文件中。和图片文件一样,文本文件也是用验证码的实际结果命名( 例如, 4MmC3.box)。
  • Tesseract OCR Chopper( http://pp19dd.com/tesseract-ocr-chopper/),另外,这样便于检查 .box 文件的内容和文件的名称,而且按文件名对目录中的文件排序之后,就可以让 .box 文件与对应的图片文件的实际结果进行对比。

训练

  • 完成所有的数据分析工作和创建 Tesseract 所需的训练文件,参见一个 Python 版的解决方案( https://github.com/REMitchell/tesseract-trainer)来处理同时包含图片文件和 .box 文件的数据文件夹,然后自动创建所有必需的训练文件。

四、获取验证码提交答案

简介

许多流行的内容管理系统即使加了验证码模块,其众所周知的注册页面也经常会遭到网络机器人的垃圾注册。
大多数网站生成的验证码图片都具有以下属性。
• 它们是服务器端的程序动态生成的图片。 验证码图片的 src 属性可能和普通图片不太一样,比如 ,但是可以和其他图片一样进行下载和处理。
• 图片的答案存储在服务器端的数据库里。
• 很多验证码都有时间限制, 如果太长时间没解决就会失效。虽然这对网络机器人来说不是什么问题, 但是如果保留验证码的答案一会儿再使用,或者想通过一些方法延长验证码的有效时限,可能很难成功。

from urllib.request import urlretrieve
from urllib.request import urlopen
from bs4 import BeautifulSoup
import subprocess
import requests
from PIL import Image
from PIL import ImageOps# https://blog.csdn.net/u010134642/article/details/78747630def cleanImage(imagePath):image = Image.open(imagePath)image = image.point(lambda x: 0 if x<143 else 255)borderImage = ImageOps.expand(image,border=20,fill='white')borderImage.save(imagePath)
html = urlopen("http://www.pythonscraping.com/humans-only")
bsObj = BeautifulSoup(html, "html.parser")
#Gather prepopulated form values
imageLocation = bsObj.find("img", {"title": "Image CAPTCHA"})["src"]
formBuildId = bsObj.find("input", {"name":"form_build_id"})["value"]
captchaSid = bsObj.find("input", {"name":"captcha_sid"})["value"]
captchaToken = bsObj.find("input", {"name":"captcha_token"})["value"]captchaUrl = "http://pythonscraping.com"+imageLocation
urlretrieve(captchaUrl, "captcha.jpg")
cleanImage("captcha.jpg")
p = subprocess.Popen(["tesseract", "captcha.jpg", "captcha"], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p.wait()
f = open("captcha.txt", "r", encoding='gbk')
#Clean any whitespace characters
captchaResponse = f.read().replace(" ", "").replace("\n", "").replace('\x0c',"")
print("Captcha solution attempt: "+captchaResponse)if len(captchaResponse) == 5:params = {"captcha_token":captchaToken, "captcha_sid":captchaSid,   "form_id":"comment_node_page_form", "form_build_id": formBuildId, "captcha_response":captchaResponse, "name":"Ryan Mitchell", "subject": "I come to seek the Grail", "comment_body[und][0][value]": "...and I am definitely not a bot"}r = requests.post("http://www.pythonscraping.com/comment/reply/10", data=params)responseObj = BeautifulSoup(r.text)if responseObj.find("div", {"class":"messages"}) is not None:print(responseObj.find("div", {"class":"messages"}).get_text())
else:print("There was a problem reading the CAPTCHA correctly!")

【课件整理复习】第十一章 图像识别与文字处理相关推荐

  1. 【上课课件整理复习】第六章 网页数据的采集(1)

    知识回顾 网络爬虫的概念 网络爬虫的应用 网络爬虫的实现 数据写入和读取 本章内容 遍历单个域名 采集整个网站 通过互联网采集 本章目标 掌握遍历单个域名的方法 掌握采集整个网站的方法 了解通过互联网 ...

  2. 计算机网络离不开光缆,九年级物理全册 第二十一章 第四节 越来越宽的信息之路习题课件 新人教版.ppt...

    九年级物理全册 第二十一章 第四节 越来越宽的信息之路习题课件 新人教版.ppt 第二十一章信息的传递,第四节越来越宽的信息之路,1微波的性质更接近光波,大致沿_______传播,需要每隔_____k ...

  3. 软件工程复习提纲——第十一章

    软件工程复习提纲,期末.考研的学霸笔记 第十一章--软件项目管理 第十一章 软件项目管理 事件4的最早时刻为:EET=max{2+3,6+0}: 事件9的最迟时刻为: LET=21-1=20: 事件8 ...

  4. 计算机游戏教学法.ppt,计算机游戏教学法第十一章课件.ppt

    计算机游戏教学法第十一章课件 第十一章 计算机游戏教学法 方法简介: 游戏与严肃性 在通常的思路中,玩游戏就是一件极不严肃的事情,人们看到的只是游戏所带来的负面影响,却从不愿正视游戏的积极功能.比如我 ...

  5. 鸟哥的Linux私房菜(基础篇)- 第十一章、认识与学习 BASH

    第十一章.认识与学习 BASH 最近升级日期:2009/08/25 在 Linux 的环境下,如果你不懂 bash 是什么,那么其他的东西就不用学了!因为前面几章我们使用终端机下达命令的方式,就是透过 ...

  6. 第十一章、认识与学习 BASH

    第十一章.认识与学习 BASH 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 shell 与 /etc/shel ...

  7. 鸟哥的Linux私房菜(服务器)- 第二十一章、文件服务器之三: FTP 服务器

    第二十一章.文件服务器之三: FTP 服务器 最近更新日期:2011/08/08 FTP (File Transfer Protocol) 可说是最古老的协议之一了,主要是用来进行档案的传输,尤其是大 ...

  8. 第十一章、认识与学习BASH

    第十一章.认识与学习BASH 第十一章.认识与学习 BASH  最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 ...

  9. 鸟哥的Linux私房菜(基础篇)- 第二十一章、系统配置工具(网络与打印机)与硬件侦测

    第二十一章.系统配置工具(网络与打印机)与硬件侦测 最近升级日期:2009/09/15 除了手动配置之外,其实系统提供了一个名为 setup 的命令给系统管理员使用喔!这个命令还能够配置网络呢.此外, ...

最新文章

  1. Suricata的输出
  2. Google团队发布,一文概览Transformer模型的17大高效变种
  3. int ,long , long long类型的范围
  4. Docker Cgroups
  5. .html天气预报上蔡,上蔡天气预报15天
  6. 何时该用无服务器,何时该用Kubernetes?
  7. python监控键盘输入_Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】...
  8. Python学习 Day 3 字符串 编码 list tuple 循环 dict set
  9. postgresql 遍历字符串数组_每日一道编程题(348):1005.K次取反后最大化的数组和...
  10. hashmap示例_Java HashMap remove()方法与示例
  11. mysql ip v4 v6_mysql IPv4 IPv6
  12. matlab中的controller,MatlabSimulinkPIDController(2DOF)..docx
  13. paip.提升效率----几款任务栏软件vc59
  14. com.alibaba.dubbo.rpc.RpcException: Since you are
  15. 鸡兔同笼的两种求解(C语言)
  16. 安装oh my zsh后出现的目录权限问题
  17. 中国出海50强,华为超越阿里得亚军,第一名居然是它?
  18. win7 设定固定的ip地址
  19. fedora8 中安装oracle,技术|在 RHEL、CentOS 及 Fedora 上安装 Drupal 8
  20. 视频直播APP源码开发iOS音频播放流程

热门文章

  1. python训练营 朋友圈点赞收费吗_千万不要随便在朋友圈点赞!
  2. 安装黑苹果提示未能安装_黑苹果安装过程中经常出现的问题及解决方法
  3. 第一节、linux中安装redis(一)
  4. 华为手机老是android自动升级,安卓手机系统升级!华为手机系统更新设置
  5. 福尔摩斯到某古堡探险
  6. xml 标签带有符号php,php-如果元素每个记录有相似的标记,则获取正确的xml值
  7. python 人工智能编程_最适合人工智能开发的5种编程语言
  8. Ubuntu子系统安装GPGPU-SIM(附相关文件)
  9. 香港云服务器比香港服务器更快吗?
  10. 4.15 最短路 题