共计 10099 个字符,预计需要花费 26 分钟才能阅读完成。
提醒:本文最后更新于2025-07-07 14:30,文中所关联的信息可能已发生改变,请知悉!
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