製作一個Node命令列影象識別工具
從 0 開始製作一個 NodeJS 命令列驗證碼識別工具。實現如下效果。

初始化專案
# 建立 recognition 專案 mkdir recognition cd recognition npm init -y # 安裝主依賴 yarn add images tesseract.js # 安裝工具依賴 yarn add chalk yargs # 可選依賴 yarn add socks5-http-client 複製程式碼
依賴說明
-
tesseract.js :純 JS 實現的 OCR(光學字元識別)工具,用於影象內容識別
-
chalk :讓命令列內容樣式好看
-
yargs :命令列引數解析器
-
socks5-http-client :SOCKS v5,用於設定代理,在需要拉取某些不能直接訪問的資源時使用, request proxy 例子
專案準備
新建 cli.js
通常命令列工具入口名字為 cli.js
,我們新建一個 cli.js
檔案,並在開頭寫上:
#!/usr/bin/env node 複製程式碼
這樣,我們告訴 *nix 系統,JavaScript/">JavaScript 檔案的直譯器應該是 /usr/bin/env node
,它查詢本地安裝的 node
。
配置 bin
// package.json { "bin": { "reg": "./cli.js" } } 複製程式碼
這樣配置完成後,別人 npm install -g @chenng/recognition
的包,就可以直接通過命令列運行了:
reg --url=https://static.chenng.cn/imgs/test_img.png 複製程式碼
link 本地開發
我們如何能夠在本地可以使用 rec
命令呢?只需要把本專案 link 即可:
yarn link 複製程式碼
核心邏輯
主要邏輯在 cli.js
和 recognize.js
中。這裡有幾個注意點:
encoding: null
const Tesseract = require('tesseract.js'); const images = require('images'); const requset = require('request'); const fs = require('fs'); const { promisify } = require('util'); const chalk = require('chalk'); const writeFile = promisify(fs.writeFile); const rp = promisify(requset); class Recognize { constructor(url) { Recognize.downloadDir = `${__dirname}/dist/`; Recognize.downloadFile = `${__dirname}/dist/temp.png`; this.url = url; this.start(); } async start() { const data = await this.downloadImg(); await writeFile(Recognize.downloadFile, data); this.recognize(); const result = await Tesseract.recognize(Recognize.downloadFile, { lang: 'eng', tessedit_char_blacklist: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', }); console.log(` 識別成功! 識別結果為:${chalk.green(result.text)} `); } async downloadImg() { if (!fs.existsSync(Recognize.downloadDir)) { fs.mkdirSync(Recognize.downloadDir); console.log(`建立了 ${Recognize.downloadDir} 資料夾`); } const res = await rp({ url: this.url, method: 'GET', encoding: null, }); return res.body; } recognize() { // 放大圖片,並覆蓋原始檔 images(Recognize.downloadFile) .size(400) .save(Recognize.downloadFile); } } module.exports = Recognize; 複製程式碼
具體可以檢視原始碼倉庫: github.com/ringcrl/rec…