1. 程式人生 > >Python 5分鐘搭建OCR伺服器,基本破解簡單的驗證碼!

Python 5分鐘搭建OCR伺服器,基本破解簡單的驗證碼!

Python 5分鐘搭建OCR伺服器,基本破解簡單的驗證碼!

Why?

OCR(又叫光學字元識別)已經成為Python的一個常用工具。隨著開源庫Tesseract和Ocrad的出現,越來越多的程式設計師用OCR來編寫自己的庫檔案和bot病毒。一個OCR的小例子,如用OCR直接從截圖中提取文字,省去了重新鍵入的麻煩。

          學習Python中有不明白推薦加入交流群
                號:516107834
                群裡有志同道合的小夥伴,互幫互助,
                群裡有不錯的學習教程!

開始的步驟

開始之前,我們需要開發一個後端服務層來表示OCR引擎的結果。這樣你就可以用你喜歡的方式來向端使用者表示你的結果。本文之後將會詳細介紹。除此之外,我們還需要新增一點後端程式碼來生成HTML表格,以及一些使用這些API的前段程式碼。這部分本文沒有講,但是你可以參閱原始碼。

準備好開始吧!

首先,需要安裝一些依賴項。這個過程也是非常有趣的。

本文已經在Ubuntu 14.04測試,但是12.x和13.x版本應該也可以。如果你用的是OSX系統,可以用VirtualBox,Docker(注意檢查有沒有包含Dockerfile和install guide),或者是DigitalOcean(推薦使用)來建立相應的環境。

Python 5分鐘搭建OCR伺服器,基本破解簡單的驗證碼!

OCR acronym definition speech bubble illustration

 

下載依賴項

我們需要Tesseract及其所有依賴項,包括Leptonica及其他相關的包。

注意:可以用_run.sh這個shell指令碼來快速安裝Leptonica和Tesseract的依賴包。如果這麼做的話,可以直接跳到搭建Web伺服器(跳轉連結)部分。但是為了學習,如果你以前沒有親手構建過庫檔案的話,還是建議嘗試一下。

$ sudo apt-get update
$ sudo apt-get install autoconf automake libtool
$ sudo apt-get install libpng12-dev
$ sudo apt-get install libjpeg62-dev
$ sudo apt-get install g++
$ sudo apt-get install libtiff4-dev
$ sudo apt-get install libopencv-dev libtesseract-dev
$ sudo apt-get install git
$ sudo apt-get install cmake
$ sudo apt-get install build-essential
$ sudo apt-get install libleptonica-dev
$ sudo apt-get install liblog4cplus-dev
$ sudo apt-get install libcurl3-dev
$ sudo apt-get install python2.7-dev
$ sudo apt-get install tk8.5 tcl8.5 tk8.5-dev tcl8.5-dev
$ sudo apt-get build-dep python-imaging --fix-missing

 

發生了什麼?

簡單說,sudo apt-get update意思就是更新包列表。然後就能安裝一些影象處理的包,如libtiff,libpng等等。除此之外,我們還需要安裝Python 2.7,作為我們的程式語言,以及python-imaging庫。

說起影象,在將程式裡面編輯影象之前我們還需要ImageMagick包。

$ sudo apt-get install imagemagick

 

構建Leptonica和Tesseract

再說一遍,如果你用_run.sh指令碼已經安裝過,就可以直接跳到搭建Web伺服器(跳轉連結)部分。

Leptonica

現在,開始安裝Leptonica。

$ wget http://www.leptonica.org/source/leptonica-1.70.tar.gz
$ tar -zxvf leptonica-1.70.tar.gz$ cd leptonica-1.70/
$ ./autobuild$ ./configure
$ make
$ sudo make install
$ sudo ldconfig

 

如果這是你第一次用tar的話,按照如下步驟操作:

1. 用wget下載Leptonica的二進位制檔案

2. 解壓

3. 用cd進入解壓後的資料夾

4. 執行autobuild和configure指令碼安裝

5. 執行make命令build

6. Build後安裝

7. 執行ldconfig建立相關的連結

OK,Leptonica建立好了,接下來就是Tesseract了。

Tesseract

現在下載並安裝Tesseract吧。

$ cd ..
$ wget https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.02.tar.gz
$ tar -zxvf tesseract-ocr-3.02.02.tar.gz$ cd tesseract-ocr/
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig

 

此處構建了一個Leptonica的映像,這部分的詳細資訊參考Leptonica的解釋。

環境變數

我們需要設定一個環境變數來訪問Tesseract資料:

$ export TESSDATA_PREFIX=/usr/local/share/

 

Tesseract包

最後安裝一下Tesseract相關的語言包:

$ cd ..
$ wget https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz
$ tar -xf tesseract-ocr-3.02.eng.tar.gz
$ sudo cp -r tesseract-ocr/tessdata 
$TESSDATA_PREFIX

 

OK,Tesseract也安裝好了,可以CLI來測試一下。更多的資訊可以參考docs(超連結)。但是,我們還需要一個Python環境。所以,接下來安裝一個能夠接受以下兩種請求的Flask伺服器:

1. 接受影象URL

2. 能夠對影象進行字元識別

搭建Web伺服器

最有趣的事情來了!首先,我們需要構建一種通過Python和Tesseract互動的方式。我們可以使用popen,但是那不是python的風格。所以,我們可以使用一個非常小但是功能非常強大的Python包將Tesseract封裝起來——pytesseract(超連結)。

想要快點的話,就執行_app.sh指令碼,否則,點選這裡(超連結)獲取程式碼/結構的模板,然後執行一下命令:

$ wget https://github.com/rhgraysonii/ocr_tutorial/archive/v0.tar.gz
$ tar -xf v0.tar.gz
$ mv ocr_tutorial-0/* ../home/
$ cd ../home
$ sudo apt-get install python-virtualenv
$ virtualenv env
$ source env/bin/activate
$ pip install -r requirements.txt

 

注意:Flask模板(有Real Python(超連結)維護)是一個獲取簡單的具有Python風格的伺服器的非常棒的庫。本文將它用來作為基本程式。點選這裡(超連結)獲取更多資訊。

安裝OCR引擎

現在,我們需要用pytesseract來建立一個類來讀取圖片。在flask_server目錄下建立一個新的檔案ocr.py,寫入如下程式碼:

import pytesseract
import requests
from PIL import Image
from PIL import ImageFilter
from StringIO import StringIO
def process_image(url):
 image = _get_image(url)
 image.filter(ImageFilter.SHARPEN)
 return pytesseract.image_to_string(image)
def _get_image(url):
 return Image.open(StringIO(requests.get(url).content))

 

非常好!

主方法process_image()的功能是銳化影象文字。

現在,這個模組已經可以用了。

可選項:為你的OCR引擎建立一個CLI工具

做了這麼多繁瑣配置工作,讓我們來建立一個CLI工具來調節一下心情吧。在flask_server目錄下建立一個新的檔案cli.py,寫入如下程式碼:

import sys
import requests
import pytesseract
from PIL import Image
from StringIO import StringIO
def get_image(url):
 return Image.open(StringIO(requests.get(url).content))
if __name__ == '__main__':
 """Tool to test the raw output of pytesseract with a given input URL"""
 sys.stdout.write("""
===OOOO=====CCCCC===RRRRRR=====

==OO==OO===CC=======RR===RR====

==OO==OO===CC=======RR===RR====

==OO==OO===CC=======RRRRRR=====

==OO==OO===CC=======RR==RR=====

==OO==OO===CC=======RR== RR====

===OOOO=====CCCCC===RR====RR===


""")
 sys.stdout.write("A simple OCR utility
")
 url = raw_input("What is the url of the image you would like to analyze?
")
 image = get_image(url)
 sys.stdout.write("The raw output from tesseract with no processing is:

")
 sys.stdout.write("-----------------BEGIN-----------------
")
 sys.stdout.write(pytesseract.image_to_string(image) + "
")
 sys.stdout.write("------------------END------------------
")

 

非常簡單。之後我們就能看到從我們的OCR引擎中輸出到標準輸出STDOUT上的文字了。執行python flask_server/cli.py來試一下吧。

回到伺服器

既然我們已經安裝好了OCR引擎,接下來該準備輸出了。講下面的程式碼加入到

app.py檔案:

@app.route('/v{}/ocr'.format(_VERSION), methods=["POST"])
def ocr():
 try:
 url = request.json['image_url']
 if 'jpg' in url:
 output = process_image(url)
 return jsonify({"output": output})
 else:
 return jsonify({"error": "only .jpg files, please"})
 except:
 return jsonify(
 {"error": "Did you mean to send: {'image_url': 'some_jpeg_url'}"}
 )

 

確保引入的下列包是最新的:

import os
import logging
from logging import Formatter, FileHandler
from flask import Flask, request, jsonify
from ocr import process_image

 

最後,新增一行API版本號:

_VERSION = 1 # API version

 

從程式碼中可以看到,我們以PIL中Image檔案物件的方式把JSON的響應傳入引擎的process_image()方法中。並且,就目前而言,它只支援.jpg圖片。

注意:如果PIL包沒有安裝的話,可以用Pillow包來代替。PIL有一些問題還沒有解決,Python社群對它的看法也不統一,詳細情況可以自行Google。

測試

執行你的程式:

$ cd ../home/flask_server/
$ python app.py

 

然後,在另外一個終端執行:

$ curl -X POST http://localhost:5000/v1/ocr -d '{"image_url": "some_url"}' -H "Content-Type: application/json"

 

例子

$ curl -X POST http://localhost:5000/v1/ocr -d '{"image_url": "https://www.realpython.com/images/blog_images/ocr/ocr.jpg"}' -H "Content-Type: application/json"
{
 "output": "ABCDE
FGH I J
KLMNO
PQRST"
}

 

前端

現在後端OCR引擎的API已經準備好了,我們可以增加一個基本的前端來使用這些API,並將結果通過AJAX和jQuery新增到DOM中。這部分內容本文就不講了,詳見這裡(超連結)。

Python 5分鐘搭建OCR伺服器,基本破解簡單的驗證碼!

 

 

用下面的樣本來測試一下:

https://www.realpython.com/images/blog_images/ocr/ocr.jpg
https://www.realpython.com/images/blog_images/ocr/sample1.jpg
https://www.realpython.com/images/blog_images/ocr/sample2.jpg
https://www.realpython.com/images/blog_images/ocr/sample3.jpg
https://www.realpython.com/images/blog_images/ocr/sample4.jpg
https://www.realpython.com/images/blog_images/ocr/sample5.jpg