1 @u4/opencv4nodejs
依赖安装及编译
opencv4nodejs
包提供了丰富de 接口,使得可以在 Node.js 下以更友好的方式使用 opencv4
,但其原始仓库近两年不再更新。@u4/opencv4nodejs
是其 fork 版本,并保持持续更新中。
opencv4nodejs
由于涉及到 Native 编译,依赖安装及编译过程极其复杂。下面为在 windows 11 下编译安装 @u4/opencv4nodejs
的过程,仅供参考。
1.1 安装 @u4/opencv4nodejs
相关依赖
在项目目录下执行命令添加依赖。示例:
yarn add -D node-gyp yarn add @u4/opencv4nodejs
然后下载并全局安装 opencv4
。可从该页面下载:https://opencv.org/releases/
该页面上的相关下载地址实际上是 github 仓库上的 release 资源。
也可以使用包管理安装。使用包管理器安装的命令参考:
# windows: scoop scoop install opencv # windows: chocolatey choco install OpenCV -y -version 4.8.0 # macos: brew brew install opencv
windows 下可以直接使用 IDM 等工具下载后解压安装。例如我这里解压在了 D:\opencv
目录(推荐解压安装至 c:\\tools\\opencv
目录,这是 build-opencv
使用的默认目录)。
1.2 使用 @u4/build-opencv
编译
以下为在 windows 11
下 PowerSHell
中的编译方法参考。
先确保已安装了 MSBuild 工具链。如果安装了 Visual Studio 社区版并选择 C++ 编译下哦昂改名工具链即可。
也可以使用 npm 安装:npm i -g windows-build-tools
。
进入项目目录下,执行如下命令:
# 禁止从源码编译 opencv,使用全局安装的 opencv $ENV:OPENCV4NODEJS_DISABLE_AUTOBUILD=1 # 指定全局安装的 opencv 路径。若安装在了 c:\\tools\\opencv 目录下(默认目录),则无需设置 $ENV:OPENCV_LIB_DIR="D:\opencv\build\x64\vc16\lib" $ENV:OPENCV_BIN_DIR="D:\opencv\build\x64\vc16\bin" $ENV:OPENCV_INCLUDE_DIR="D:\opencv\build\include" # 执行自动编译 yarn build-opencv --nobuild auto # 强制重新编译 # yarn build-opencv --nobuild rebuild
编译成功后,则会产出文件 node_modules/@u4/opencv4nodejs/build/Release/opencv4nodejs.node
。
可以用如下脚本测试其可用性:
const cv = require('@u4/opencv4nodejs'); // load image from file const mat = cv.imread('./path/img.jpg'); // show image cv.imshow('a window name', mat);
2 基于 @u4/opencv4nodejs
的验证码 OCR 识别
2.1 基于 @u4/opencv4nodejs
的滑块匹配验证码
滑块验证码识别是当前各大网站登录页面最为常见的一种。通过使用 @u4/opencv4nodejs
提供的 matchTemplate
方法,可以快速实现滑块验证码的识别。参考以下示例代码:
const cv = require('@u4/opencv4nodejs'); const fs = require('fs'); const sliderImage = fs.readFileSync('./slider.png'); const originalImage = fs.readFileSync('./original.png'); const sliderMat = cv.imdecode(sliderImage); const originalMat = cv.imdecode(originalImage); const matched = sliderMat.matchTemplate(originalMat, cv.TM_CCOEFF_NORMED); const matchedPoints = matched.minMaxLoc(); console.log('x: ', matchedPoints.maxLoc.x, matchedPoints);
2.2 基于 @lzwme/captcha-cv-ocr
的验证码识别
captcha-cv-ocr
模块基于 @u4/opencv4nodejs
和 tesseract.js
封装实现了几种常见的验证码识别实现。我们可以安装并使用它首先简单的实现验证码识别能力。由于 captcha-cv-ocr
近两年未更新,@lzwme/captcha-cv-ocr
是本人基于 captcha-cv-ocr
fork 并做了依赖升级、能力扩展等。
安装:
npm i @lzwme/captcha-ocr
2.2.1 基于 Node.js API 调用的使用
示例:
const { Cvocr, getCodesList } = require("captcha-cv-ocr"); // 获取支持的验证码识别类型列表 const codesList = getCodesList(); console.log('codes:', codesList); async function cvocrTest() { // 获取支持的验证码识别类型列表 const codesList = getCodesList(); console.log('codes:', codesList); const mode = "simplest"; const cvocr = new Cvocr(mode); await cvocr.init([{ num: 1 }]); // 支持文件地址、Base64、Buffer形式 const imgBase64 = `data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAUADwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtNVmn8t5fIluBGGdvJ/fSHHIAPc+n1rlLbXtbt7rTP7Z0+3t7K/m+zxRxEpNCxICeZng+/f1x0rtNVtzp1pJfSXCGytjJxKScBA+ePwNee6f4i0jXNat575w5MoisdOETfI3AEj4GC57DJC/XmprR1SZtGkmtrnZat9tjhA0tEkkJIaWSTMcWPXHOfwqHR9Se+tDDMY0nilaCRwuBlO4Oeh9xTNbns4I4PtUL/YLgMkkzE/uhjgYAJIJyMjFReEovNmvfsJl/soMotyrcA4+fAbnGf1zVKEeT3kc/JFS0Kut6/LpurafYWM0U0k08cc7MN4hDngdOCeT+HStTWtTn0vTJ9Qm82URkEeVIQCScdjxzjtXFarpeu6e2ntdnTLie41KJ/Oy5eSXnYH6fIB2GMV1/iFb5vC1wLeKQ37QBJVWMlOf9ZsyemN+O/TvXR7OklFIil70nchsdR1ODVbe28SW8Mj3isbdkWSQjYMkYZhwQeue3vXolheRfZI/OjnVscCO3ZVx2wPm7Y715d4ZXSx4m06XwqY/LWOVL2VhKAAQPLyWPGW/uc8HPFepxi/8ALX5rTp2Vm/XNVJpPT8jplBJks9nDLEsbplPND49y3P8AM1QubdZrTUFct/o8mxTnJOBkE56ntnriiiipsRLYkjto11Z7dgHhaIuUdVIzv+lTS6XafZf9SORvAPIQ7v4QeAPbp7UUU6YR2KOtWqWNq8sDPjjdG7blbkdc8/rU39l20l4kLhiFAIbPzdW70UVzvc0qbIL3TIreznZXkdM7vLkw46jjJG7H41NY2do9pEzWkGWUE/JRRRFe8zKXwo//2Q==`; // const imgFile = "simplest.jpg"; // 支持文件地址、Base64、Buffer形式 const ans = await cvocr.recognize(imgBase64); console.log("ans:", ans); process.exit(0); } cvocrTest();
2.2.2 基于 http API 的调用使用
@lzwme/captcha-cv-ocr
内置了一个简单的 server 能力,可以调用它提供本地 http 服务调用能力。基于 http server 的使用示例。
命令行下直接启动示例:
# 默认启动 3000 端口 node ./node_modules/@lzwme/captcha-cv-ocr/index.js
通过调用 createServer
方法启动 sever 示例:
const { createServer } = require('@lzwme/captcha-cv-ocr'); createServer({ port: 3000 });
然后即可通过 post
请求的方式使用。示例(基于 fetch API,可在 Node.js 环境或 chrome 控制台直接调用):
async function httpOcrTest() { const body = { mode: 'simplest', // 验证码图片 base64: 'data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAUADwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtNVmn8t5fIluBGGdvJ/fSHHIAPc+n1rlLbXtbt7rTP7Z0+3t7K/m+zxRxEpNCxICeZng+/f1x0rtNVtzp1pJfSXCGytjJxKScBA+ePwNee6f4i0jXNat575w5MoisdOETfI3AEj4GC57DJC/XmprR1SZtGkmtrnZat9tjhA0tEkkJIaWSTMcWPXHOfwqHR9Se+tDDMY0nilaCRwuBlO4Oeh9xTNbns4I4PtUL/YLgMkkzE/uhjgYAJIJyMjFReEovNmvfsJl/soMotyrcA4+fAbnGf1zVKEeT3kc/JFS0Kut6/LpurafYWM0U0k08cc7MN4hDngdOCeT+HStTWtTn0vTJ9Qm82URkEeVIQCScdjxzjtXFarpeu6e2ntdnTLie41KJ/Oy5eSXnYH6fIB2GMV1/iFb5vC1wLeKQ37QBJVWMlOf9ZsyemN+O/TvXR7OklFIil70nchsdR1ODVbe28SW8Mj3isbdkWSQjYMkYZhwQeue3vXolheRfZI/OjnVscCO3ZVx2wPm7Y715d4ZXSx4m06XwqY/LWOVL2VhKAAQPLyWPGW/uc8HPFepxi/8ALX5rTp2Vm/XNVJpPT8jplBJks9nDLEsbplPND49y3P8AM1QubdZrTUFct/o8mxTnJOBkE56ntnriiiipsRLYkjto11Z7dgHhaIuUdVIzv+lTS6XafZf9SORvAPIQ7v4QeAPbp7UUU6YR2KOtWqWNq8sDPjjdG7blbkdc8/rU39l20l4kLhiFAIbPzdW70UVzvc0qbIL3TIreznZXkdM7vLkw46jjJG7H41NY2do9pEzWkGWUE/JRRRFe8zKXwo//2Q==', // slide_match 模式的底图 originalBase64: '', }; const result = await fetch('http://localhost:3000/ocr', { method: 'post', body: JSON.stringify(body), headers: { 'Content-Type': 'application/json' } }).then(d => d.json()); console.log(result); }
3 扩展:基于 ocr_api_server
快速搭建基于 http API 的验证码识别服务
ddddocr 是一个基于 python 和 opencv 实现的 OCR 通用验证码识别 SDK,而 ocr_api_server | github 是基于 ddddocr 封装的 API 服务实现。
基于源码启动示例:
# 拉取代码 git clone --depth 1 git@gitee.com:fkgeek/ocr_api_server.git # 安装依赖 pip install -r requirements.txt -i https://pypi.douban.com/simple # 运行 可选参数如下 # --port 9898 指定端口,默认为9898 # --ocr 开启ocr模块 默认开启 # --old 只有ocr模块开启的情况下生效 默认不开启 # --det 开启目标检测模式 # 同时开启ocr模块以及目标检测模块 python ocr_server.py --port 9898 --ocr --det
基于源码的方式可能会因为 python 环境等因素出现各种问题而失败。基于 docker 的方式可以快速启动一个本地服务。docker hub 上有许多 ocr_api_server
的镜像,可以搜索并选择其一安装启动,基本上只需映射 9898
端口出来即可。
API 调用测试示例:
await fetch('http://localhost:9898/ocr/b64/json', { method: 'post', mode: "cors", // no-cors, *cors, same-origin cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached credentials: "omit", // include, *same-origin, omit body: `/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAUADwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtNVmn8t5fIluBGGdvJ/fSHHIAPc+n1rlLbXtbt7rTP7Z0+3t7K/m+zxRxEpNCxICeZng+/f1x0rtNVtzp1pJfSXCGytjJxKScBA+ePwNee6f4i0jXNat575w5MoisdOETfI3AEj4GC57DJC/XmprR1SZtGkmtrnZat9tjhA0tEkkJIaWSTMcWPXHOfwqHR9Se+tDDMY0nilaCRwuBlO4Oeh9xTNbns4I4PtUL/YLgMkkzE/uhjgYAJIJyMjFReEovNmvfsJl/soMotyrcA4+fAbnGf1zVKEeT3kc/JFS0Kut6/LpurafYWM0U0k08cc7MN4hDngdOCeT+HStTWtTn0vTJ9Qm82URkEeVIQCScdjxzjtXFarpeu6e2ntdnTLie41KJ/Oy5eSXnYH6fIB2GMV1/iFb5vC1wLeKQ37QBJVWMlOf9ZsyemN+O/TvXR7OklFIil70nchsdR1ODVbe28SW8Mj3isbdkWSQjYMkYZhwQeue3vXolheRfZI/OjnVscCO3ZVx2wPm7Y715d4ZXSx4m06XwqY/LWOVL2VhKAAQPLyWPGW/uc8HPFepxi/8ALX5rTp2Vm/XNVJpPT8jplBJks9nDLEsbplPND49y3P8AM1QubdZrTUFct/o8mxTnJOBkE56ntnriiiipsRLYkjto11Z7dgHhaIuUdVIzv+lTS6XafZf9SORvAPIQ7v4QeAPbp7UUU6YR2KOtWqWNq8sDPjjdG7blbkdc8/rU39l20l4kLhiFAIbPzdW70UVzvc0qbIL3TIreznZXkdM7vLkw46jjJG7H41NY2do9pEzWkGWUE/JRRRFe8zKXwo//2Q==`, headers: { token: 'e939b7e5-5dbe-41c2-81bb-393a0de75425' } }).then(d => d.json())
若希望允许在浏览器中跨域调用,则可以增加一个前置 nginx,配置 htttps 证书和 CORS header 头。nginx cors 配置参考:
# * 星号代表任意跨源请求都支持 # add_header Access-Control-Allow-Origin '*'; add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Credentials "true"; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'Content-Type,token,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,XRequested-With'; if ($request_method = 'OPTIONS') { return 200; }
4 总结与参考
本文主要介绍了 @u4/opencv4nodejs
在 windows 下的安装与编译方法,并介绍了基于 @u4/opencv4nodejs
和 tesseract.js
封装实现验证码识别的开源项目 captcha-cv-ocr
。并继续介绍了本人基于captcha-cv-ocr
扩展实现的 @lzwme/captcha-cv-ocr
包,通过使用 @lzwme/captcha-cv-ocr
可以在 Node.js 应用中快速的实现验证码识别能力,同时也可以简单快速的启动一个 http server 以提供 http 请求方式的验证码识别服务。
- https://github.com/renxia/captcha-cv-ocr
- tesseract.js
- @u4/opencv4nodejs
- opencv4nodejs API
- OpenCV 文档
- sharp API
其它验证码识别类的相关仓库参考:
- https://github.com/PillarsZhang/captcha-cv-ocr
- ocr_api_server | github ocr_api_server | gitee
- https://github.com/sml2h3/ddddocr