opencv4nodejs

Nodejs 绑定到 OpenCV 3 和 OpenCV 4。(Nodejs bindings to OpenCV 3 and OpenCV 4)

Github星跟蹤圖

opencv4nodejs

opencv4nodejs 允许您在 nodejs 中使用原生 OpenCV 库。除了同步 API 之外,该包还提供了异步API,允许您构建非阻塞和多线程的计算机视觉任务。opencv4nodejs 支持 OpenCV 3 和 OpenCV 4。

本项目的最终目标是提供到 OpenCV 和 OpenCV-contrib 模块的 API 的完整的 nodejs 绑定集合。要获得当前实现绑定的概述,请查看此包的类型声明。此外,我们高度赞赏所作的贡献。如果您想添加缺少的绑定,请查看贡献指南

示例

参阅 示例 for implementation.

安装

npm install --save opencv4nodej

原生 node 模块是通过 node-gyp 构建的,默认情况下已随 npm 一起提供。 但是,node-gyp 要求您安装 python。 如果您遇到 node-gyp 的特定问题,请首先查看node-gyp 的已知问题。

重要说明:node-gyp 无法正确处理空格,因此请确保项目目录的路径中不包含空格。 在“C:\Program Files\some_dir”或类似目录下安装 opencv4nodejs 将无法正常工作,并且将失败并显示:"fatal error C1083: Cannot open include file: 'opencv2/core.hpp'"!**

在 Windows 上,您还将需要 Windows Build Tools 来编译 OpenCV 和 opencv4nodejs。 如果您没有安装 Visual Studio 或 Windows 生成工具,则可以轻松安装 VS2015 生成工具:

npm install --global windows-build-tools

手动安装 OpenCV

单独设置 OpenCV 需要设置一个环境变量,以防止自动构建脚本运行

# linux and osx:
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
# on windows:
set OPENCV4NODEJS_DISABLE_AUTOBUILD=1

Windows

您可以手动或通过 Chocolatey 包管理器安装 OpenCV 3 或 OpenCV 4 的任何版本

# to install OpenCV 4.1.0
choco install OpenCV -y -version 4.1.0

注意,这将不包含 contrib 模块。要在 windows 下安装带有 contrib 模块的 OpenCV,必须从源代码构建库,或者可以使用自动构建脚本。

在通过自己的 OpenCV 安装来安装 opencv4nodejs 之前,需要公开以下环境变量:

  • OPENCV_INCLUDE_DIR 指向带有包含头文件的子文件夹 opencv2 的目录
  • OPENCV_LIB_DIR 指向包含 OpenCV.lib 文件的 lib 目录

另外,您还需要将OpenCV二进制文件添加到系统路径:

  • 添加一个环境变量 OPENCV_BIN_DIR 指向包含 OpenCV.dll 文件的二进制目录
  • 附加 ;%OPENCV_BIN_DIR%; 到您的系统路径变量

注意:对环境进行更改后,重新启动当前的控制台会话。

MacOSX

在 OSX 下,我们可以简单地通过 brew 安装 OpenCV:

brew update
brew install opencv@4
brew link --force opencv@4

Linux

在 Linux 下,我们必须手动或使用自动构建脚本从源代码构建 OpenCV。

通过自动构建脚本安装OpenCV

自动构建脚本以 opencv-build npm 软件包的形式出现,该软件包将在安装opencv4nodejs时默认运行。该脚本要求您安装git和最新版本的cmake。

自动构建标志

您可以使用 OPENCV4NODEJS_AUTOBUILD_FLAGS= 自定义自动构建标志。标志必须以空格分隔。

这是高级自定义,您应该了解有关 OpenCV 编译标志的知识。默认情况下添加的标志在此处列出。

安装特定版本的OpenCV

您可以通过设置环境变量来通过脚本指定要安装的 OpenCV 版本:export OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION=4.1.0

仅安装 OpenCV 模块的子集

如果只想构建 OpenCV 模块的子集,则可以通过 OPENCV4NODEJS_AUTOBUILD_FLAGS 环境变量传递 -DBUILD_LIST cmake 标志。例如,export OPENCV4NODEJS_AUTOBUILD_FLAGS =-DBUILD_LIST=dnn 将仅构建 dnn 所需的模块,并减少 OpenCV 软件包的大小和编译时间。

Docker 的用法

opencv-express -- 使用 express.js 和 docker 的 opencv4nodejs 示例

或者简单地从 justadudewhohacks/opencv-nodejs 中获取已全局安装 opencv4nodejs 的 opencv-3.2 + contrib-3.2:

FROM justadudewhohacks/opencv-nodejs

注意:前面提到的 Docker 映像已经全局安装了 opencv4nodejs。为了防止在 npm 安装过程中发生构建错误,您的 package.json 不应包含 opencv4nodejs,而应通过绝对路径或将 NODE_PATH 环境变量设置为 /usr/lib/node_modules 中的 /usr/lib /node_modules 来包含/请求全局软件包。您的 Dockerfile 并像往常一样需要软件包。

可以在以下位置找到不同的 OpenCV 3.x 基本映像:

https://hub.docker.com/r/justadudewhohacks/

与 Electron 一起使用

opencv-electron -- electron opencv4nodejs 的例子

将以下脚本添加到 package.json 中

"electron-rebuild": "electron-rebuild -w opencv4nodejs"

运行脚本:

$ npm run electron-rebuild

在应用程序中 require 它。

const cv = require('opencv4nodejs');

NW.js 的用法

任何本机模块,包括 opencv4nodejs,都必须重新编译才能与 NW.js 一起使用。关于如何做到这一点的说明可以在 NW.js 文档的 Use Native Modules 部分找到。

重新编译后,就可以像往常一样安装和需要模块了

const cv = require('opencv4nodejs');

快速入门

恕删略。请参考自述文件。

(First edition: vz edited at 2019.09.22)

概覽

名稱與所有者justadudewhohacks/opencv4nodejs
主編程語言C++
編程語言Python (語言數: 7)
平台Linux, Mac, Windows
許可證MIT License
發布數39
最新版本名稱5.6.0 (發布於 )
第一版名稱2.38.0 (發布於 )
創建於2017-08-20 15:22:13
推送於2023-04-18 20:32:54
最后一次提交2022-06-21 21:51:38
星數4.9k
關注者數136
派生數806
提交數1.1k
已啟用問題?
問題數652
打開的問題數285
拉請求數196
打開的拉請求數9
關閉的拉請求數21
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?

opencv4nodejs

opencv4nodejs

Build Status
Build status
Coverage
npm download
node version
Slack

opencv4nodejs allows you to use the native OpenCV library in nodejs. Besides a synchronous API the package provides an asynchronous API, which allows you to build non-blocking and multithreaded computer vision tasks. opencv4nodejs supports OpenCV 3 and OpenCV 4.

The ultimate goal of this project is to provide a comprehensive collection of nodejs bindings to the API of OpenCV and the OpenCV-contrib modules. To get an overview of the currently implemented bindings, have a look at the type declarations of this package. Furthermore, contribution is highly appreciated. If you want to add missing bindings check out the contribution guide.

Examples

See examples for implementation.

Face Detection

face0
face1

Face Recognition with the OpenCV face module

Check out Node.js + OpenCV for Face Recognition.

facerec

Face Landmarks with the OpenCV face module

facelandmarks

Face Recognition with face-recognition.js

Check out Node.js + face-recognition.js : Simple and Robust Face Recognition using Deep Learning.

IMAGE ALT TEXT

Hand Gesture Recognition

Check out Simple Hand Gesture Recognition using OpenCV and JavaScript.

gesture-rec_sm

Object Recognition with Deep Neural Networks

Check out Node.js meets OpenCV’s Deep Neural Networks — Fun with Tensorflow and Caffe.

Tensorflow Inception

husky
car
banana

Single Shot Multibox Detector with COCO

dishes-detection
car-detection

Machine Learning

Check out Machine Learning with OpenCV and JavaScript: Recognizing Handwritten Letters using HOG and SVM.

resulttable

Object Tracking

trackbgsubtract
trackbycolor

Feature Matching

matchsift

Image Histogram

plotbgr
plotgray

Boiler plate for combination of opencv4nodejs, express and websockets.

opencv4nodejs-express-websockets - Boilerplate express app for getting started on opencv with nodejs and to live stream the video through websockets.

Automating lights by people detection through classifier

Check out Automating lights with Computer Vision & NodeJS.

user-presence

How to install

npm install --save opencv4nodejs

Native node modules are built via node-gyp, which already comes with npm by default. However, node-gyp requires you to have python installed. If you are running into node-gyp specific issues have a look at known issues with node-gyp first.

Important note: node-gyp won't handle whitespaces properly, thus make sure, that the path to your project directory does not contain any whitespaces. Installing opencv4nodejs under "C:\Program Files\some_dir" or similar will not work and will fail with: "fatal error C1083: Cannot open include file: 'opencv2/core.hpp'"!**

On Windows you will furthermore need Windows Build Tools to compile OpenCV and opencv4nodejs. If you don't have Visual Studio or Windows Build Tools installed, you can easily install the VS2015 build tools:

npm install --global windows-build-tools

Installing OpenCV Manually

Setting up OpenCV on your own will require you to set an environment variable to prevent the auto build script to run:

# linux and osx:
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
# on windows:
set OPENCV4NODEJS_DISABLE_AUTOBUILD=1

Windows

You can install any of the OpenCV 3 or OpenCV 4 releases manually or via the Chocolatey package manager:

# to install OpenCV 4.1.0
choco install OpenCV -y -version 4.1.0

Note, this will come without contrib modules. To install OpenCV under windows with contrib modules you have to build the library from source or you can use the auto build script.

Before installing opencv4nodejs with an own installation of OpenCV you need to expose the following environment variables:

  • OPENCV_INCLUDE_DIR pointing to the directory with the subfolder opencv2 containing the header files
  • OPENCV_LIB_DIR pointing to the lib directory containing the OpenCV .lib files

Also you will need to add the OpenCV binaries to your system path:

  • add an environment variable OPENCV_BIN_DIR pointing to the binary directory containing the OpenCV .dll files
  • append ;%OPENCV_BIN_DIR%; to your system path variable

Note: Restart your current console session after making changes to your environment.

MacOSX

Under OSX we can simply install OpenCV via brew:

brew update
brew install opencv@4
brew link --force opencv@4

Linux

Under Linux we have to build OpenCV from source manually or using the auto build script.

Installing OpenCV via Auto Build Script

The auto build script comes in form of the opencv-build npm package, which will run by default when installing opencv4nodejs. The script requires you to have git and a recent version of cmake installed.

Auto Build Flags

You can customize the autobuild flags using OPENCV4NODEJS_AUTOBUILD_FLAGS=.
Flags must be space-separated.

This is an advanced customization and you should have knowledge regarding the OpenCV compilation flags. Flags added by default are listed here.

Installing a Specific Version of OpenCV

You can specify the Version of OpenCV you want to install via the script by setting an environment variable:
export OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION=4.1.0

Installing only a Subset of OpenCV modules

If you only want to build a subset of the OpenCV modules you can pass the -DBUILD_LIST cmake flag via the OPENCV4NODEJS_AUTOBUILD_FLAGS environment variable. For example export OPENCV4NODEJS_AUTOBUILD_FLAGS=-DBUILD_LIST=dnn will build only modules required for dnn and reduces the size and compilation time of the OpenCV package.

Configuring Environments via package.json

It's possible to specify build environment variables by inserting them into the package.json as follows:

{
  "name": "my-project",
  "version": "0.0.0",
  "dependencies": {
    "opencv4nodejs": "^X.X.X"
  },
  "opencv4nodejs": {
    "disableAutoBuild": 1,
    "opencvIncludeDir": "C:\\tools\\opencv\\build\\include",
    "opencvLibDir": "C:\\tools\\opencv\\build\\x64\\vc14\\lib",
    "opencvBinDir": "C:\\tools\\opencv\\build\\x64\\vc14\\bin"
  }
}

The following environment variables can be passed:

  • autoBuildBuildCuda
  • autoBuildFlags
  • autoBuildOpencvVersion
  • autoBuildWithoutContrib
  • disableAutoBuild
  • opencvIncludeDir
  • opencvLibDir
  • opencvBinDir

Usage with Docker

opencv-express - example for opencv4nodejs with express.js and docker

Or simply pull from justadudewhohacks/opencv-nodejs for opencv-3.2 + contrib-3.2 with opencv4nodejs globally installed:

FROM justadudewhohacks/opencv-nodejs

Note: The aforementioned Docker image already has opencv4nodejs installed globally. In order to prevent build errors during an npm install, your package.json should not include opencv4nodejs, and instead should include/require the global package either by requiring it by absolute path or setting the NODE_PATH environment variable to /usr/lib/node_modules in your Dockerfile and requiring the package as you normally would.

Different OpenCV 3.x base images can be found here: https://hub.docker.com/r/justadudewhohacks/.

Usage with Electron

opencv-electron - example for opencv4nodejs with electron

Add the following script to your package.json:

"electron-rebuild": "electron-rebuild -w opencv4nodejs"

Run the script:

$ npm run electron-rebuild

Require it in the application:

const cv = require('opencv4nodejs');

Usage with NW.js

Any native modules, including opencv4nodejs, must be recompiled to be used with NW.js. Instructions on how to do this are available in the Use Native Modules section of the the NW.js documentation.

Once recompiled, the module can be installed and required as usual:

const cv = require('opencv4nodejs');

Quick Start

const cv = require('opencv4nodejs');

Initializing Mat (image matrix), Vec, Point

const rows = 100; // height
const cols = 100; // width

// empty Mat
const emptyMat = new cv.Mat(rows, cols, cv.CV_8UC3);

// fill the Mat with default value
const whiteMat = new cv.Mat(rows, cols, cv.CV_8UC1, 255);
const blueMat = new cv.Mat(rows, cols, cv.CV_8UC3, [255, 0, 0]);

// from array (3x3 Matrix, 3 channels)
const matData = [
  [[255, 0, 0], [255, 0, 0], [255, 0, 0]],
  [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
  [[255, 0, 0], [255, 0, 0], [255, 0, 0]]
];
const matFromArray = new cv.Mat(matData, cv.CV_8UC3);

// from node buffer
const charData = [255, 0, ...];
const matFromArray = new cv.Mat(Buffer.from(charData), rows, cols, cv.CV_8UC3);

// Point
const pt2 = new cv.Point(100, 100);
const pt3 = new cv.Point(100, 100, 0.5);

// Vector
const vec2 = new cv.Vec(100, 100);
const vec3 = new cv.Vec(100, 100, 0.5);
const vec4 = new cv.Vec(100, 100, 0.5, 0.5);

Mat and Vec operations

const mat0 = new cv.Mat(...);
const mat1 = new cv.Mat(...);

// arithmetic operations for Mats and Vecs
const matMultipliedByScalar = mat0.mul(0.5);  // scalar multiplication
const matDividedByScalar = mat0.div(2);       // scalar division
const mat0PlusMat1 = mat0.add(mat1);          // addition
const mat0MinusMat1 = mat0.sub(mat1);         // subtraction
const mat0MulMat1 = mat0.hMul(mat1);          // elementwise multiplication
const mat0DivMat1 = mat0.hDiv(mat1);          // elementwise division

// logical operations Mat only
const mat0AndMat1 = mat0.and(mat1);
const mat0OrMat1 = mat0.or(mat1);
const mat0bwAndMat1 = mat0.bitwiseAnd(mat1);
const mat0bwOrMat1 = mat0.bitwiseOr(mat1);
const mat0bwXorMat1 = mat0.bitwiseXor(mat1);
const mat0bwNot = mat0.bitwiseNot();

Accessing Mat data

const matBGR = new cv.Mat(..., cv.CV_8UC3);
const matGray = new cv.Mat(..., cv.CV_8UC1);

// get pixel value as vector or number value
const vec3 = matBGR.at(200, 100);
const grayVal = matGray.at(200, 100);

// get raw pixel value as array
const [b, g, r] = matBGR.atRaw(200, 100);

// set single pixel values
matBGR.set(50, 50, [255, 0, 0]);
matBGR.set(50, 50, new Vec(255, 0, 0));
matGray.set(50, 50, 255);

// get a 25x25 sub region of the Mat at offset (50, 50)
const width = 25;
const height = 25;
const region = matBGR.getRegion(new cv.Rect(50, 50, width, height));

// get a node buffer with raw Mat data
const matAsBuffer = matBGR.getData();

// get entire Mat data as JS array
const matAsArray = matBGR.getDataAsArray();

IO

// load image from file
const mat = cv.imread('./path/img.jpg');
cv.imreadAsync('./path/img.jpg', (err, mat) => {
  ...
})

// save image
cv.imwrite('./path/img.png', mat);
cv.imwriteAsync('./path/img.jpg', mat,(err) => {
  ...
})

// show image
cv.imshow('a window name', mat);
cv.waitKey();

// load base64 encoded image
const base64text='data:image/png;base64,R0lGO..';//Base64 encoded string
const base64data =base64text.replace('data:image/jpeg;base64','')
                            .replace('data:image/png;base64','');//Strip image type prefix
const buffer = Buffer.from(base64data,'base64');
const image = cv.imdecode(buffer); //Image is now represented as Mat

// convert Mat to base64 encoded jpg image
const outBase64 =  cv.imencode('.jpg', croppedImage).toString('base64'); // Perform base64 encoding
const htmlImg='<img src=data:image/jpeg;base64,'+outBase64 + '>'; //Create insert into HTML compatible <img> tag

// open capture from webcam
const devicePort = 0;
const wCap = new cv.VideoCapture(devicePort);

// open video capture
const vCap = new cv.VideoCapture('./path/video.mp4');

// read frames from capture
const frame = vCap.read();
vCap.readAsync((err, frame) => {
  ...
});

// loop through the capture
const delay = 10;
let done = false;
while (!done) {
  let frame = vCap.read();
  // loop back to start on end of stream reached
  if (frame.empty) {
    vCap.reset();
    frame = vCap.read();
  }

  // ...

  const key = cv.waitKey(delay);
  done = key !== 255;
}

Useful Mat methods

const matBGR = new cv.Mat(..., cv.CV_8UC3);

// convert types
const matSignedInt = matBGR.convertTo(cv.CV_32SC3);
const matDoublePrecision = matBGR.convertTo(cv.CV_64FC3);

// convert color space
const matGray = matBGR.bgrToGray();
const matHSV = matBGR.cvtColor(cv.COLOR_BGR2HSV);
const matLab = matBGR.cvtColor(cv.COLOR_BGR2Lab);

// resize
const matHalfSize = matBGR.rescale(0.5);
const mat100x100 = matBGR.resize(100, 100);
const matMaxDimIs100 = matBGR.resizeToMax(100);

// extract channels and create Mat from channels
const [matB, matG, matR] = matBGR.splitChannels();
const matRGB = new cv.Mat([matR, matB, matG]);

Drawing a Mat into HTML Canvas

const img = ...

// convert your image to rgba color space
const matRGBA = img.channels === 1
  ? img.cvtColor(cv.COLOR_GRAY2RGBA)
  : img.cvtColor(cv.COLOR_BGR2RGBA);

// create new ImageData from raw mat data
const imgData = new ImageData(
  new Uint8ClampedArray(matRGBA.getData()),
  img.cols,
  img.rows
);

// set canvas dimensions
const canvas = document.getElementById('myCanvas');
canvas.height = img.rows;
canvas.width = img.cols;

// set image data
const ctx = canvas.getContext('2d');
ctx.putImageData(imgData, 0, 0);

Method Interface

OpenCV method interface from official docs or src:

void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);

translates to:

const src = new cv.Mat(...);
// invoke with required arguments
const dst0 = src.gaussianBlur(new cv.Size(5, 5), 1.2);
// with optional paramaters
const dst2 = src.gaussianBlur(new cv.Size(5, 5), 1.2, 0.8, cv.BORDER_REFLECT);
// or pass specific optional parameters
const optionalArgs = {
  borderType: cv.BORDER_CONSTANT
};
const dst2 = src.gaussianBlur(new cv.Size(5, 5), 1.2, optionalArgs);

Async API

The async API can be consumed by passing a callback as the last argument of the function call. By default, if an async method is called without passing a callback, the function call will yield a Promise.

Async Face Detection

const classifier = new cv.CascadeClassifier(cv.HAAR_FRONTALFACE_ALT2);

// by nesting callbacks
cv.imreadAsync('./faceimg.jpg', (err, img) => {
  if (err) { return console.error(err); }

  const grayImg = img.bgrToGray();
  classifier.detectMultiScaleAsync(grayImg, (err, res) => {
    if (err) { return console.error(err); }

    const { objects, numDetections } = res;
    ...
  });
});

// via Promise
cv.imreadAsync('./faceimg.jpg')
  .then(img =>
    img.bgrToGrayAsync()
      .then(grayImg => classifier.detectMultiScaleAsync(grayImg))
      .then((res) => {
        const { objects, numDetections } = res;
        ...
      })
  )
  .catch(err => console.error(err));

// using async await
try {
  const img = await cv.imreadAsync('./faceimg.jpg');
  const grayImg = await img.bgrToGrayAsync();
  const { objects, numDetections } = await classifier.detectMultiScaleAsync(grayImg);
  ...
} catch (err) {
  console.error(err);
}

With TypeScript

import * as cv from 'opencv4nodejs'

Check out the TypeScript examples.

External Memory Tracking (v4.0.0)

Since version 4.0.0 was released, external memory tracking has been enabled by default. Simply put, the memory allocated for Matrices (cv.Mat) will be manually reported to the node process. This solves the issue of inconsistent Garbage Collection, which could have resulted in spiking memory usage of the node process eventually leading to overflowing the RAM of your system, prior to version 4.0.0.

Note, that in doubt this feature can be disabled by setting an environment variable OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING before requiring the module:

export OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING=1 // linux
set OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING=1 // windows

Or directly in your code:

process.env.OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING = 1
const cv = require('opencv4nodejs')
去到頂部