詳細解讀文字識別工具———Tesseract-OCR

閱讀提示

本文將提到Tesseract-OCR的簡介、配置使用並附帶超實用案例,包括pdf文字識別、圖形驗證碼提取等。


   在嘗試破解12306驗證碼的時候,提前瞭解了一下應對各種驗證碼的解決方案,這裏主要是學習到了面對文字圖片驗證碼,例如亞馬遜、豆瓣等平臺的登錄時會遇到的情況,效果還不錯。

一、工具介紹

​    Tesseract-OCR 是一款由HP實驗室開發由Google維護的開源OCR(Optical Character Recognition , 光學字符識別)引擎。與Microsoft Office Document Imaging(MODI)相比,我們可以不斷的訓練的庫,使圖像轉換文本的能力不斷增強;如果團隊深度需要,還可以以它爲模板,開發出符合自身需求的OCR引擎。
GitHub 地址:https://github.com/tesseract-…
安裝包官方下載地址:https://digi.bib.uni-mannheim…
安裝包百度雲盤下載地址:https://pan.baidu.com/s/1AOsJ…

二、配置環境變量

2.1 進入環境變量配置界面

右鍵點擊此電腦–屬性–高級系統設置–環境變量–系統變量–Path
clipboard.png

clipboard.png

clipboard.png

2.2 添加系統變量

   找到系統變量的 Path ,將 Tesseract-OCR 的安裝目錄添加進去:

clipboard.png

2.3 添加 tessdata 系統變量

   如下圖新建系統變量 : TESSDATA_PREFIX
   變量值爲 tessdata 文件夾的路徑(在Tesseract-OCR的安裝目錄下):

clipboard.png

三、使用 Tesseract-OCR

3.1 進入cmd 輸入下面的命令查看版本,正常運行則安裝成功:

tesseract --version

clipboard.png

3.2 使用下面命令識別圖片

clipboard.png

tesseract 圖片路徑 輸出文件

clipboard.png

查看輸出的 result.txt文件:

clipboard.png

結果正確!

四、處理給規範的文字

   處理的大多數文字最好都是比較乾淨、格式規範的。格式規範的文字通常可以滿足一些需求,通常格式規範的文字具有以下特點:

  • 使用一個標準字體(不包含手寫體、草書,或者十分“花哨的”字體)
  • 即使被複印或拍照,字體還是很清晰,沒有多餘的痕跡或污點
  • 排列整齊,沒有歪歪斜斜的字
  • 沒有超出圖片範圍,也沒有殘缺不全,或緊緊貼在圖片的邊緣

   文字的一些格式問題在圖片預處理時可以進行解決。例如,可以把圖片轉換成灰度圖,調整亮度和對比度,還可以根據需要進行裁剪和旋轉(詳情需要了解圖像與信號處理)等。

4.1 格式規範文字的理想示例

   識別結果很準確,不過符號^*分別被表示成了雙引號和單引號。大體上可以讓你很舒服地閱讀。

4.2 通過Python代碼實現

import pytesseract
from PIL import Image

image = Image.open('test.jpg')
text = pytesseract.image_to_string(image)
print text

運行結果:

This is some text, written in Arial, that will be read by
Tesseract. Here are some symbols: !@#$%"&*()

4.3 對圖片進行閾值過濾和降噪處理(瞭解即可)

   隨着背景色從左到右不斷加深,文字變得越來越難以識別,Tesseract 識別出的 每一行的最後幾個字符都是錯的。

   遇到這類問題,可以先用 Python 腳本對圖片進行清理。利用 PIL 庫,我們可以創建一個閾值過濾器來去掉漸變的背景色,只把文字留下來,從而讓圖片更加清晰,便於 Tesseract 讀取:

from PIL import Image
import subprocess

def cleanFile(filePath, newFilePath):
    image = Image.open(filePath)

    # 對圖片進行閾值過濾(低於143的置爲黑色,否則爲白色)
    image = image.point(lambda x: 0 if x < 143 else 255)
    # 重新保存圖片
    image.save(newFilePath)

    # 調用系統的tesseract命令對圖片進行OCR識別     
    subprocess.call(["tesseract", newFilePath, "output"]) #第三個參數是保存後的文件名

    # 打開文件讀取結果
    with open("output.txt", 'r') as f:
        print(f.read())

if __name__ == "__main__":
    cleanFile("text2.png", "text2clean.png")

通過一個閾值對前面的“模糊”圖片進行過濾的結果

4.4 從網站圖片中抓取文字

   用 Tesseract 讀取硬盤裏圖片上的文字,可能不怎麼令人興奮,但當我們把它和網絡爬蟲組合使用時,就能成爲一個強大的工具。

   網站上的圖片可能並不是故意把文字做得很花哨,但它們上面的文字對網絡爬蟲來說就是隱藏起來 了,舉個例子:

  • 雖然亞馬遜的 robots.txt 文件允許抓取網站的產品頁面,但是圖書的預覽頁通常不讓網絡機 器人採集。
  • 圖書的預覽頁是通過用戶觸發 Ajax 腳本進行加載的,預覽圖片隱藏在 div 節點 下面;其實,普通的訪問者會覺得它們看起來更像是一個 Flash 動畫,而不是一個圖片文 件。當然,即使我們能獲得圖片,要把它們讀成文字也沒那麼簡單。
  • 下面的程序就解決了這個問題:首先導航到托爾斯泰的《戰爭與和平》的大字號印刷版 1, 打開閱讀器,收集圖片的 URL 鏈接,然後下載圖片,識別圖片,最後打印每個圖片的文 字。因爲這個程序很複雜,利用了前面幾章的多個程序片段,所以我增加了一些註釋以讓 每段代碼的目的更加清晰:
#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@author: GaoYang
@file: 網站圖片和獲取文字.py
@time: 2019/12/4 21:14
@desc: 
"""
import time
from urllib.request import urlretrieve
import subprocess
from selenium import webdriver

# 創建新的selenium driver
driver = webdriver.Chrome()

# 調用瀏覽器
driver.get('http://www.amazon.com/War-Peace-Leo-Nikolayevich-Tolstoy/dp/1427030200')


# 點擊圖片
driver.find_element_by_xpath("//div[@id='img-canvas']/img").click()
time.sleep(5)
#
imageList = set()
# 等箭頭可以點擊時,開始翻頁
while "pointer" in driver.find_element_by_id("sitbReaderRightPageTurner").get_attribute('style'):
    driver.find_element_by_id("sitbReaderRightPageTurner").click()
    time.sleep(2)
    # 獲取已經加載的新頁面(一次可加載多個,但是重複的頁面不能進到集合裏)
    pages = driver.find_elements_by_xpath("//div[@class='pageImage']/div/img")
    for page in pages:
        image = page.get_attribute("src")
        imageList.add(image)
        # print(imageList)
driver.quit()

# 用Tesseract處理我們收集的圖片URL鏈接
for image in sorted(imageList):
    # 保存圖片
    urlretrieve(image, "page.jpg")
    p = subprocess.Popen(["tesseract", "page.jpg", "page"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    f = open("page.txt", 'r')
    p.wait()
    print(f.read())

   和前面使用 Tesseract 讀取的效果一樣,這個程序也會完美地打印書中很多長長的段落,第六頁的預覽如下所示:

Prince Vasily wanted this post for his son, but other people were
working through the Empress Maria Fyodorovna to get it for the
baron. Anna Pavlovna half-closed her eyes to indicate that neither she
nor anyone else could pass judgement on what the Empress might feel
like doing or want to do. 'Baron Funke has been recommended to the
Dowager Empress by her sister,) was all she said, in a dry, Tugubrious
tone. As she pronounced the name of the Empress, Anna Paviovna's
face took on an expression of profound and sincere devotion mixed
with respect and tinged with sadness, which invariably came upon her
when she had occasion to mention her exalted patroness. She said that
her Majesty had been gracious enough to show Baron Funke great
respect, at which her face once again dissolved into sadness.

但是當文字出現在彩色封面上時,結果就不那麼完美了:

   WEI' nrrd Peace
   Len Nlkelayevldu Iolfluy
   Readmg shmdd be ax
   wlnvame asnossxble Wenfler
   an mm m our cram: Llhvary
    - Leo Tmsloy was a Russian rwovelwst
    I and moval phflmopher med lur
    A ms Ideas 01 nonviolenx reswslance m 5 We range     0, "and"

   如果想把文字加工成普通人可以看懂的效果,還需要花很多時間去處理。

   比如,通過給 Tesseract 提供大量已知的文字與圖片映射集,經過訓練 Tesseract 就可以“學會”識別同一種字體,而且可以達到極高的精確率和準確率,甚至可以忽略圖片中文字的背景色和相對位置等問題。

4.5 執行 JavaScript 語句

  • 隱藏百度圖片
#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@author: GaoYang
@file: 練習2.py
@time: 2019/12/5 11:35
@desc: 
"""

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")

# 給搜索輸入框標紅的javascript腳本
js = "var q=document.getElementById(\"kw\");q.style.border=\"2px solid red\";"

# 調用給搜索輸入框標紅js腳本
driver.execute_script(js)

# 查看頁面快照
driver.save_screenshot("redbaidu.png")

# js隱藏元素,將獲取的圖片元素隱藏
img = driver.find_element_by_xpath("//*[@id='lg']/img")
driver.execute_script('$(arguments[0]).fadeOut()', img)

# 向下滾動到頁面底部
driver.execute_script("$('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);});")

# 查看頁面快照
driver.save_screenshot("nullbaidu.png")
time.sleep(3)

driver.quit()
  • 模擬滾動條滾動到底部
#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@author: GaoYang
@file: 練習2.py
@time: 2019/12/5 10:35
@desc: 
"""
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://movie.douban.com/typerank?type_name=劇情&type=11&interval_id=100:90&action=")

# 向下滾動10000像素
js = "document.body.scrollTop=10000"
#js="var q=document.documentElement.scrollTop=10000"
time.sleep(3)

#查看頁面快照
driver.save_screenshot("douban.png")

# 執行JS語句
driver.execute_script(js)
time.sleep(3)

#查看頁面快照
driver.save_screenshot("newdouban.png")

driver.quit()



★★以上是我的學習筆記,如有不足或錯誤之處還請各位讀者指正,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章