accept uri as input to demo node and node-canvas

pull/54/head
Vladimir Mandic 2021-04-25 10:05:25 -04:00
parent 1410be346a
commit b8830e8cd3
3 changed files with 40 additions and 13 deletions

View File

@ -22,6 +22,9 @@ async function image(input) {
const c = canvas.createCanvas(img.width, img.height);
const ctx = c.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
// const out = fs.createWriteStream('test.jpg');
// const stream = c.createJPEGStream({ quality: 0.6, progressive: true, chromaSubsampling: true });
// stream.pipe(out);
return c;
}
@ -80,7 +83,7 @@ async function main() {
log.info('Processed', numImages, 'images in', Math.trunc(parseInt(t1 - t0) / 1000 / 1000), 'ms');
} else {
const param = process.argv[2];
if (fs.existsSync(param)) {
if (fs.existsSync(param) || param.startsWith('http:') || param.startsWith('https:')) {
const c = await image(param);
const result = await detect(c);
log.data('Image:', param, 'Detected faces:', result.length);

View File

@ -6,6 +6,8 @@ const path = require('path');
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
const log = require('@vladmandic/pilogger');
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
const fetch = require('node-fetch').default;
// eslint-disable-next-line import/no-extraneous-dependencies, node/no-unpublished-require
const tf = require('@tensorflow/tfjs-node');
const faceapi = require('../dist/face-api.node.js'); // this is equivalent to '@vladmandic/faceapi'
@ -15,14 +17,35 @@ const minConfidence = 0.15;
const maxResults = 5;
let optionsSSDMobileNet;
async function image(img) {
const buffer = fs.readFileSync(img);
const decoded = tf.node.decodeImage(buffer);
const casted = decoded.toFloat();
const result = casted.expandDims(0);
decoded.dispose();
casted.dispose();
return result;
async function image(input) {
// read input image file and create tensor to be used for processing
let buffer;
log.info('Loading image:', input);
if (input.startsWith('http:') || input.startsWith('https:')) {
const res = await fetch(input);
if (res && res.ok) buffer = await res.buffer();
else log.error('Invalid image URL:', input, res.status, res.statusText, res.headers.get('content-type'));
} else {
buffer = fs.readFileSync(input);
}
// decode image using tfjs-node so we don't need external depenencies
// can also be done using canvas.js or some other 3rd party image library
if (!buffer) return {};
const tensor = tf.tidy(() => {
const decode = faceapi.tf.node.decodeImage(buffer, 3);
let expand;
if (decode.shape[2] === 4) { // input is in rgba format, need to convert to rgb
const channels = faceapi.tf.split(decode, 4, 2); // tf.split(tensor, 4, 2); // split rgba to channels
const rgb = faceapi.tf.stack([channels[0], channels[1], channels[2]], 2); // stack channels back to rgb and ignore alpha
expand = faceapi.tf.reshape(rgb, [1, decode.shape[0], decode.shape[1], 3]); // move extra dim from the end of tensor and use it as batch number instead
} else {
expand = faceapi.tf.expandDims(decode, 0);
}
const cast = faceapi.tf.cast(expand, 'float32');
return cast;
});
return tensor;
}
async function detect(tensor) {
@ -97,7 +120,7 @@ async function main() {
log.info('Processed', dir.length, 'images in', Math.trunc(parseInt(t1 - t0) / 1000 / 1000), 'ms');
} else {
const param = process.argv[2];
if (fs.existsSync(param)) {
if (fs.existsSync(param) || param.startsWith('http:') || param.startsWith('https:')) {
const tensor = await image(param);
const result = await detect(tensor);
// const result = await detectPromise(null);

View File

@ -53,18 +53,19 @@
"canvas": "^2.7.0",
"chokidar": "^3.5.1",
"dayjs": "^1.10.4",
"esbuild": "^0.11.12",
"eslint": "^7.24.0",
"esbuild": "^0.11.14",
"eslint": "^7.25.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-json": "^2.1.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"node-fetch": "^2.6.1",
"rimraf": "^3.0.2",
"seedrandom": "^3.0.5",
"simple-git": "^2.38.0",
"tslib": "^2.2.0",
"typedoc": "^0.20.35",
"typedoc": "^0.20.36",
"typescript": "^4.2.4"
}
}