list detect cameras

pull/280/head
Vladimir Mandic 2021-08-13 10:34:09 -04:00
parent fc01b2a4a6
commit 2f9d7dedae
3 changed files with 37 additions and 17 deletions

View File

@ -9,11 +9,12 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog ## Changelog
### **HEAD -> main** 2021/08/12 mandic00@live.com
### **2.1.3** 2021/08/12 mandic00@live.com ### **2.1.3** 2021/08/12 mandic00@live.com
- fix centernet & update blazeface
### **origin/main** 2021/08/11 mandic00@live.com
- minor update - minor update
- replace movenet with lightning-v4 - replace movenet with lightning-v4
- enable webgl uniform support for faster warmup - enable webgl uniform support for faster warmup

View File

@ -7,6 +7,7 @@
*/ */
const util = require('util'); const util = require('util');
const process = require('process');
const log = require('@vladmandic/pilogger'); const log = require('@vladmandic/pilogger');
// eslint-disable-next-line node/no-missing-require // eslint-disable-next-line node/no-missing-require
const nodeWebCam = require('node-webcam'); const nodeWebCam = require('node-webcam');
@ -21,19 +22,31 @@ const optionsCamera = {
callbackReturn: 'buffer', // this means whatever `fswebcam` writes to disk, no additional processing so it's fastest callbackReturn: 'buffer', // this means whatever `fswebcam` writes to disk, no additional processing so it's fastest
saveShots: false, // don't save processed frame to disk, note that temp file is still created by fswebcam thus recommendation for tmpfs saveShots: false, // don't save processed frame to disk, note that temp file is still created by fswebcam thus recommendation for tmpfs
}; };
const camera = nodeWebCam.create(optionsCamera);
// options for human // options for human
const optionsHuman = { const optionsHuman = {
backend: 'tensorflow', backend: 'tensorflow',
modelBasePath: 'file://models/', modelBasePath: 'file://models/',
}; };
const camera = nodeWebCam.create(optionsCamera);
const capture = util.promisify(camera.capture);
const human = new Human(optionsHuman); const human = new Human(optionsHuman);
const results = []; const results = [];
const list = util.promisify(camera.list);
const capture = util.promisify(camera.capture);
async function init() {
try {
const found = await list();
log.data('Camera data:', found);
} catch {
log.error('Could not access camera');
process.exit(1);
}
}
const buffer2tensor = human.tf.tidy((buffer) => { const buffer2tensor = human.tf.tidy((buffer) => {
if (!buffer) return null;
const decode = human.tf.node.decodeImage(buffer, 3); const decode = human.tf.node.decodeImage(buffer, 3);
let expand; let expand;
if (decode.shape[2] === 4) { // input is in rgba format, need to convert to rgb if (decode.shape[2] === 4) { // input is in rgba format, need to convert to rgb
@ -47,24 +60,30 @@ const buffer2tensor = human.tf.tidy((buffer) => {
return cast; return cast;
}); });
async function process() { async function detect() {
// trigger next frame every 5 sec // trigger next frame every 5 sec
// triggered here before actual capture and detection since we assume it will complete in less than 5sec // triggered here before actual capture and detection since we assume it will complete in less than 5sec
// so it's as close as possible to real 5sec and not 5sec + detection time // so it's as close as possible to real 5sec and not 5sec + detection time
// if there is a chance of race scenario where detection takes longer than loop trigger, then trigger should be at the end of the function instead // if there is a chance of race scenario where detection takes longer than loop trigger, then trigger should be at the end of the function instead
setTimeout(() => process(), 5000); setTimeout(() => detect(), 5000);
const buffer = await capture(); // gets the (default) jpeg data from from webcam const buffer = await capture(); // gets the (default) jpeg data from from webcam
const tensor = buffer2tensor(buffer); // create tensor from image buffer const tensor = buffer2tensor(buffer); // create tensor from image buffer
const res = await human.detect(tensor); // run detection if (tensor) {
const res = await human.detect(tensor); // run detection
// do whatever here with the res
// or just append it to results array that will contain all processed results over time
results.push(res);
// do whatever here with the res
// or just append it to results array that will contain all processed results over time
results.push(res);
}
// alternatively to triggering every 5sec sec, simply trigger next frame as fast as possible // alternatively to triggering every 5sec sec, simply trigger next frame as fast as possible
// setImmediate(() => process()); // setImmediate(() => process());
} }
async function main() {
await init();
detect();
}
log.header(); log.header();
process(); main();

View File

@ -66,14 +66,14 @@
"@tensorflow/tfjs-layers": "^3.8.0", "@tensorflow/tfjs-layers": "^3.8.0",
"@tensorflow/tfjs-node": "^3.8.0", "@tensorflow/tfjs-node": "^3.8.0",
"@tensorflow/tfjs-node-gpu": "^3.8.0", "@tensorflow/tfjs-node-gpu": "^3.8.0",
"@types/node": "^16.6.0", "@types/node": "^16.6.1",
"@typescript-eslint/eslint-plugin": "^4.29.1", "@typescript-eslint/eslint-plugin": "^4.29.1",
"@typescript-eslint/parser": "^4.29.1", "@typescript-eslint/parser": "^4.29.1",
"@vladmandic/pilogger": "^0.2.18", "@vladmandic/pilogger": "^0.2.18",
"canvas": "^2.8.0", "canvas": "^2.8.0",
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
"dayjs": "^1.10.6", "dayjs": "^1.10.6",
"esbuild": "^0.12.19", "esbuild": "^0.12.20",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1", "eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.24.0", "eslint-plugin-import": "^2.24.0",
@ -83,7 +83,7 @@
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"seedrandom": "^3.0.5", "seedrandom": "^3.0.5",
"simple-git": "^2.42.0", "simple-git": "^2.43.0",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typedoc": "0.21.5", "typedoc": "0.21.5",
"typescript": "4.3.5" "typescript": "4.3.5"