opencv4nodejs-prebuilt
Advanced tools
Comparing version 5.3.0-1 to 5.3.0-2
const opencvBuild = require(`@nut-tree/opencv-build-${process.platform}`) | ||
const { resolvePath } = require('../lib/commons') | ||
const fs = require('fs') | ||
const { basename } = require("path"); | ||
@@ -26,8 +27,20 @@ const libDir = resolvePath(opencvBuild.opencvLibDir); | ||
// linkLib produces linker flags for GNU ld and BSD ld | ||
// It generates linker flags based on the libPath, which make dealing with version numbers in lib names easier | ||
// On Linux, it passes the full path via -l:/path/to/lib which links against the given file | ||
// On macOS it strips the *.dylib suffix and the lib prefix and passes the result to via -l | ||
// This results in e.g. -lopencv_world.4.1 | ||
const linkLib = (lib) => { | ||
if (opencvBuild.isOSX()) { | ||
return `-l${basename(lib.libPath, ".dylib").replace("lib", "")}`; | ||
} else { | ||
return `-l:${basename(lib.libPath)}`; | ||
} | ||
} | ||
const libs = opencvBuild.isWin() | ||
? libsFoundInDir.map(lib => resolvePath(lib.libPath)) | ||
: // dynamically link libs if not on windows | ||
["-L" + libDir] | ||
.concat(libsFoundInDir.map(lib => "-lopencv_" + lib.opencvModule)) | ||
.concat("-Wl,-rpath," + libDir); | ||
// dynamically link libs if not on windows | ||
: ['-L' + libDir] | ||
.concat(libsFoundInDir.map(lib => linkLib(lib))) | ||
.concat('-Wl,-rpath,' + libDir) | ||
@@ -34,0 +47,0 @@ module.exports = { |
@@ -17,15 +17,17 @@ const { execSync } = require("child_process"); | ||
if (!isX64) { | ||
console.log("Unsupported platform, only x64 is supported."); | ||
process.exit(-1); | ||
} | ||
if (!process.env["OPENCV4NODEJS_PREBUILT_SKIP_DEPENDENCIES"]) { | ||
if (!isX64) { | ||
console.log("Unsupported platform, only x64 is supported."); | ||
process.exit(-1); | ||
} | ||
const op = process.platform; | ||
const op = process.platform; | ||
console.log(`Installing prebuilt OpenCV v${process.env.npm_package_opencv} for plattform ${op}`); | ||
install(`@nut-tree/opencv-build-${op}@${process.env.npm_package_opencv}`); | ||
packages[op].forEach(pkg => { | ||
console.log(`Installing additional runtime dependency '${pkg}'`); | ||
install(pkg); | ||
}); | ||
console.log(`Done.`); | ||
console.log(`Installing prebuilt OpenCV v${process.env.npm_package_opencv} for plattform ${op}`); | ||
install(`@nut-tree/opencv-build-${op}@${process.env.npm_package_opencv}`); | ||
packages[op].forEach(pkg => { | ||
console.log(`Installing additional runtime dependency '${pkg}'`); | ||
install(pkg); | ||
}); | ||
console.log(`Done.`); | ||
} |
const opencvBuild = require(`@nut-tree/opencv-build-${process.platform}`) | ||
const child_process = require('child_process') | ||
const { basename } = require("path"); | ||
const fs = require('fs') | ||
@@ -61,2 +62,14 @@ const log = require('npmlog') | ||
// linkLib produces linker flags for GNU ld and BSD ld | ||
// It generates linker flags based on the libPath, which make dealing with version numbers in lib names easier | ||
// On Linux, it passes the full path via -l:/path/to/lib which links against the given file | ||
// On macOS it strips the *.dylib suffix and the lib prefix and passes the result to via -l | ||
// This results in e.g. -lopencv_world.4.1 | ||
const linkLib = (lib) => { | ||
if (opencvBuild.isOSX()) { | ||
return `-l${basename(lib.libPath, ".dylib").replace("lib", "")}`; | ||
} else { | ||
return `-l:${basename(lib.libPath)}`; | ||
} | ||
} | ||
const libs = opencvBuild.isWin() | ||
@@ -66,3 +79,3 @@ ? libsFoundInDir.map(lib => resolvePath(lib.libPath)) | ||
: ['-L' + libDir] | ||
.concat(libsFoundInDir.map(lib => '-lopencv_' + lib.opencvModule)) | ||
.concat(libsFoundInDir.map(lib => linkLib(lib))) | ||
.concat('-Wl,-rpath,' + libDir) | ||
@@ -69,0 +82,0 @@ |
{ | ||
"name": "opencv4nodejs-prebuilt", | ||
"version": "5.3.0-1", | ||
"version": "5.3.0-2", | ||
"description": "Asynchronous OpenCV 3.x nodejs bindings with JavaScript and TypeScript API.", | ||
@@ -49,3 +49,3 @@ "keywords": [ | ||
"npmlog": "^4.1.2", | ||
"prebuild-install": "^5.3.2" | ||
"prebuild-install": "^5.3.3" | ||
}, | ||
@@ -58,3 +58,3 @@ "optionalDependencies": { | ||
}, | ||
"opencv": "4.1.1-5", | ||
"opencv": "4.1.1-7", | ||
"devDependencies": { | ||
@@ -61,0 +61,0 @@ "prebuild": "^9.1.0" |
359
README.md
@@ -208,355 +208,12 @@ opencv4nodejs | ||
<a name="usage-with-docker"></a> | ||
## Disabeling installation of prebuilt OpenCV | ||
# Usage with Docker | ||
By default opencv4nodejs-prebuilt will install a prebuilt version of OpenCV for the current platform via @nut-tree/opencv-build-(win32/linux/darwin). | ||
If you want to disable this behaviour (to e.g. provide your own OpenCV build), set the following environment variable: | ||
### [opencv-express](https://github.com/justadudewhohacks/opencv-express) - example for opencv4nodejs with express.js and docker | ||
Or simply pull from [justadudewhohacks/opencv-nodejs](https://hub.docker.com/r/justadudewhohacks/opencv-nodejs/) for opencv-3.2 + contrib-3.2 with opencv4nodejs globally installed: | ||
``` docker | ||
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/. | ||
<a name="usage-with-electron"></a> | ||
# Usage with Electron | ||
### [opencv-electron](https://github.com/justadudewhohacks/opencv-electron) - example for opencv4nodejs with electron | ||
Add the following script to your package.json: | ||
``` python | ||
"electron-rebuild": "electron-rebuild -w opencv4nodejs" | ||
``` | ||
Run the script: | ||
``` bash | ||
$ npm run electron-rebuild | ||
``` | ||
Require it in the application: | ||
``` javascript | ||
const cv = require('opencv4nodejs'); | ||
``` | ||
<a name="usage-with-nwjs"></a> | ||
# Usage with NW.js | ||
Any native modules, including opencv4nodejs, must be recompiled to be used with [NW.js](https://nwjs.io/). Instructions on how to do this are available in the **[Use Native Modules](http://docs.nwjs.io/en/latest/For%20Users/Advanced/Use%20Native%20Node%20Modules/)** section of the the NW.js documentation. | ||
Once recompiled, the module can be installed and required as usual: | ||
``` javascript | ||
const cv = require('opencv4nodejs'); | ||
``` | ||
<a name="quick-start"></a> | ||
# Quick Start | ||
``` javascript | ||
const cv = require('opencv4nodejs'); | ||
``` | ||
### Initializing Mat (image matrix), Vec, Point | ||
``` javascript | ||
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 | ||
``` javascript | ||
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 | ||
``` javascript | ||
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 | ||
``` javascript | ||
// 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 | ||
``` javascript | ||
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 | ||
``` javascript | ||
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: | ||
``` c++ | ||
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT); | ||
``` | ||
translates to: | ||
``` javascript | ||
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); | ||
``` | ||
<a name="async-api"></a> | ||
# 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 | ||
``` javascript | ||
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); | ||
} | ||
``` | ||
<a name="with-typescript"></a> | ||
# With TypeScript | ||
``` javascript | ||
import * as cv from 'opencv4nodejs' | ||
``` | ||
Check out the TypeScript [examples](https://github.com/justadudewhohacks/opencv4nodejs/tree/master/examples/typed). | ||
<a name="external-mem-tracking"></a> | ||
# 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: | ||
``` bash | ||
export OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING=1 // linux | ||
set OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING=1 // windows | ||
``` | ||
Or directly in your code: | ||
``` javascript | ||
process.env.OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING = 1 | ||
const cv = require('opencv4nodejs') | ||
``` | ||
# linux and osx: | ||
export OPENCV4NODEJS_PREBUILT_SKIP_DEPENDENCIES=1 | ||
# on windows: | ||
set OPENCV4NODEJS_PREBUILT_SKIP_DEPENDENCIES=1 | ||
``` |
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
2444
10928912
218
21
- Removedundici-types@5.26.5(transitive)
Updatedprebuild-install@^5.3.3