Python:处理一些格式规范的文字
你要處理的大多數(shù)文字都是比較干凈、格式規(guī)范的。格式規(guī)范的文字通常可以滿足一些需求,不過(guò)究竟什么是“格式混亂”,什么算“格式規(guī)范”,確實(shí)因人而異。 通常,格式規(guī)范的文字具有以下特點(diǎn):
- 使用一個(gè)標(biāo)準(zhǔn)字體(不包含手寫(xiě)體、草書(shū),或者十分“花哨的”字體) ? 雖然被復(fù)印或拍照,字體還是很清晰,沒(méi)有多余的痕跡或污點(diǎn)
- 排列整齊,沒(méi)有歪歪斜斜的字
- 沒(méi)有超出圖片范圍,也沒(méi)有殘缺不全,或緊緊貼在圖片的邊緣
文字的一些格式問(wèn)題在圖片預(yù)處理時(shí)可以進(jìn)行解決。例如,可以把圖片轉(zhuǎn)換成灰度圖,調(diào) 整亮度和對(duì)比度,還可以根據(jù)需要進(jìn)行裁剪和旋轉(zhuǎn)(詳情請(qǐng)關(guān)注圖像與信號(hào)處理),但是,這些做法在進(jìn)行更具擴(kuò)展性的 訓(xùn)練時(shí)會(huì)遇到一些限制。
格式規(guī)范文字的理想示例
?
通過(guò)下面的命令運(yùn)行 Tesseract,讀取文件并把結(jié)果寫(xiě)到一個(gè)文本文件中: `tesseract test.jpg text
?
cat text.txt?即可顯示結(jié)果。
識(shí)別結(jié)果很準(zhǔn)確,不過(guò)符號(hào)^和*分別被表示成了雙引號(hào)和單引號(hào)。大體上可以讓你很舒服地閱讀。
通過(guò)Python代碼實(shí)現(xiàn)
import pytesseract
from PIL import Imageimage = Image.open('test.jpg')
text = pytesseract.image_to_string(image)
print text
運(yùn)行結(jié)果:
This is some text, written in Arial, that will be read by
Tesseract. Here are some symbols: !@#$%"&*()
對(duì)圖片進(jìn)行閾值過(guò)濾和降噪處理(了解即可)
很多時(shí)候我們?cè)诰W(wǎng)上會(huì)看到這樣的圖片:
?
Tesseract 不能完整處理這個(gè)圖片,主要是因?yàn)閳D片背景色是漸變的,最終結(jié)果是這樣:
?
隨著背景色從左到右不斷加深,文字變得越來(lái)越難以識(shí)別,Tesseract 識(shí)別出的 每一行的最后幾個(gè)字符都是錯(cuò)的。
遇到這類(lèi)問(wèn)題,可以先用 Python 腳本對(duì)圖片進(jìn)行清理。利用 Pillow 庫(kù),我們可以創(chuàng)建一個(gè) 閾值過(guò)濾器來(lái)去掉漸變的背景色,只把文字留下來(lái),從而讓圖片更加清晰,便于 Tesseract 讀取:
from PIL import Image
import subprocessdef cleanFile(filePath, newFilePath): image = Image.open(filePath)# 對(duì)圖片進(jìn)行閾值過(guò)濾,然后保存image = image.point(lambda x: 0 if x<143 else 255) image.save(newFilePath)# 調(diào)用系統(tǒng)的tesseract命令對(duì)圖片進(jìn)行OCR識(shí)別 subprocess.call(["tesseract", newFilePath, "output"])# 打開(kāi)文件讀取結(jié)果file = open("output.txt", 'r') print(file.read()) file.close()cleanFile("text2.jpg", "text2clean.png")
通過(guò)一個(gè)閾值對(duì)前面的“模糊”圖片進(jìn)行過(guò)濾的結(jié)果
?
?
除了一些標(biāo)點(diǎn)符號(hào)不太清晰或丟失了,大部分文字都被讀出來(lái)了。Tesseract 給出了最好的 結(jié)果:
?
?
從網(wǎng)站圖片中抓取文字
用 Tesseract 讀取硬盤(pán)里圖片上的文字,可能不怎么令人興奮,但當(dāng)我們把它和網(wǎng)絡(luò)爬蟲(chóng)組合使用時(shí),就能成為一個(gè)強(qiáng)大的工具。
網(wǎng)站上的圖片可能并不是故意把文字做得很花哨 (就像餐館菜單的 JPG 圖片上的藝術(shù)字),但它們上面的文字對(duì)網(wǎng)絡(luò)爬蟲(chóng)來(lái)說(shuō)就是隱藏起來(lái) 了,舉個(gè)例子:
-
雖然亞馬遜的 robots.txt 文件允許抓取網(wǎng)站的產(chǎn)品頁(yè)面,但是圖書(shū)的預(yù)覽頁(yè)通常不讓網(wǎng)絡(luò)機(jī) 器人采集。
-
圖書(shū)的預(yù)覽頁(yè)是通過(guò)用戶觸發(fā) Ajax 腳本進(jìn)行加載的,預(yù)覽圖片隱藏在 div 節(jié)點(diǎn) 下面;其實(shí),普通的訪問(wèn)者會(huì)覺(jué)得它們看起來(lái)更像是一個(gè) Flash 動(dòng)畫(huà),而不是一個(gè)圖片文 件。當(dāng)然,即使我們能獲得圖片,要把它們讀成文字也沒(méi)那么簡(jiǎn)單。
-
下面的程序就解決了這個(gè)問(wèn)題:首先導(dǎo)航到托爾斯泰的《戰(zhàn)爭(zhēng)與和平》的大字號(hào)印刷版 1, 打開(kāi)閱讀器,收集圖片的 URL 鏈接,然后下載圖片,識(shí)別圖片,最后打印每個(gè)圖片的文 字。因?yàn)檫@個(gè)程序很復(fù)雜,利用了前面幾章的多個(gè)程序片段,所以我增加了一些注釋以讓 每段代碼的目的更加清晰:
import time
from urllib.request import urlretrieve
import subprocess
from selenium import webdriver
#創(chuàng)建新的Selenium driver
driver = webdriver.PhantomJS()# 用Selenium試試Firefox瀏覽器:
# driver = webdriver.Firefox()driver.get("http://www.amazon.com/War-Peace-Leo-Nikolayevich-Tolstoy/dp/1427030200")
# 單擊圖書(shū)預(yù)覽按鈕 driver.find_element_by_id("sitbLogoImg").click() imageList = set()
# 等待頁(yè)面加載完成
time.sleep(5)
# 當(dāng)向右箭頭可以點(diǎn)擊時(shí),開(kāi)始翻頁(yè)
while "pointer" in driver.find_element_by_id("sitbReaderRightPageTurner").get_attribute("style"):driver.find_element_by_id("sitbReaderRightPageTurner").click()time.sleep(2)# 獲取已加載的新頁(yè)面(一次可以加載多個(gè)頁(yè)面,但是重復(fù)的頁(yè)面不能加載到集合中) 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()# 用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 讀取的效果一樣,這個(gè)程序也會(huì)完美地打印書(shū)中很多長(zhǎng)長(zhǎng)的段 落,第六頁(yè)的預(yù)覽如下所示:
6"A word of friendly advice, moncher. Be off as soon as you can,that's all I have to tell you. Happyhe who has ears to hear. Good-by,my dear fellow. Oh, by the by!" heshouted through the doorway afterPierre, "is it true that the countesshas fallen into the clutches of theholy fathers of the Society of je-sus?"Pierre did not answer and left Ros-topchin's room more sullen and an-gry than he had ever before shownhimself.
但是,當(dāng)文字出現(xiàn)在彩色封面上時(shí),結(jié)果就不那么完美了:
WEI' nrrd PeaceLen Nlkelayevldu IolfluyReadmg shmdd be axwlnvame asnossxble Wenfleran mm m our cram: Llhvary- Leo Tmsloy was a Russian rwovelwstI and moval phflmopher med lurA ms Ideas 01 nonviolenx reswslance m 5 We range 0, "and"
如果想把文字加工成普通人可以看懂的 效果,還需要花很多時(shí)間去處理。
下一節(jié)將介紹另一種方法來(lái)解決文字混亂的問(wèn)題,尤其是當(dāng)你愿意花一點(diǎn)兒時(shí)間訓(xùn)練 Tesseract 的時(shí)候。
通過(guò)給 Tesseract 提供大量已知的文字與圖片映射集,經(jīng)過(guò)訓(xùn)練 Tesseract 就可以“學(xué)會(huì)”識(shí)別同一種字體,而且可以達(dá)到極高的精確率和準(zhǔn)確率,甚至可以忽略圖 片中文字的背景色和相對(duì)位置等問(wèn)題。
總結(jié)
以上是生活随笔為你收集整理的Python:处理一些格式规范的文字的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python:尝试对知乎网验证码进行处理
- 下一篇: Python机器学习:训练Tessera