在驗證碼識別上,node.js
其實也只是打醬油的角色,由於已經有成熟的工具作這個事情,而node
只須要作調度就好了。node
那麼介紹一下這些工具吧git
Tesseract
開源的 OCR
識別工具,目前由 Google
維護,支持中文,默認的識別率很低哈,特別是中文,可是能夠本身提供樣本,訓練提升識別率。github
graphicsmagick
很是實用的圖像處理工具,下面會講到用途。工具
如下操做均在 Mac 環境下,Windows 其實也差很少,請自行區分 :-)。ui
brew install tesseract --all-languages
spa
tesseract 1.jpg -psm 7 r
.net
-psm 7
表示識別的內容是文本,r
是保存識別內容的文件。code
而後你會發現識別結果很坑.. (⊙o⊙)..圖片
之因此是這樣,是由於驗證碼上有無關的圖像干擾,例如噪點什麼的,理論上去掉了干擾的元素,識別率就會極大的提升。
用閾值處理圖片是個很方便的辦法,在Photoshop中能夠模擬這種操做
。資源
這裏配置爲55%的閾值,再來一次。
成功了!( ⊙ o ⊙ )!雖然多了個空格,可是已經完整識別出來了。
最後在node.js
中整合上面的操做,其中圖像處理用 graphicsmagick
代替。
直接上源碼吧,裏面用到了 tesseract
和 graphicsmagick
在node.js
中對應的包裝。
var fs = require('fs'); var tesseract = require('node-tesseract'); var gm = require('gm'); processImg('1.jpg', 'test_1.jpg') .then(recognizer) .then(text => { console.log(`識別結果:${text}`); }) .catch((err)=> { console.error(`識別失敗:${err}`); }); /** * 處理圖片爲閾值圖片 * @param imgPath * @param newPath * @param [thresholdVal=55] 默認閾值 * @returns {Promise} */ function processImg (imgPath, newPath, thresholdVal) { return new Promise((resolve, reject) => { gm(imgPath) .threshold(thresholdVal || 55) .write(newPath, (err)=> { if (err) return reject(err); resolve(newPath); }); }); } /** * 識別圖片 * @param imgPath * @param options tesseract options * @returns {Promise} */ function recognizer (imgPath, options) { options = Object.assign({psm: 7}, options); return new Promise((resolve, reject) => { tesseract .process(imgPath, options, (err, text) => { if (err) return reject(err); resolve(text.replace(/[\r\n\s]/gm, '')); }); }); }
寫完以後才發現示例中的驗證碼的第一個字符實際上是 G,而不是識別出來的C。
默認樣本對相近字符識別仍是挺低的,能夠搜索 tesseract 訓練
,提升相近字符的識別率。
node-tesseract tesseract的node包裝
gm graphicsmagick的node包裝
node-ocr-demo 還作了一個 demo 放在 github 上了
本文同時發佈在 think2011的博客 2016-01-31 17:49:08