百度 OCR API 初探
近日得知百度在其 APIStore 上開放了 OCR 的 API,目前以 即用API 的形式試運行,所謂 "即用" 指可立即調用、無需注冊付費,但也加上了有使用次數這么一個限制。
目前該 API 的文檔很少,不過接口和參數都在其 API頁面 進行了說明,要用起來還是沒有問題的。下面是接口的信息
- 接口地址: http://apis.baidu.com/apistore/idlocr/ocr
- 請求方法: POST
相關的參數則有
| 參數名 | 類型 | 必填 | 參數位置 | 描述 | 可用值 |
|---|---|---|---|---|---|
| fromdevice | string | yes | bodyParam | 來源設備 | android, iPhone, pc |
| clientip | string | yes | bodyParam | 客戶端出口ip | |
| detecttype | string | yes | bodyParam | OCR服務類型 | LocateRecognize, Recognize, Locate, SingleCharRecognize |
| languagetype | string | yes | bodyParam | 待檢測的文字類型 | CHN_ENG, ENG, JAP, KOR |
| imagetype | string | yes | bodyParam | 圖片資源類型 | 1: 經過BASE64處理的字符串; 2: 圖片源文件 |
| image | string | yes | bodyParam | 圖片資源,300K以下 | |
| apikey | string | yes | header | API 密鑰 |
返回的結果會是一個 JSON 字符串,如下所示:
{
"errNum": 0,
"errMsg": "success",
"querySign": "3845925467,2370020290",
"retData": [
{
"rect": {
"left": "0",
"top": "0",
"width": "33",
"height": "31"
},
"word": " 8"
}
]
}
各字段的意義如下:
-
errNum
標識處理是否成功, 0: 表示成功, 其它值, 表示失敗。在 API頁面 上可以查看更詳細的錯誤碼列表。
-
errMsg
錯誤類型說明,當服務調用成功時為字符串 'success'
-
querySign
本次請求用戶傳遞原圖或rl的唯一標示, 方便定位問題
-
retData
返回內容集合
-
rect
該行文字所在的矩形區域的信息
-
word
該行所識別出的文字
用 Python 調用百度 OCR API
在 API 頁面上倒是提供了 Python 的調用示例,不過個人感覺比較丑,居然還在使用 urllib !我們完全可以用 requests 來做這些事情,下面是我寫的一個方法:
# -*- coding: utf-8 -*- import requests URL = 'http://apis.baidu.com/apistore/idlocr/ocr' LANG_LIST = ['CHN_ENG', 'ENG', 'JAP', 'KOR'] def ocr(picture, lang='CHN_ENG'): """Recognize a picture and return the text on it. picture could be a local picture or url of picture on web. lang should be one of CHN_ENG, ENG, JAP, KOR """ data = {} data['fromdevice'] = "pc" data['clientip'] = '10.10.10.0' data['detecttype'] = 'Recognize' data['imagetype'] = "2" if lang not in LANG_LIST: raise Exception('invalid language: %s' % lang) else: data['languagetype'] = lang # 此處應使用自己的 API key header = {"apikey": "your api key"} image_file = None try: if picture.startswith('http://') or picture.startswith('https://'): image_file = requests.get(picture).content else: image_file = open(picture, 'rb').read() except Exception: raise Exception('invalid picture: %s' % picture) resp = requests.post(URL, headers=header, data=data, files={"image": ("baidu.jpg", image_file)}) if resp is not None: resp = resp.json() if int(resp.get('errNum')) != 0: raise Exception(reps.get('errMsg')) else: return resp.get('retData')[0].get('word') else: return None
需要注意的是,雖然 API 頁面上說圖片目前僅支持 jpg 格式,但實際上對圖片格式的檢查很有可能是通過檢查文件名的后綴來進行的,所以通過將 "imagetype" 設置為 2 並將圖片以 jpg 作為后綴名進行上傳來繞過這個限制。
然后拿一張圖片來看看!好,就是下面這張了:

識別結果如下:

與 Tesseract 的簡單對比
要比較全面、客觀地對比出兩個不同的產品的性能是需要大量的數據和詳盡地設計的,這里只是根據我個人對 OCR 系統的認識,使用了少量的數據進行的對比,至於兩者孰優孰劣請讀者自行試驗再下結論。
圖一:

百度 OCR API 識別結果:
討論代數方程r+積—勁—1=0在(—”0)內實根的情況
Tesseract 識別結果:
討論代數方程娛+4籌-3χ-l=O在 (-∞,O〉 內實根的情況₋
圖二:

百度 OCR API 識別結果:
L(理)已知:是虛數單位.則(―1―D《2―D=一一一一f》 A―3+iB―1―3 C―3+3D―1―1
Tesseract 識別結果:
L₍₋₎已概ᵢ量ᵦ效單位。口(—₁針)(2₋E,= ⋯煙~₋ (
A₋₋₃+ᵢ BL-{•S宜
C.-3+3i D·一l震拿
罐震 ,△、an.△ᵅ=₂₋!₋₃—?又₋T=xf —$⩽ᵣ⩽玉 ₋l S校 r= —
圖三:

百度 OCR API 識別結果:
新課標全國)在一組樣本數據(Xl,y)G,y)%不全相等的散點圖中,若所有樣本點ki,y4+|上,則這組樣本數據的樣本相關系數為0 Boc.號
Tesseract 識別結果:
!新課標全國)在崗組樣本數據Uh趴汕懶h… 蘑. 不全相等)的散點圖中,若所有樣本點犧酬 L篆+I 上,則這組樣本數據的樣本相關系數為 o 1 B.0 時
圖四:

百度 OCR API 識別結果:
11分)如圖271日.在△A風中,∠C=45·現妹10.高AD=8.矩形EFPQ的一邊吐在風邊上,1
Tesseract 識別結果:
.’⁻.∴ 、,〉 、、.罐’∣【
r\∪【川 '′ ∣⋃./L 、∥('中.
"pQ的
圖五:

百度 OCR API 識別結果:
B
Tesseract 識別結果:
樂散說, 你是找的全部 你是耕掌希寧觸-都余 但找的主命寧 豬漆能裝有你 就傅 她環東能玻節玻引才 A美未能表有童氣 大她東能裝有四兔
從以上這些對比,我得到以下一些 不一定客觀 的結論:
- 百度的 OCR 系統對噪聲、模糊等有較強的抗干擾性,這一點上要優於 Tesseract
- 百度的 OCR 系統沒有進行布局分析,但 Tesseract 在布局分析上做得比較好
- 百度的 OCR 系統 可能 對 黑底白字 的圖像識別不好
百度 OCR API 的使用以及與 Tesseract 的簡單對比
10 Jun 2015
百度 OCR API 初探
近日得知百度在其 APIStore 上開放了 OCR 的 API,目前以 即用API 的形式試運行,所謂 "即用" 指可立即調用、無需注冊付費,但也加上了有使用次數這么一個限制。
目前該 API 的文檔很少,不過接口和參數都在其 API頁面 進行了說明,要用起來還是沒有問題的。下面是接口的信息
- 接口地址: http://apis.baidu.com/apistore/idlocr/ocr
- 請求方法: POST
相關的參數則有
| 參數名 | 類型 | 必填 | 參數位置 | 描述 | 可用值 |
|---|---|---|---|---|---|
| fromdevice | string | yes | bodyParam | 來源設備 | android, iPhone, pc |
| clientip | string | yes | bodyParam | 客戶端出口ip | |
| detecttype | string | yes | bodyParam | OCR服務類型 | LocateRecognize, Recognize, Locate, SingleCharRecognize |
| languagetype | string | yes | bodyParam | 待檢測的文字類型 | CHN_ENG, ENG, JAP, KOR |
| imagetype | string | yes | bodyParam | 圖片資源類型 | 1: 經過BASE64處理的字符串; 2: 圖片源文件 |
| image | string | yes | bodyParam | 圖片資源,300K以下 | |
| apikey | string | yes | header | API 密鑰 |
返回的結果會是一個 JSON 字符串,如下所示:
{
"errNum": 0,
"errMsg": "success",
"querySign": "3845925467,2370020290",
"retData": [
{
"rect": {
"left": "0",
"top": "0",
"width": "33",
"height": "31"
},
"word": " 8"
}
]
}
各字段的意義如下:
-
errNum
標識處理是否成功, 0: 表示成功, 其它值, 表示失敗。在 API頁面 上可以查看更詳細的錯誤碼列表。
-
errMsg
錯誤類型說明,當服務調用成功時為字符串 'success'
-
querySign
本次請求用戶傳遞原圖或rl的唯一標示, 方便定位問題
-
retData
返回內容集合
-
rect
該行文字所在的矩形區域的信息
-
word
該行所識別出的文字
用 Python 調用百度 OCR API
在 API 頁面上倒是提供了 Python 的調用示例,不過個人感覺比較丑,居然還在使用 urllib !我們完全可以用 requests 來做這些事情,下面是我寫的一個方法:
# -*- coding: utf-8 -*- import requests URL = 'http://apis.baidu.com/apistore/idlocr/ocr' LANG_LIST = ['CHN_ENG', 'ENG', 'JAP', 'KOR'] def ocr(picture, lang='CHN_ENG'): """Recognize a picture and return the text on it. picture could be a local picture or url of picture on web. lang should be one of CHN_ENG, ENG, JAP, KOR """ data = {} data['fromdevice'] = "pc" data['clientip'] = '10.10.10.0' data['detecttype'] = 'Recognize' data['imagetype'] = "2" if lang not in LANG_LIST: raise Exception('invalid language: %s' % lang) else: data['languagetype'] = lang # 此處應使用自己的 API key header = {"apikey": "your api key"} image_file = None try: if picture.startswith('http://') or picture.startswith('https://'): image_file = requests.get(picture).content else: image_file = open(picture, 'rb').read() except Exception: raise Exception('invalid picture: %s' % picture) resp = requests.post(URL, headers=header, data=data, files={"image": ("baidu.jpg", image_file)}) if resp is not None: resp = resp.json() if int(resp.get('errNum')) != 0: raise Exception(reps.get('errMsg')) else: return resp.get('retData')[0].get('word') else: return None
需要注意的是,雖然 API 頁面上說圖片目前僅支持 jpg 格式,但實際上對圖片格式的檢查很有可能是通過檢查文件名的后綴來進行的,所以通過將 "imagetype" 設置為 2 並將圖片以 jpg 作為后綴名進行上傳來繞過這個限制。
然后拿一張圖片來看看!好,就是下面這張了:

識別結果如下:

與 Tesseract 的簡單對比
要比較全面、客觀地對比出兩個不同的產品的性能是需要大量的數據和詳盡地設計的,這里只是根據我個人對 OCR 系統的認識,使用了少量的數據進行的對比,至於兩者孰優孰劣請讀者自行試驗再下結論。
圖一:

百度 OCR API 識別結果:
討論代數方程r+積—勁—1=0在(—”0)內實根的情況
Tesseract 識別結果:
討論代數方程娛+4籌-3χ-l=O在 (-∞,O〉 內實根的情況₋
圖二:

百度 OCR API 識別結果:
L(理)已知:是虛數單位.則(―1―D《2―D=一一一一f》 A―3+iB―1―3 C―3+3D―1―1
Tesseract 識別結果:
L₍₋₎已概ᵢ量ᵦ效單位。口(—₁針)(2₋E,= ⋯煙~₋ (
A₋₋₃+ᵢ BL-{•S宜
C.-3+3i D·一l震拿
罐震 ,△、an.△ᵅ=₂₋!₋₃—?又₋T=xf —$⩽ᵣ⩽玉 ₋l S校 r= —
圖三:

百度 OCR API 識別結果:
新課標全國)在一組樣本數據(Xl,y)G,y)%不全相等的散點圖中,若所有樣本點ki,y4+|上,則這組樣本數據的樣本相關系數為0 Boc.號
Tesseract 識別結果:
!新課標全國)在崗組樣本數據Uh趴汕懶h… 蘑. 不全相等)的散點圖中,若所有樣本點犧酬 L篆+I 上,則這組樣本數據的樣本相關系數為 o 1 B.0 時
圖四:

百度 OCR API 識別結果:
11分)如圖271日.在△A風中,∠C=45·現妹10.高AD=8.矩形EFPQ的一邊吐在風邊上,1
Tesseract 識別結果:
.’⁻.∴ 、,〉 、、.罐’∣【
r\∪【川 '′ ∣⋃./L 、∥('中.
"pQ的
圖五:

百度 OCR API 識別結果:
B
Tesseract 識別結果:
樂散說, 你是找的全部 你是耕掌希寧觸-都余 但找的主命寧 豬漆能裝有你 就傅 她環東能玻節玻引才 A美未能表有童氣 大她東能裝有四兔
從以上這些對比,我得到以下一些 不一定客觀 的結論:
- 百度的 OCR 系統對噪聲、模糊等有較強的抗干擾性,這一點上要優於 Tesseract
- 百度的 OCR 系統沒有進行布局分析,但 Tesseract 在布局分析上做得比較好
- 百度的 OCR 系統 可能 對 黑底白字 的圖像識別不好
