用node.js實現驗證碼簡單識別

概述

在驗證碼識別上,node.js其實也只是打醬油的角色,由於已經有成熟的工具作這個事情,而node只須要作調度就好了。node

所需工具

那麼介紹一下這些工具吧git

  • Tesseract 開源的 OCR 識別工具,目前由 Google 維護,支持中文,默認的識別率很低哈,特別是中文,可是能夠本身提供樣本,訓練提升識別率。github

  • graphicsmagick 很是實用的圖像處理工具,下面會講到用途。工具

Tesseract的使用

如下操做均在 Mac 環境下,Windows 其實也差很少,請自行區分 :-)。ui

安裝

brew install tesseract --all-languagesspa

使用

tesseract 1.jpg -psm 7 r.net

-psm 7 表示識別的內容是文本,r是保存識別內容的文件。code

而後你會發現識別結果很坑.. (⊙o⊙)..
圖片

提升識別率

之因此是這樣,是由於驗證碼上有無關的圖像干擾,例如噪點什麼的,理論上去掉了干擾的元素,識別率就會極大的提升。
用閾值處理圖片是個很方便的辦法,在Photoshop中能夠模擬這種操做
資源

再試一次

這裏配置爲55%的閾值,再來一次。

成功了!( ⊙ o ⊙ )!雖然多了個空格,可是已經完整識別出來了。

用node.js實現

最後在node.js中整合上面的操做,其中圖像處理用 graphicsmagick 代替。
直接上源碼吧,裏面用到了 tesseractgraphicsmagicknode.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 訓練,提升相近字符的識別率。

資源

本文同時發佈在 think2011的博客 2016-01-31 17:49:08

相關文章
相關標籤/搜索