Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit 5a04a3b

Browse files
committed
(#3) Added possibility to disable automated installation of prebuilt OpenCV via env var
1 parent bbbbc4e commit 5a04a3b

File tree

2 files changed

+22
-363
lines changed

2 files changed

+22
-363
lines changed

README.md

Lines changed: 8 additions & 351 deletions
Original file line numberDiff line numberDiff line change
@@ -205,357 +205,14 @@ The following environment variables can be passed:
205205
- opencvLibDir
206206
- opencvBinDir
207207

208-
<a name="usage-with-docker"></a>
208+
## Disabeling installation of prebuilt OpenCV
209209

210-
# Usage with Docker
211-
212-
### [opencv-express](https://github.com/justadudewhohacks/opencv-express) - example for opencv4nodejs with express.js and docker
213-
214-
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:
215-
216-
``` docker
217-
FROM justadudewhohacks/opencv-nodejs
218-
```
219-
220-
**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.
221-
222-
Different OpenCV 3.x base images can be found here: https://hub.docker.com/r/justadudewhohacks/.
223-
224-
<a name="usage-with-electron"></a>
225-
226-
# Usage with Electron
227-
228-
### [opencv-electron](https://github.com/justadudewhohacks/opencv-electron) - example for opencv4nodejs with electron
229-
230-
Add the following script to your package.json:
231-
``` python
232-
"electron-rebuild": "electron-rebuild -w opencv4nodejs"
233-
```
234-
235-
Run the script:
236-
``` bash
237-
$ npm run electron-rebuild
238-
```
239-
240-
Require it in the application:
241-
``` javascript
242-
const cv = require('opencv4nodejs');
243-
```
244-
245-
<a name="usage-with-nwjs"></a>
246-
247-
# Usage with NW.js
248-
249-
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.
250-
251-
Once recompiled, the module can be installed and required as usual:
252-
253-
``` javascript
254-
const cv = require('opencv4nodejs');
255-
```
256-
257-
<a name="quick-start"></a>
258-
259-
# Quick Start
260-
261-
``` javascript
262-
const cv = require('opencv4nodejs');
263-
```
264-
265-
### Initializing Mat (image matrix), Vec, Point
266-
267-
``` javascript
268-
const rows = 100; // height
269-
const cols = 100; // width
270-
271-
// empty Mat
272-
const emptyMat = new cv.Mat(rows, cols, cv.CV_8UC3);
273-
274-
// fill the Mat with default value
275-
const whiteMat = new cv.Mat(rows, cols, cv.CV_8UC1, 255);
276-
const blueMat = new cv.Mat(rows, cols, cv.CV_8UC3, [255, 0, 0]);
277-
278-
// from array (3x3 Matrix, 3 channels)
279-
const matData = [
280-
[[255, 0, 0], [255, 0, 0], [255, 0, 0]],
281-
[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
282-
[[255, 0, 0], [255, 0, 0], [255, 0, 0]]
283-
];
284-
const matFromArray = new cv.Mat(matData, cv.CV_8UC3);
285-
286-
// from node buffer
287-
const charData = [255, 0, ...];
288-
const matFromArray = new cv.Mat(Buffer.from(charData), rows, cols, cv.CV_8UC3);
289-
290-
// Point
291-
const pt2 = new cv.Point(100, 100);
292-
const pt3 = new cv.Point(100, 100, 0.5);
293-
294-
// Vector
295-
const vec2 = new cv.Vec(100, 100);
296-
const vec3 = new cv.Vec(100, 100, 0.5);
297-
const vec4 = new cv.Vec(100, 100, 0.5, 0.5);
298-
```
299-
300-
### Mat and Vec operations
301-
302-
``` javascript
303-
const mat0 = new cv.Mat(...);
304-
const mat1 = new cv.Mat(...);
305-
306-
// arithmetic operations for Mats and Vecs
307-
const matMultipliedByScalar = mat0.mul(0.5); // scalar multiplication
308-
const matDividedByScalar = mat0.div(2); // scalar division
309-
const mat0PlusMat1 = mat0.add(mat1); // addition
310-
const mat0MinusMat1 = mat0.sub(mat1); // subtraction
311-
const mat0MulMat1 = mat0.hMul(mat1); // elementwise multiplication
312-
const mat0DivMat1 = mat0.hDiv(mat1); // elementwise division
313-
314-
// logical operations Mat only
315-
const mat0AndMat1 = mat0.and(mat1);
316-
const mat0OrMat1 = mat0.or(mat1);
317-
const mat0bwAndMat1 = mat0.bitwiseAnd(mat1);
318-
const mat0bwOrMat1 = mat0.bitwiseOr(mat1);
319-
const mat0bwXorMat1 = mat0.bitwiseXor(mat1);
320-
const mat0bwNot = mat0.bitwiseNot();
321-
```
322-
323-
### Accessing Mat data
324-
325-
``` javascript
326-
const matBGR = new cv.Mat(..., cv.CV_8UC3);
327-
const matGray = new cv.Mat(..., cv.CV_8UC1);
328-
329-
// get pixel value as vector or number value
330-
const vec3 = matBGR.at(200, 100);
331-
const grayVal = matGray.at(200, 100);
332-
333-
// get raw pixel value as array
334-
const [b, g, r] = matBGR.atRaw(200, 100);
335-
336-
// set single pixel values
337-
matBGR.set(50, 50, [255, 0, 0]);
338-
matBGR.set(50, 50, new Vec(255, 0, 0));
339-
matGray.set(50, 50, 255);
340-
341-
// get a 25x25 sub region of the Mat at offset (50, 50)
342-
const width = 25;
343-
const height = 25;
344-
const region = matBGR.getRegion(new cv.Rect(50, 50, width, height));
345-
346-
// get a node buffer with raw Mat data
347-
const matAsBuffer = matBGR.getData();
348-
349-
// get entire Mat data as JS array
350-
const matAsArray = matBGR.getDataAsArray();
351-
```
352-
353-
### IO
354-
355-
``` javascript
356-
// load image from file
357-
const mat = cv.imread('./path/img.jpg');
358-
cv.imreadAsync('./path/img.jpg', (err, mat) => {
359-
...
360-
})
361-
362-
// save image
363-
cv.imwrite('./path/img.png', mat);
364-
cv.imwriteAsync('./path/img.jpg', mat,(err) => {
365-
...
366-
})
367-
368-
// show image
369-
cv.imshow('a window name', mat);
370-
cv.waitKey();
371-
372-
// load base64 encoded image
373-
const base64text='data:image/png;base64,R0lGO..';//Base64 encoded string
374-
const base64data =base64text.replace('data:image/jpeg;base64','')
375-
.replace('data:image/png;base64','');//Strip image type prefix
376-
const buffer = Buffer.from(base64data,'base64');
377-
const image = cv.imdecode(buffer); //Image is now represented as Mat
378-
379-
// convert Mat to base64 encoded jpg image
380-
const outBase64 = cv.imencode('.jpg', croppedImage).toString('base64'); // Perform base64 encoding
381-
const htmlImg='<img src=data:image/jpeg;base64,'+outBase64 + '>'; //Create insert into HTML compatible <img> tag
382-
383-
// open capture from webcam
384-
const devicePort = 0;
385-
const wCap = new cv.VideoCapture(devicePort);
386-
387-
// open video capture
388-
const vCap = new cv.VideoCapture('./path/video.mp4');
389-
390-
// read frames from capture
391-
const frame = vCap.read();
392-
vCap.readAsync((err, frame) => {
393-
...
394-
});
395-
396-
// loop through the capture
397-
const delay = 10;
398-
let done = false;
399-
while (!done) {
400-
let frame = vCap.read();
401-
// loop back to start on end of stream reached
402-
if (frame.empty) {
403-
vCap.reset();
404-
frame = vCap.read();
405-
}
406-
407-
// ...
408-
409-
const key = cv.waitKey(delay);
410-
done = key !== 255;
411-
}
412-
```
413-
414-
### Useful Mat methods
415-
416-
``` javascript
417-
const matBGR = new cv.Mat(..., cv.CV_8UC3);
418-
419-
// convert types
420-
const matSignedInt = matBGR.convertTo(cv.CV_32SC3);
421-
const matDoublePrecision = matBGR.convertTo(cv.CV_64FC3);
422-
423-
// convert color space
424-
const matGray = matBGR.bgrToGray();
425-
const matHSV = matBGR.cvtColor(cv.COLOR_BGR2HSV);
426-
const matLab = matBGR.cvtColor(cv.COLOR_BGR2Lab);
427-
428-
// resize
429-
const matHalfSize = matBGR.rescale(0.5);
430-
const mat100x100 = matBGR.resize(100, 100);
431-
const matMaxDimIs100 = matBGR.resizeToMax(100);
432-
433-
// extract channels and create Mat from channels
434-
const [matB, matG, matR] = matBGR.splitChannels();
435-
const matRGB = new cv.Mat([matR, matB, matG]);
436-
```
437-
438-
### Drawing a Mat into HTML Canvas
439-
440-
``` javascript
441-
const img = ...
442-
443-
// convert your image to rgba color space
444-
const matRGBA = img.channels === 1
445-
? img.cvtColor(cv.COLOR_GRAY2RGBA)
446-
: img.cvtColor(cv.COLOR_BGR2RGBA);
447-
448-
// create new ImageData from raw mat data
449-
const imgData = new ImageData(
450-
new Uint8ClampedArray(matRGBA.getData()),
451-
img.cols,
452-
img.rows
453-
);
454-
455-
// set canvas dimensions
456-
const canvas = document.getElementById('myCanvas');
457-
canvas.height = img.rows;
458-
canvas.width = img.cols;
459-
460-
// set image data
461-
const ctx = canvas.getContext('2d');
462-
ctx.putImageData(imgData, 0, 0);
463-
```
464-
465-
### Method Interface
466-
467-
OpenCV method interface from official docs or src:
468-
``` c++
469-
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);
470-
```
471-
472-
translates to:
473-
474-
``` javascript
475-
const src = new cv.Mat(...);
476-
// invoke with required arguments
477-
const dst0 = src.gaussianBlur(new cv.Size(5, 5), 1.2);
478-
// with optional paramaters
479-
const dst2 = src.gaussianBlur(new cv.Size(5, 5), 1.2, 0.8, cv.BORDER_REFLECT);
480-
// or pass specific optional parameters
481-
const optionalArgs = {
482-
borderType: cv.BORDER_CONSTANT
483-
};
484-
const dst2 = src.gaussianBlur(new cv.Size(5, 5), 1.2, optionalArgs);
485-
```
486-
487-
<a name="async-api"></a>
488-
489-
# Async API
490-
491-
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.
492-
493-
### Async Face Detection
494-
495-
``` javascript
496-
const classifier = new cv.CascadeClassifier(cv.HAAR_FRONTALFACE_ALT2);
497-
498-
// by nesting callbacks
499-
cv.imreadAsync('./faceimg.jpg', (err, img) => {
500-
if (err) { return console.error(err); }
501-
502-
const grayImg = img.bgrToGray();
503-
classifier.detectMultiScaleAsync(grayImg, (err, res) => {
504-
if (err) { return console.error(err); }
505-
506-
const { objects, numDetections } = res;
507-
...
508-
});
509-
});
510-
511-
// via Promise
512-
cv.imreadAsync('./faceimg.jpg')
513-
.then(img =>
514-
img.bgrToGrayAsync()
515-
.then(grayImg => classifier.detectMultiScaleAsync(grayImg))
516-
.then((res) => {
517-
const { objects, numDetections } = res;
518-
...
519-
})
520-
)
521-
.catch(err => console.error(err));
522-
523-
// using async await
524-
try {
525-
const img = await cv.imreadAsync('./faceimg.jpg');
526-
const grayImg = await img.bgrToGrayAsync();
527-
const { objects, numDetections } = await classifier.detectMultiScaleAsync(grayImg);
528-
...
529-
} catch (err) {
530-
console.error(err);
531-
}
532-
```
533-
534-
<a name="with-typescript"></a>
535-
536-
# With TypeScript
537-
538-
``` javascript
539-
import * as cv from 'opencv4nodejs'
540-
```
541-
542-
Check out the TypeScript [examples](https://github.com/justadudewhohacks/opencv4nodejs/tree/master/examples/typed).
543-
544-
<a name="external-mem-tracking"></a>
545-
546-
# External Memory Tracking (v4.0.0)
547-
548-
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.
549-
550-
Note, that in doubt this feature can be **disabled** by setting an environment variable `OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING` before requiring the module:
210+
By default opencv4nodejs-prebuilt will install a prebuilt version of OpenCV for the current platform via @nut-tree/opencv-build-(win32/linux/darwin).
211+
If you want to disable this behaviour (to e.g. provide your own OpenCV build), set the following environment variable:
551212

552213
``` bash
553-
export OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING=1 // linux
554-
set OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING=1 // windows
555-
```
556-
557-
Or directly in your code:
558-
``` javascript
559-
process.env.OPENCV4NODEJS_DISABLE_EXTERNAL_MEM_TRACKING = 1
560-
const cv = require('opencv4nodejs')
561-
```
214+
# linux and osx:
215+
export OPENCV4NODEJS_PREBUILT_SKIP_DEPENDENCIES=1
216+
# on windows:
217+
set OPENCV4NODEJS_PREBUILT_SKIP_DEPENDENCIES=1
218+
```

install/dependencies.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,19 @@ const packages = {
1414
]
1515
}
1616

17-
if (!isX64) {
18-
console.log("Unsupported platform, only x64 is supported.");
19-
process.exit(-1);
20-
}
17+
if (!process.env["OPENCV4NODEJS_PREBUILT_SKIP_DEPENDENCIES"]) {
18+
if (!isX64) {
19+
console.log("Unsupported platform, only x64 is supported.");
20+
process.exit(-1);
21+
}
2122

22-
const op = process.platform;
23+
const op = process.platform;
2324

24-
console.log(`Installing prebuilt OpenCV v${process.env.npm_package_opencv} for plattform ${op}`);
25-
install(`@nut-tree/opencv-build-${op}@${process.env.npm_package_opencv}`);
26-
packages[op].forEach(pkg => {
27-
console.log(`Installing additional runtime dependency '${pkg}'`);
28-
install(pkg);
29-
});
30-
console.log(`Done.`);
25+
console.log(`Installing prebuilt OpenCV v${process.env.npm_package_opencv} for plattform ${op}`);
26+
install(`@nut-tree/opencv-build-${op}@${process.env.npm_package_opencv}`);
27+
packages[op].forEach(pkg => {
28+
console.log(`Installing additional runtime dependency '${pkg}'`);
29+
install(pkg);
30+
});
31+
console.log(`Done.`);
32+
}

0 commit comments

Comments
 (0)