From 47c7bdfae27d2021f738e3dc9d1556716464e398 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Sun, 21 Aug 2022 15:23:03 -0400 Subject: [PATCH] expand type safety --- .eslintrc.json | 21 +- CHANGELOG.md | 2 +- TODO.md | 2 + demo/faceid/index.js | 4 +- demo/faceid/index.js.map | 6 +- demo/faceid/index.ts | 18 +- demo/typescript/index.js | 4 +- demo/typescript/index.js.map | 4 +- demo/typescript/index.ts | 12 +- src/body/blazepose.ts | 8 +- src/body/blazeposedetector.ts | 4 +- src/body/movenet.ts | 8 +- src/body/movenetfix.ts | 2 +- src/body/posenet.ts | 8 +- src/body/posenetutils.ts | 6 +- src/draw/body.ts | 4 +- src/draw/draw.ts | 6 +- src/draw/face.ts | 8 +- src/draw/gesture.ts | 4 +- src/draw/hand.ts | 4 +- src/draw/object.ts | 4 +- src/draw/options.ts | 38 +- src/face/face.ts | 2 +- src/face/faceboxes.ts | 8 +- src/face/facemeshutil.ts | 4 +- src/face/faceres.ts | 18 +- src/hand/handpose.ts | 4 +- src/hand/handposedetector.ts | 19 +- src/hand/handposepipeline.ts | 2 +- src/human.ts | 4 +- src/image/enhance.ts | 2 +- src/image/image.ts | 23 +- src/image/imagefx.ts | 24 +- src/models.ts | 2 +- src/tfjs/backend.ts | 12 +- src/tfjs/humangl.ts | 14 +- src/tfjs/load.ts | 6 +- src/util/env.ts | 6 +- src/util/interpolate.ts | 6 +- src/util/persons.ts | 2 +- src/util/profile.ts | 6 +- src/warmup.ts | 12 +- test/build.log | 78 +- test/test.log | 1940 ++++++++++++++++----------------- 44 files changed, 1197 insertions(+), 1174 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index f713f5c7..d680eeee 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,13 +22,29 @@ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:@typescript-eslint/strict", "plugin:import/recommended", "plugin:promise/recommended" ], "rules": { "@typescript-eslint/ban-ts-comment":"off", + "@typescript-eslint/dot-notation":"off", "@typescript-eslint/no-empty-interface":"off", "@typescript-eslint/no-inferrable-types":"off", + "@typescript-eslint/no-misused-promises":"off", + "@typescript-eslint/no-unnecessary-condition":"off", + "@typescript-eslint/no-unsafe-argument":"off", + "@typescript-eslint/no-unsafe-assignment":"off", + "@typescript-eslint/no-unsafe-call":"off", + "@typescript-eslint/no-unsafe-member-access":"off", + "@typescript-eslint/no-unsafe-return":"off", + "@typescript-eslint/non-nullable-type-assertion-style":"off", + "@typescript-eslint/prefer-for-of":"off", + "@typescript-eslint/prefer-nullish-coalescing":"off", + "@typescript-eslint/prefer-ts-expect-error":"off", + "@typescript-eslint/restrict-plus-operands":"off", + "@typescript-eslint/restrict-template-expressions":"off", "dot-notation":"off", "guard-for-in":"off", "import/extensions": ["off", "always"], @@ -47,6 +63,7 @@ "no-regex-spaces":"off", "no-restricted-syntax":"off", "no-return-assign":"off", + "no-void":"off", "object-curly-newline":"off", "prefer-destructuring":"off", "prefer-template":"off", @@ -130,8 +147,8 @@ "html", "@html-eslint" ], "rules": { - "@html-eslint/indent": ["error", 2], - "@html-eslint/element-newline":"off" + "@html-eslint/element-newline":"off", + "@html-eslint/indent": ["error", 2] } } ], diff --git a/CHANGELOG.md b/CHANGELOG.md index 61c4c10e..2590d40f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ ## Changelog -### **HEAD -> main** 2022/08/20 mandic00@live.com +### **HEAD -> main** 2022/08/21 mandic00@live.com ### **2.9.4** 2022/08/20 mandic00@live.com diff --git a/TODO.md b/TODO.md index 1290f357..46291f90 100644 --- a/TODO.md +++ b/TODO.md @@ -66,6 +66,8 @@ Model is supported using `WebGL` backend in browser - Allow hosting models in **Google Cloud Bucket** Hosted models can be directly used without downloading to local storage Example: `modelPath: 'https://storage.googleapis.com/human-models/facemesh.json'` +- Stricter linting rules for both **TypeScript** and **JavaScript** + See `./eslintrc.json` for details - Fix **MobileFaceNet** model as alternative for face embedding/descriptor detection Configurable using `config.face.mobilefacenet` config section - Fix **EfficientPose** module as alternative body detection diff --git a/demo/faceid/index.js b/demo/faceid/index.js index 4d28394c..b9807b6b 100644 --- a/demo/faceid/index.js +++ b/demo/faceid/index.js @@ -4,6 +4,6 @@ author: ' */ -import*as B from"../../dist/human.esm.js";var l,R="human",g="person",p=(...t)=>console.log("indexdb",...t);async function v(){return l?!0:new Promise(t=>{let o=indexedDB.open(R,1);o.onerror=s=>p("error:",s),o.onupgradeneeded=s=>{p("create:",s.target),l=s.target.result,l.createObjectStore(g,{keyPath:"id",autoIncrement:!0})},o.onsuccess=s=>{l=s.target.result,p("open:",l),t(!0)}})}async function x(){let t=[];return l||await v(),new Promise(o=>{let s=l.transaction([g],"readwrite").objectStore(g).openCursor(null,"next");s.onerror=i=>p("load error:",i),s.onsuccess=i=>{i.target.result?(t.push(i.target.result.value),i.target.result.continue()):o(t)}})}async function y(){return l||await v(),new Promise(t=>{let o=l.transaction([g],"readwrite").objectStore(g).count();o.onerror=s=>p("count error:",s),o.onsuccess=()=>t(o.result)})}async function C(t){l||await v();let o={name:t.name,descriptor:t.descriptor,image:t.image};l.transaction([g],"readwrite").objectStore(g).put(o),p("save:",o)}async function D(t){l||await v(),l.transaction([g],"readwrite").objectStore(g).delete(t.id),p("delete:",t)}var b={modelBasePath:"../../models",filter:{equalization:!0},face:{enabled:!0,detector:{rotation:!0,return:!0,cropFactor:1.6,mask:!1},description:{enabled:!0},iris:{enabled:!0},emotion:{enabled:!1},antispoof:{enabled:!0},liveness:{enabled:!0}},body:{enabled:!1},hand:{enabled:!1},object:{enabled:!1},gesture:{enabled:!0}},E={order:2,multiplier:25,min:.2,max:.8},c={minConfidence:.6,minSize:224,maxTime:1e4,blinkMin:10,blinkMax:800,threshold:.5,mask:b.face.detector.mask,rotation:b.face.detector.rotation,cropFactor:b.face.detector.cropFactor,...E},n={faceCount:!1,faceConfidence:!1,facingCenter:!1,lookingCenter:!1,blinkDetected:!1,faceSize:!1,antispoofCheck:!1,livenessCheck:!1,elapsedMs:0},I=()=>n.faceCount&&n.faceSize&&n.blinkDetected&&n.facingCenter&&n.lookingCenter&&n.faceConfidence&&n.antispoofCheck&&n.livenessCheck,r={face:null,record:null},u={start:0,end:0,time:0},a=new B.Human(b);a.env.perfadd=!1;a.draw.options.font='small-caps 18px "Lato"';a.draw.options.lineHeight=20;var e={video:document.getElementById("video"),canvas:document.getElementById("canvas"),log:document.getElementById("log"),fps:document.getElementById("fps"),match:document.getElementById("match"),name:document.getElementById("name"),save:document.getElementById("save"),delete:document.getElementById("delete"),retry:document.getElementById("retry"),source:document.getElementById("source"),ok:document.getElementById("ok")},w={detect:0,draw:0},h={detect:0,draw:0},S=0,m=(...t)=>{e.log.innerText+=t.join(" ")+` -`,console.log(...t)},k=t=>e.fps.innerText=t;async function H(){k("starting webcam...");let t={audio:!1,video:{facingMode:"user",resizeMode:"none",width:{ideal:document.body.clientWidth}}},o=await navigator.mediaDevices.getUserMedia(t),s=new Promise(i=>{e.video.onloadeddata=()=>i(!0)});e.video.srcObject=o,e.video.play(),await s,e.canvas.width=e.video.videoWidth,e.canvas.height=e.video.videoHeight,a.env.initial&&m("video:",e.video.videoWidth,e.video.videoHeight,"|",o.getVideoTracks()[0].label),e.canvas.onclick=()=>{e.video.paused?e.video.play():e.video.pause()}}async function T(){if(!e.video.paused){r.face&&r.face.tensor&&a.tf.dispose(r.face.tensor),await a.detect(e.video);let t=a.now();h.detect=1e3/(t-w.detect),w.detect=t,requestAnimationFrame(T)}}async function L(){let t=await a.next(a.result);await a.draw.canvas(e.video,e.canvas),await a.draw.all(e.canvas,t);let o=a.now();if(h.draw=1e3/(o-w.draw),w.draw=o,k(`fps: ${h.detect.toFixed(1).padStart(5," ")} detect | ${h.draw.toFixed(1).padStart(5," ")} draw`),n.faceCount=a.result.face.length===1,n.faceCount){let i=Object.values(a.result.gesture).map(f=>f.gesture);(i.includes("blink left eye")||i.includes("blink right eye"))&&(u.start=a.now()),u.start>0&&!i.includes("blink left eye")&&!i.includes("blink right eye")&&(u.end=a.now()),n.blinkDetected=n.blinkDetected||Math.abs(u.end-u.start)>c.blinkMin&&Math.abs(u.end-u.start)c.minConfidence&&(a.result.face[0].faceScore||0)>c.minConfidence,n.antispoofCheck=(a.result.face[0].real||0)>c.minConfidence,n.livenessCheck=(a.result.face[0].live||0)>c.minConfidence,n.faceSize=a.result.face[0].box[2]>=c.minSize&&a.result.face[0].box[3]>=c.minSize}let s=32;for(let[i,f]of Object.entries(n)){let d=document.getElementById(`ok-${i}`);d||(d=document.createElement("div"),d.innerText=i,d.className="ok",d.style.top=`${s}px`,e.ok.appendChild(d)),typeof f=="boolean"?d.style.backgroundColor=f?"lightgreen":"lightcoral":d.innerText=`${i}:${f}`,s+=28}return I()||n.elapsedMs>c.maxTime?(e.video.pause(),a.result.face[0]):(n.elapsedMs=Math.trunc(a.now()-S),new Promise(i=>{setTimeout(async()=>{await L()&&i(a.result.face[0])},30)}))}async function z(){var t,o,s,i;if(e.name.value.length>0){let f=(t=e.canvas.getContext("2d"))==null?void 0:t.getImageData(0,0,e.canvas.width,e.canvas.height),d={id:0,name:e.name.value,descriptor:(o=r.face)==null?void 0:o.embedding,image:f};await C(d),m("saved face record:",d.name,"descriptor length:",(i=(s=r.face)==null?void 0:s.embedding)==null?void 0:i.length),m("known face records:",await y())}else m("invalid name")}async function P(){r.record&&r.record.id>0&&await D(r.record)}async function j(){var i,f;if((i=e.canvas.getContext("2d"))==null||i.clearRect(0,0,c.minSize,c.minSize),!r.face||!r.face.tensor||!r.face.embedding)return!1;if(console.log("face record:",r.face),a.tf.browser.toPixels(r.face.tensor,e.canvas),await y()===0)return m("face database is empty"),document.body.style.background="black",e.delete.style.display="none",!1;let t=await x(),o=t.map(d=>d.descriptor).filter(d=>d.length>0),s=await a.match(r.face.embedding,o,E);return r.record=t[s.index]||null,r.record&&(m(`best match: ${r.record.name} | id: ${r.record.id} | similarity: ${Math.round(1e3*s.similarity)/10}%`),e.name.value=r.record.name,e.source.style.display="",(f=e.source.getContext("2d"))==null||f.putImageData(r.record.image,0,0)),document.body.style.background=s.similarity>c.threshold?"darkgreen":"maroon",s.similarity>c.threshold}async function M(){var t,o;return n.faceCount=!1,n.faceConfidence=!1,n.facingCenter=!1,n.blinkDetected=!1,n.faceSize=!1,n.antispoofCheck=!1,n.livenessCheck=!1,n.elapsedMs=0,e.match.style.display="none",e.retry.style.display="none",e.source.style.display="none",document.body.style.background="black",await H(),await T(),S=a.now(),r.face=await L(),e.canvas.width=((t=r.face.tensor)==null?void 0:t.shape[1])||c.minSize,e.canvas.height=((o=r.face.tensor)==null?void 0:o.shape[0])||c.minSize,e.source.width=e.canvas.width,e.source.height=e.canvas.height,e.canvas.style.width="",e.match.style.display="flex",e.save.style.display="flex",e.delete.style.display="flex",e.retry.style.display="block",I()?j():(m("did not find valid face"),!1)}async function q(){var t,o;m("human version:",a.version,"| tfjs version:",a.tf.version["tfjs-core"]),m("face embedding model:",b.face.description.enabled?"faceres":"",(t=b.face.mobilefacenet)!=null&&t.enabled?"mobilefacenet":"",(o=b.face.insightface)!=null&&o.enabled?"insightface":""),m("options:",JSON.stringify(c).replace(/{|}|"|\[|\]/g,"").replace(/,/g," ")),k("loading..."),m("known face records:",await y()),await H(),await a.load(),k("initializing..."),e.retry.addEventListener("click",M),e.save.addEventListener("click",z),e.delete.addEventListener("click",P),await a.warmup(),await M()}window.onload=q; +import*as B from"../../dist/human.esm.js";var l,R="human",g="person",p=(...t)=>console.log("indexdb",...t);async function v(){return l?!0:new Promise(t=>{let a=indexedDB.open(R,1);a.onerror=s=>p("error:",s),a.onupgradeneeded=s=>{p("create:",s.target),l=s.target.result,l.createObjectStore(g,{keyPath:"id",autoIncrement:!0})},a.onsuccess=s=>{l=s.target.result,p("open:",l),t(!0)}})}async function x(){let t=[];return l||await v(),new Promise(a=>{let s=l.transaction([g],"readwrite").objectStore(g).openCursor(null,"next");s.onerror=i=>p("load error:",i),s.onsuccess=i=>{i.target.result?(t.push(i.target.result.value),i.target.result.continue()):a(t)}})}async function y(){return l||await v(),new Promise(t=>{let a=l.transaction([g],"readwrite").objectStore(g).count();a.onerror=s=>p("count error:",s),a.onsuccess=()=>t(a.result)})}async function C(t){l||await v();let a={name:t.name,descriptor:t.descriptor,image:t.image};l.transaction([g],"readwrite").objectStore(g).put(a),p("save:",a)}async function D(t){l||await v(),l.transaction([g],"readwrite").objectStore(g).delete(t.id),p("delete:",t)}var b={modelBasePath:"../../models",filter:{equalization:!0},face:{enabled:!0,detector:{rotation:!0,return:!0,cropFactor:1.6,mask:!1},description:{enabled:!0},iris:{enabled:!0},emotion:{enabled:!1},antispoof:{enabled:!0},liveness:{enabled:!0}},body:{enabled:!1},hand:{enabled:!1},object:{enabled:!1},gesture:{enabled:!0}},E={order:2,multiplier:25,min:.2,max:.8},c={minConfidence:.6,minSize:224,maxTime:1e4,blinkMin:10,blinkMax:800,threshold:.5,mask:b.face.detector.mask,rotation:b.face.detector.rotation,cropFactor:b.face.detector.cropFactor,...E},o={faceCount:!1,faceConfidence:!1,facingCenter:!1,lookingCenter:!1,blinkDetected:!1,faceSize:!1,antispoofCheck:!1,livenessCheck:!1,elapsedMs:0},I=()=>o.faceCount&&o.faceSize&&o.blinkDetected&&o.facingCenter&&o.lookingCenter&&o.faceConfidence&&o.antispoofCheck&&o.livenessCheck,r={face:null,record:null},u={start:0,end:0,time:0},n=new B.Human(b);n.env.perfadd=!1;n.draw.options.font='small-caps 18px "Lato"';n.draw.options.lineHeight=20;var e={video:document.getElementById("video"),canvas:document.getElementById("canvas"),log:document.getElementById("log"),fps:document.getElementById("fps"),match:document.getElementById("match"),name:document.getElementById("name"),save:document.getElementById("save"),delete:document.getElementById("delete"),retry:document.getElementById("retry"),source:document.getElementById("source"),ok:document.getElementById("ok")},w={detect:0,draw:0},h={detect:0,draw:0},S=0,f=(...t)=>{e.log.innerText+=t.join(" ")+` +`,console.log(...t)},k=t=>e.fps.innerText=t;async function H(){k("starting webcam...");let t={audio:!1,video:{facingMode:"user",resizeMode:"none",width:{ideal:document.body.clientWidth}}},a=await navigator.mediaDevices.getUserMedia(t),s=new Promise(i=>{e.video.onloadeddata=()=>i(!0)});e.video.srcObject=a,e.video.play(),await s,e.canvas.width=e.video.videoWidth,e.canvas.height=e.video.videoHeight,n.env.initial&&f("video:",e.video.videoWidth,e.video.videoHeight,"|",a.getVideoTracks()[0].label),e.canvas.onclick=()=>{e.video.paused?e.video.play():e.video.pause()}}async function T(){var t;if(!e.video.paused){(t=r.face)!=null&&t.tensor&&n.tf.dispose(r.face.tensor),await n.detect(e.video);let a=n.now();h.detect=1e3/(a-w.detect),w.detect=a,requestAnimationFrame(T)}}async function L(){let t=n.next(n.result);n.draw.canvas(e.video,e.canvas),await n.draw.all(e.canvas,t);let a=n.now();if(h.draw=1e3/(a-w.draw),w.draw=a,k(`fps: ${h.detect.toFixed(1).padStart(5," ")} detect | ${h.draw.toFixed(1).padStart(5," ")} draw`),o.faceCount=n.result.face.length===1,o.faceCount){let i=Object.values(n.result.gesture).map(m=>m.gesture);(i.includes("blink left eye")||i.includes("blink right eye"))&&(u.start=n.now()),u.start>0&&!i.includes("blink left eye")&&!i.includes("blink right eye")&&(u.end=n.now()),o.blinkDetected=o.blinkDetected||Math.abs(u.end-u.start)>c.blinkMin&&Math.abs(u.end-u.start)c.minConfidence&&(n.result.face[0].faceScore||0)>c.minConfidence,o.antispoofCheck=(n.result.face[0].real||0)>c.minConfidence,o.livenessCheck=(n.result.face[0].live||0)>c.minConfidence,o.faceSize=n.result.face[0].box[2]>=c.minSize&&n.result.face[0].box[3]>=c.minSize}let s=32;for(let[i,m]of Object.entries(o)){let d=document.getElementById(`ok-${i}`);d||(d=document.createElement("div"),d.innerText=i,d.className="ok",d.style.top=`${s}px`,e.ok.appendChild(d)),typeof m=="boolean"?d.style.backgroundColor=m?"lightgreen":"lightcoral":d.innerText=`${i}:${m}`,s+=28}return I()||o.elapsedMs>c.maxTime?(e.video.pause(),n.result.face[0]):(o.elapsedMs=Math.trunc(n.now()-S),new Promise(i=>{setTimeout(async()=>{await L(),i(n.result.face[0])},30)}))}async function z(){var t,a,s,i;if(e.name.value.length>0){let m=(t=e.canvas.getContext("2d"))==null?void 0:t.getImageData(0,0,e.canvas.width,e.canvas.height),d={id:0,name:e.name.value,descriptor:(a=r.face)==null?void 0:a.embedding,image:m};await C(d),f("saved face record:",d.name,"descriptor length:",(i=(s=r.face)==null?void 0:s.embedding)==null?void 0:i.length),f("known face records:",await y())}else f("invalid name")}async function P(){r.record&&r.record.id>0&&await D(r.record)}async function j(){var i,m;if((i=e.canvas.getContext("2d"))==null||i.clearRect(0,0,c.minSize,c.minSize),!r.face||!r.face.tensor||!r.face.embedding)return!1;if(console.log("face record:",r.face),n.tf.browser.toPixels(r.face.tensor,e.canvas),await y()===0)return f("face database is empty"),document.body.style.background="black",e.delete.style.display="none",!1;let t=await x(),a=t.map(d=>d.descriptor).filter(d=>d.length>0),s=n.match(r.face.embedding,a,E);return r.record=t[s.index]||null,r.record&&(f(`best match: ${r.record.name} | id: ${r.record.id} | similarity: ${Math.round(1e3*s.similarity)/10}%`),e.name.value=r.record.name,e.source.style.display="",(m=e.source.getContext("2d"))==null||m.putImageData(r.record.image,0,0)),document.body.style.background=s.similarity>c.threshold?"darkgreen":"maroon",s.similarity>c.threshold}async function M(){var t,a;return o.faceCount=!1,o.faceConfidence=!1,o.facingCenter=!1,o.blinkDetected=!1,o.faceSize=!1,o.antispoofCheck=!1,o.livenessCheck=!1,o.elapsedMs=0,e.match.style.display="none",e.retry.style.display="none",e.source.style.display="none",document.body.style.background="black",await H(),await T(),S=n.now(),r.face=await L(),e.canvas.width=((t=r.face.tensor)==null?void 0:t.shape[1])||c.minSize,e.canvas.height=((a=r.face.tensor)==null?void 0:a.shape[0])||c.minSize,e.source.width=e.canvas.width,e.source.height=e.canvas.height,e.canvas.style.width="",e.match.style.display="flex",e.save.style.display="flex",e.delete.style.display="flex",e.retry.style.display="block",I()?j():(f("did not find valid face"),!1)}async function q(){var t,a;f("human version:",n.version,"| tfjs version:",n.tf.version["tfjs-core"]),f("face embedding model:",b.face.description.enabled?"faceres":"",(t=b.face.mobilefacenet)!=null&&t.enabled?"mobilefacenet":"",(a=b.face.insightface)!=null&&a.enabled?"insightface":""),f("options:",JSON.stringify(c).replace(/{|}|"|\[|\]/g,"").replace(/,/g," ")),k("loading..."),f("known face records:",await y()),await H(),await n.load(),k("initializing..."),e.retry.addEventListener("click",M),e.save.addEventListener("click",z),e.delete.addEventListener("click",P),await n.warmup(),await M()}window.onload=q; //# sourceMappingURL=index.js.map diff --git a/demo/faceid/index.js.map b/demo/faceid/index.js.map index 7f6023f4..c448e0ee 100644 --- a/demo/faceid/index.js.map +++ b/demo/faceid/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["index.ts", "indexdb.ts"], - "sourcesContent": ["/**\n * Human demo for browsers\n * @default Human Library\n * @summary \n * @author \n * @copyright \n * @license MIT\n */\n\nimport * as H from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human\nimport * as indexDb from './indexdb'; // methods to deal with indexdb\n\nconst humanConfig = { // user configuration for human, used to fine-tune behavior\n modelBasePath: '../../models',\n filter: { equalization: true }, // lets run with histogram equilizer\n face: {\n enabled: true,\n detector: { rotation: true, return: true, cropFactor: 1.6, mask: false }, // return tensor is used to get detected face image\n description: { enabled: true }, // default model for face descriptor extraction is faceres\n // mobilefacenet: { enabled: true, modelPath: 'https://vladmandic.github.io/human-models/models/mobilefacenet.json' }, // alternative model\n // insightface: { enabled: true, modelPath: 'https://vladmandic.github.io/insightface/models/insightface-mobilenet-swish.json' }, // alternative model\n iris: { enabled: true }, // needed to determine gaze direction\n emotion: { enabled: false }, // not needed\n antispoof: { enabled: true }, // enable optional antispoof module\n liveness: { enabled: true }, // enable optional liveness module\n },\n body: { enabled: false },\n hand: { enabled: false },\n object: { enabled: false },\n gesture: { enabled: true }, // parses face and iris gestures\n};\n\n// const matchOptions = { order: 2, multiplier: 1000, min: 0.0, max: 1.0 }; // for embedding model\nconst matchOptions = { order: 2, multiplier: 25, min: 0.2, max: 0.8 }; // for faceres model\n\nconst options = {\n minConfidence: 0.6, // overal face confidence for box, face, gender, real, live\n minSize: 224, // min input to face descriptor model before degradation\n maxTime: 10000, // max time before giving up\n blinkMin: 10, // minimum duration of a valid blink\n blinkMax: 800, // maximum duration of a valid blink\n threshold: 0.5, // minimum similarity\n mask: humanConfig.face.detector.mask,\n rotation: humanConfig.face.detector.rotation,\n cropFactor: humanConfig.face.detector.cropFactor,\n ...matchOptions,\n};\n\nconst ok = { // must meet all rules\n faceCount: false,\n faceConfidence: false,\n facingCenter: false,\n lookingCenter: false,\n blinkDetected: false,\n faceSize: false,\n antispoofCheck: false,\n livenessCheck: false,\n elapsedMs: 0, // total time while waiting for valid face\n};\nconst allOk = () => ok.faceCount && ok.faceSize && ok.blinkDetected && ok.facingCenter && ok.lookingCenter && ok.faceConfidence && ok.antispoofCheck && ok.livenessCheck;\nconst current: { face: H.FaceResult | null, record: indexDb.FaceRecord | null } = { face: null, record: null }; // current face record and matched database record\n\nconst blink = { // internal timers for blink start/end/duration\n start: 0,\n end: 0,\n time: 0,\n};\n\n// let db: Array<{ name: string, source: string, embedding: number[] }> = []; // holds loaded face descriptor database\nconst human = new H.Human(humanConfig); // create instance of human with overrides from user configuration\n\nhuman.env.perfadd = false; // is performance data showing instant or total values\nhuman.draw.options.font = 'small-caps 18px \"Lato\"'; // set font used to draw labels when using draw methods\nhuman.draw.options.lineHeight = 20;\n\nconst dom = { // grab instances of dom objects so we dont have to look them up later\n video: document.getElementById('video') as HTMLVideoElement,\n canvas: document.getElementById('canvas') as HTMLCanvasElement,\n log: document.getElementById('log') as HTMLPreElement,\n fps: document.getElementById('fps') as HTMLPreElement,\n match: document.getElementById('match') as HTMLDivElement,\n name: document.getElementById('name') as HTMLInputElement,\n save: document.getElementById('save') as HTMLSpanElement,\n delete: document.getElementById('delete') as HTMLSpanElement,\n retry: document.getElementById('retry') as HTMLDivElement,\n source: document.getElementById('source') as HTMLCanvasElement,\n ok: document.getElementById('ok') as HTMLDivElement,\n};\nconst timestamp = { detect: 0, draw: 0 }; // holds information used to calculate performance and possible memory leaks\nconst fps = { detect: 0, draw: 0 }; // holds calculated fps information for both detect and screen refresh\nlet startTime = 0;\n\nconst log = (...msg) => { // helper method to output messages\n dom.log.innerText += msg.join(' ') + '\\n';\n console.log(...msg); // eslint-disable-line no-console\n};\nconst printFPS = (msg) => dom.fps.innerText = msg; // print status element\n\nasync function webCam() { // initialize webcam\n printFPS('starting webcam...');\n // @ts-ignore resizeMode is not yet defined in tslib\n const cameraOptions: MediaStreamConstraints = { audio: false, video: { facingMode: 'user', resizeMode: 'none', width: { ideal: document.body.clientWidth } } };\n const stream: MediaStream = await navigator.mediaDevices.getUserMedia(cameraOptions);\n const ready = new Promise((resolve) => { dom.video.onloadeddata = () => resolve(true); });\n dom.video.srcObject = stream;\n dom.video.play();\n await ready;\n dom.canvas.width = dom.video.videoWidth;\n dom.canvas.height = dom.video.videoHeight;\n if (human.env.initial) log('video:', dom.video.videoWidth, dom.video.videoHeight, '|', stream.getVideoTracks()[0].label);\n dom.canvas.onclick = () => { // pause when clicked on screen and resume on next click\n if (dom.video.paused) dom.video.play();\n else dom.video.pause();\n };\n}\n\nasync function detectionLoop() { // main detection loop\n if (!dom.video.paused) {\n if (current.face && current.face.tensor) human.tf.dispose(current.face.tensor); // dispose previous tensor\n await human.detect(dom.video); // actual detection; were not capturing output in a local variable as it can also be reached via human.result\n const now = human.now();\n fps.detect = 1000 / (now - timestamp.detect);\n timestamp.detect = now;\n requestAnimationFrame(detectionLoop); // start new frame immediately\n }\n}\n\nasync function validationLoop(): Promise { // main screen refresh loop\n const interpolated = await human.next(human.result); // smoothen result using last-known results\n await human.draw.canvas(dom.video, dom.canvas); // draw canvas to screen\n await human.draw.all(dom.canvas, interpolated); // draw labels, boxes, lines, etc.\n const now = human.now();\n fps.draw = 1000 / (now - timestamp.draw);\n timestamp.draw = now;\n printFPS(`fps: ${fps.detect.toFixed(1).padStart(5, ' ')} detect | ${fps.draw.toFixed(1).padStart(5, ' ')} draw`); // write status\n ok.faceCount = human.result.face.length === 1; // must be exactly detected face\n if (ok.faceCount) { // skip the rest if no face\n const gestures: string[] = Object.values(human.result.gesture).map((gesture) => (gesture as H.GestureResult).gesture); // flatten all gestures\n if (gestures.includes('blink left eye') || gestures.includes('blink right eye')) blink.start = human.now(); // blink starts when eyes get closed\n if (blink.start > 0 && !gestures.includes('blink left eye') && !gestures.includes('blink right eye')) blink.end = human.now(); // if blink started how long until eyes are back open\n ok.blinkDetected = ok.blinkDetected || (Math.abs(blink.end - blink.start) > options.blinkMin && Math.abs(blink.end - blink.start) < options.blinkMax);\n if (ok.blinkDetected && blink.time === 0) blink.time = Math.trunc(blink.end - blink.start);\n ok.facingCenter = gestures.includes('facing center');\n ok.lookingCenter = gestures.includes('looking center'); // must face camera and look at camera\n ok.faceConfidence = (human.result.face[0].boxScore || 0) > options.minConfidence && (human.result.face[0].faceScore || 0) > options.minConfidence;\n ok.antispoofCheck = (human.result.face[0].real || 0) > options.minConfidence;\n ok.livenessCheck = (human.result.face[0].live || 0) > options.minConfidence;\n ok.faceSize = human.result.face[0].box[2] >= options.minSize && human.result.face[0].box[3] >= options.minSize;\n }\n let y = 32;\n for (const [key, val] of Object.entries(ok)) {\n let el = document.getElementById(`ok-${key}`);\n if (!el) {\n el = document.createElement('div');\n el.innerText = key;\n el.className = 'ok';\n el.style.top = `${y}px`;\n dom.ok.appendChild(el);\n }\n if (typeof val === 'boolean') el.style.backgroundColor = val ? 'lightgreen' : 'lightcoral';\n else el.innerText = `${key}:${val}`;\n y += 28;\n }\n if (allOk()) { // all criteria met\n dom.video.pause();\n return human.result.face[0];\n }\n if (ok.elapsedMs > options.maxTime) { // give up\n dom.video.pause();\n return human.result.face[0];\n }\n // run again\n ok.elapsedMs = Math.trunc(human.now() - startTime);\n return new Promise((resolve) => {\n setTimeout(async () => {\n const res = await validationLoop(); // run validation loop until conditions are met\n if (res) resolve(human.result.face[0]); // recursive promise resolve\n }, 30); // use to slow down refresh from max refresh rate to target of 30 fps\n });\n}\n\nasync function saveRecords() {\n if (dom.name.value.length > 0) {\n const image = dom.canvas.getContext('2d')?.getImageData(0, 0, dom.canvas.width, dom.canvas.height) as ImageData;\n const rec = { id: 0, name: dom.name.value, descriptor: current.face?.embedding as number[], image };\n await indexDb.save(rec);\n log('saved face record:', rec.name, 'descriptor length:', current.face?.embedding?.length);\n log('known face records:', await indexDb.count());\n } else {\n log('invalid name');\n }\n}\n\nasync function deleteRecord() {\n if (current.record && current.record.id > 0) {\n await indexDb.remove(current.record);\n }\n}\n\nasync function detectFace() {\n dom.canvas.getContext('2d')?.clearRect(0, 0, options.minSize, options.minSize);\n if (!current.face || !current.face.tensor || !current.face.embedding) return false;\n console.log('face record:', current.face); // eslint-disable-line no-console\n human.tf.browser.toPixels(current.face.tensor as unknown as H.TensorLike, dom.canvas);\n if (await indexDb.count() === 0) {\n log('face database is empty');\n document.body.style.background = 'black';\n dom.delete.style.display = 'none';\n return false;\n }\n const db = await indexDb.load();\n const descriptors = db.map((rec) => rec.descriptor).filter((desc) => desc.length > 0);\n const res = await human.match(current.face.embedding, descriptors, matchOptions);\n current.record = db[res.index] || null;\n if (current.record) {\n log(`best match: ${current.record.name} | id: ${current.record.id} | similarity: ${Math.round(1000 * res.similarity) / 10}%`);\n dom.name.value = current.record.name;\n dom.source.style.display = '';\n dom.source.getContext('2d')?.putImageData(current.record.image, 0, 0);\n }\n document.body.style.background = res.similarity > options.threshold ? 'darkgreen' : 'maroon';\n return res.similarity > options.threshold;\n}\n\nasync function main() { // main entry point\n ok.faceCount = false;\n ok.faceConfidence = false;\n ok.facingCenter = false;\n ok.blinkDetected = false;\n ok.faceSize = false;\n ok.antispoofCheck = false;\n ok.livenessCheck = false;\n ok.elapsedMs = 0;\n dom.match.style.display = 'none';\n dom.retry.style.display = 'none';\n dom.source.style.display = 'none';\n document.body.style.background = 'black';\n await webCam();\n await detectionLoop(); // start detection loop\n startTime = human.now();\n current.face = await validationLoop(); // start validation loop\n dom.canvas.width = current.face.tensor?.shape[1] || options.minSize;\n dom.canvas.height = current.face.tensor?.shape[0] || options.minSize;\n dom.source.width = dom.canvas.width;\n dom.source.height = dom.canvas.height;\n dom.canvas.style.width = '';\n dom.match.style.display = 'flex';\n dom.save.style.display = 'flex';\n dom.delete.style.display = 'flex';\n dom.retry.style.display = 'block';\n if (!allOk()) { // is all criteria met?\n log('did not find valid face');\n return false;\n }\n return detectFace();\n}\n\nasync function init() {\n log('human version:', human.version, '| tfjs version:', human.tf.version['tfjs-core']);\n log('face embedding model:', humanConfig.face.description.enabled ? 'faceres' : '', humanConfig.face['mobilefacenet']?.enabled ? 'mobilefacenet' : '', humanConfig.face['insightface']?.enabled ? 'insightface' : '');\n log('options:', JSON.stringify(options).replace(/{|}|\"|\\[|\\]/g, '').replace(/,/g, ' '));\n printFPS('loading...');\n log('known face records:', await indexDb.count());\n await webCam(); // start webcam\n await human.load(); // preload all models\n printFPS('initializing...');\n dom.retry.addEventListener('click', main);\n dom.save.addEventListener('click', saveRecords);\n dom.delete.addEventListener('click', deleteRecord);\n await human.warmup(); // warmup function to initialize backend for future faster detection\n await main();\n}\n\nwindow.onload = init;\n", "let db: IDBDatabase; // instance of indexdb\n\nconst database = 'human';\nconst table = 'person';\n\nexport interface FaceRecord { id: number, name: string, descriptor: number[], image: ImageData }\n\nconst log = (...msg) => console.log('indexdb', ...msg); // eslint-disable-line no-console\n\nexport async function open() {\n if (db) return true;\n return new Promise((resolve) => {\n const request: IDBOpenDBRequest = indexedDB.open(database, 1);\n request.onerror = (evt) => log('error:', evt);\n request.onupgradeneeded = (evt: IDBVersionChangeEvent) => { // create if doesnt exist\n log('create:', evt.target);\n db = (evt.target as IDBOpenDBRequest).result;\n db.createObjectStore(table, { keyPath: 'id', autoIncrement: true });\n };\n request.onsuccess = (evt) => { // open\n db = (evt.target as IDBOpenDBRequest).result;\n log('open:', db);\n resolve(true);\n };\n });\n}\n\nexport async function load(): Promise {\n const faceDB: FaceRecord[] = [];\n if (!db) await open(); // open or create if not already done\n return new Promise((resolve) => {\n const cursor: IDBRequest = db.transaction([table], 'readwrite').objectStore(table).openCursor(null, 'next');\n cursor.onerror = (evt) => log('load error:', evt);\n cursor.onsuccess = (evt) => {\n if ((evt.target as IDBRequest).result) {\n faceDB.push((evt.target as IDBRequest).result.value);\n (evt.target as IDBRequest).result.continue();\n } else {\n resolve(faceDB);\n }\n };\n });\n}\n\nexport async function count(): Promise {\n if (!db) await open(); // open or create if not already done\n return new Promise((resolve) => {\n const store: IDBRequest = db.transaction([table], 'readwrite').objectStore(table).count();\n store.onerror = (evt) => log('count error:', evt);\n store.onsuccess = () => resolve(store.result);\n });\n}\n\nexport async function save(faceRecord: FaceRecord) {\n if (!db) await open(); // open or create if not already done\n const newRecord = { name: faceRecord.name, descriptor: faceRecord.descriptor, image: faceRecord.image }; // omit id as its autoincrement\n db.transaction([table], 'readwrite').objectStore(table).put(newRecord);\n log('save:', newRecord);\n}\n\nexport async function remove(faceRecord: FaceRecord) {\n if (!db) await open(); // open or create if not already done\n db.transaction([table], 'readwrite').objectStore(table).delete(faceRecord.id); // delete based on id\n log('delete:', faceRecord);\n}\n"], - "mappings": "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", - "names": ["H", "db", "database", "table", "log", "msg", "open", "resolve", "request", "evt", "load", "faceDB", "cursor", "count", "store", "save", "faceRecord", "newRecord", "remove", "humanConfig", "matchOptions", "options", "ok", "allOk", "current", "blink", "human", "dom", "timestamp", "fps", "startTime", "log", "msg", "printFPS", "webCam", "cameraOptions", "stream", "ready", "resolve", "detectionLoop", "now", "validationLoop", "interpolated", "gestures", "gesture", "y", "key", "val", "el", "saveRecords", "_a", "_b", "_c", "_d", "image", "rec", "save", "count", "deleteRecord", "remove", "detectFace", "db", "load", "descriptors", "desc", "res", "main", "init"] + "sourcesContent": ["/**\n * Human demo for browsers\n * @default Human Library\n * @summary \n * @author \n * @copyright \n * @license MIT\n */\n\nimport * as H from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human\nimport * as indexDb from './indexdb'; // methods to deal with indexdb\n\nconst humanConfig = { // user configuration for human, used to fine-tune behavior\n modelBasePath: '../../models',\n filter: { equalization: true }, // lets run with histogram equilizer\n face: {\n enabled: true,\n detector: { rotation: true, return: true, cropFactor: 1.6, mask: false }, // return tensor is used to get detected face image\n description: { enabled: true }, // default model for face descriptor extraction is faceres\n // mobilefacenet: { enabled: true, modelPath: 'https://vladmandic.github.io/human-models/models/mobilefacenet.json' }, // alternative model\n // insightface: { enabled: true, modelPath: 'https://vladmandic.github.io/insightface/models/insightface-mobilenet-swish.json' }, // alternative model\n iris: { enabled: true }, // needed to determine gaze direction\n emotion: { enabled: false }, // not needed\n antispoof: { enabled: true }, // enable optional antispoof module\n liveness: { enabled: true }, // enable optional liveness module\n },\n body: { enabled: false },\n hand: { enabled: false },\n object: { enabled: false },\n gesture: { enabled: true }, // parses face and iris gestures\n};\n\n// const matchOptions = { order: 2, multiplier: 1000, min: 0.0, max: 1.0 }; // for embedding model\nconst matchOptions = { order: 2, multiplier: 25, min: 0.2, max: 0.8 }; // for faceres model\n\nconst options = {\n minConfidence: 0.6, // overal face confidence for box, face, gender, real, live\n minSize: 224, // min input to face descriptor model before degradation\n maxTime: 10000, // max time before giving up\n blinkMin: 10, // minimum duration of a valid blink\n blinkMax: 800, // maximum duration of a valid blink\n threshold: 0.5, // minimum similarity\n mask: humanConfig.face.detector.mask,\n rotation: humanConfig.face.detector.rotation,\n cropFactor: humanConfig.face.detector.cropFactor,\n ...matchOptions,\n};\n\nconst ok = { // must meet all rules\n faceCount: false,\n faceConfidence: false,\n facingCenter: false,\n lookingCenter: false,\n blinkDetected: false,\n faceSize: false,\n antispoofCheck: false,\n livenessCheck: false,\n elapsedMs: 0, // total time while waiting for valid face\n};\nconst allOk = () => ok.faceCount && ok.faceSize && ok.blinkDetected && ok.facingCenter && ok.lookingCenter && ok.faceConfidence && ok.antispoofCheck && ok.livenessCheck;\nconst current: { face: H.FaceResult | null, record: indexDb.FaceRecord | null } = { face: null, record: null }; // current face record and matched database record\n\nconst blink = { // internal timers for blink start/end/duration\n start: 0,\n end: 0,\n time: 0,\n};\n\n// let db: Array<{ name: string, source: string, embedding: number[] }> = []; // holds loaded face descriptor database\nconst human = new H.Human(humanConfig); // create instance of human with overrides from user configuration\n\nhuman.env.perfadd = false; // is performance data showing instant or total values\nhuman.draw.options.font = 'small-caps 18px \"Lato\"'; // set font used to draw labels when using draw methods\nhuman.draw.options.lineHeight = 20;\n\nconst dom = { // grab instances of dom objects so we dont have to look them up later\n video: document.getElementById('video') as HTMLVideoElement,\n canvas: document.getElementById('canvas') as HTMLCanvasElement,\n log: document.getElementById('log') as HTMLPreElement,\n fps: document.getElementById('fps') as HTMLPreElement,\n match: document.getElementById('match') as HTMLDivElement,\n name: document.getElementById('name') as HTMLInputElement,\n save: document.getElementById('save') as HTMLSpanElement,\n delete: document.getElementById('delete') as HTMLSpanElement,\n retry: document.getElementById('retry') as HTMLDivElement,\n source: document.getElementById('source') as HTMLCanvasElement,\n ok: document.getElementById('ok') as HTMLDivElement,\n};\nconst timestamp = { detect: 0, draw: 0 }; // holds information used to calculate performance and possible memory leaks\nconst fps = { detect: 0, draw: 0 }; // holds calculated fps information for both detect and screen refresh\nlet startTime = 0;\n\nconst log = (...msg) => { // helper method to output messages\n dom.log.innerText += msg.join(' ') + '\\n';\n console.log(...msg); // eslint-disable-line no-console\n};\nconst printFPS = (msg) => dom.fps.innerText = msg; // print status element\n\nasync function webCam() { // initialize webcam\n printFPS('starting webcam...');\n // @ts-ignore resizeMode is not yet defined in tslib\n const cameraOptions: MediaStreamConstraints = { audio: false, video: { facingMode: 'user', resizeMode: 'none', width: { ideal: document.body.clientWidth } } };\n const stream: MediaStream = await navigator.mediaDevices.getUserMedia(cameraOptions);\n const ready = new Promise((resolve) => { dom.video.onloadeddata = () => resolve(true); });\n dom.video.srcObject = stream;\n void dom.video.play();\n await ready;\n dom.canvas.width = dom.video.videoWidth;\n dom.canvas.height = dom.video.videoHeight;\n if (human.env.initial) log('video:', dom.video.videoWidth, dom.video.videoHeight, '|', stream.getVideoTracks()[0].label);\n dom.canvas.onclick = () => { // pause when clicked on screen and resume on next click\n if (dom.video.paused) void dom.video.play();\n else dom.video.pause();\n };\n}\n\nasync function detectionLoop() { // main detection loop\n if (!dom.video.paused) {\n if (current.face?.tensor) human.tf.dispose(current.face.tensor); // dispose previous tensor\n await human.detect(dom.video); // actual detection; were not capturing output in a local variable as it can also be reached via human.result\n const now = human.now();\n fps.detect = 1000 / (now - timestamp.detect);\n timestamp.detect = now;\n requestAnimationFrame(detectionLoop); // start new frame immediately\n }\n}\n\nasync function validationLoop(): Promise { // main screen refresh loop\n const interpolated = human.next(human.result); // smoothen result using last-known results\n human.draw.canvas(dom.video, dom.canvas); // draw canvas to screen\n await human.draw.all(dom.canvas, interpolated); // draw labels, boxes, lines, etc.\n const now = human.now();\n fps.draw = 1000 / (now - timestamp.draw);\n timestamp.draw = now;\n printFPS(`fps: ${fps.detect.toFixed(1).padStart(5, ' ')} detect | ${fps.draw.toFixed(1).padStart(5, ' ')} draw`); // write status\n ok.faceCount = human.result.face.length === 1; // must be exactly detected face\n if (ok.faceCount) { // skip the rest if no face\n const gestures: string[] = Object.values(human.result.gesture).map((gesture: H.GestureResult) => gesture.gesture); // flatten all gestures\n if (gestures.includes('blink left eye') || gestures.includes('blink right eye')) blink.start = human.now(); // blink starts when eyes get closed\n if (blink.start > 0 && !gestures.includes('blink left eye') && !gestures.includes('blink right eye')) blink.end = human.now(); // if blink started how long until eyes are back open\n ok.blinkDetected = ok.blinkDetected || (Math.abs(blink.end - blink.start) > options.blinkMin && Math.abs(blink.end - blink.start) < options.blinkMax);\n if (ok.blinkDetected && blink.time === 0) blink.time = Math.trunc(blink.end - blink.start);\n ok.facingCenter = gestures.includes('facing center');\n ok.lookingCenter = gestures.includes('looking center'); // must face camera and look at camera\n ok.faceConfidence = (human.result.face[0].boxScore || 0) > options.minConfidence && (human.result.face[0].faceScore || 0) > options.minConfidence;\n ok.antispoofCheck = (human.result.face[0].real || 0) > options.minConfidence;\n ok.livenessCheck = (human.result.face[0].live || 0) > options.minConfidence;\n ok.faceSize = human.result.face[0].box[2] >= options.minSize && human.result.face[0].box[3] >= options.minSize;\n }\n let y = 32;\n for (const [key, val] of Object.entries(ok)) {\n let el = document.getElementById(`ok-${key}`);\n if (!el) {\n el = document.createElement('div');\n el.innerText = key;\n el.className = 'ok';\n el.style.top = `${y}px`;\n dom.ok.appendChild(el);\n }\n if (typeof val === 'boolean') el.style.backgroundColor = val ? 'lightgreen' : 'lightcoral';\n else el.innerText = `${key}:${val}`;\n y += 28;\n }\n if (allOk()) { // all criteria met\n dom.video.pause();\n return human.result.face[0];\n }\n if (ok.elapsedMs > options.maxTime) { // give up\n dom.video.pause();\n return human.result.face[0];\n }\n // run again\n ok.elapsedMs = Math.trunc(human.now() - startTime);\n return new Promise((resolve) => {\n setTimeout(async () => {\n await validationLoop(); // run validation loop until conditions are met\n resolve(human.result.face[0]); // recursive promise resolve\n }, 30); // use to slow down refresh from max refresh rate to target of 30 fps\n });\n}\n\nasync function saveRecords() {\n if (dom.name.value.length > 0) {\n const image = dom.canvas.getContext('2d')?.getImageData(0, 0, dom.canvas.width, dom.canvas.height) as ImageData;\n const rec = { id: 0, name: dom.name.value, descriptor: current.face?.embedding as number[], image };\n await indexDb.save(rec);\n log('saved face record:', rec.name, 'descriptor length:', current.face?.embedding?.length);\n log('known face records:', await indexDb.count());\n } else {\n log('invalid name');\n }\n}\n\nasync function deleteRecord() {\n if (current.record && current.record.id > 0) {\n await indexDb.remove(current.record);\n }\n}\n\nasync function detectFace() {\n dom.canvas.getContext('2d')?.clearRect(0, 0, options.minSize, options.minSize);\n if (!current.face || !current.face.tensor || !current.face.embedding) return false;\n console.log('face record:', current.face); // eslint-disable-line no-console\n human.tf.browser.toPixels(current.face.tensor as unknown as H.TensorLike, dom.canvas);\n if (await indexDb.count() === 0) {\n log('face database is empty');\n document.body.style.background = 'black';\n dom.delete.style.display = 'none';\n return false;\n }\n const db = await indexDb.load();\n const descriptors = db.map((rec) => rec.descriptor).filter((desc) => desc.length > 0);\n const res = human.match(current.face.embedding, descriptors, matchOptions);\n current.record = db[res.index] || null;\n if (current.record) {\n log(`best match: ${current.record.name} | id: ${current.record.id} | similarity: ${Math.round(1000 * res.similarity) / 10}%`);\n dom.name.value = current.record.name;\n dom.source.style.display = '';\n dom.source.getContext('2d')?.putImageData(current.record.image, 0, 0);\n }\n document.body.style.background = res.similarity > options.threshold ? 'darkgreen' : 'maroon';\n return res.similarity > options.threshold;\n}\n\nasync function main() { // main entry point\n ok.faceCount = false;\n ok.faceConfidence = false;\n ok.facingCenter = false;\n ok.blinkDetected = false;\n ok.faceSize = false;\n ok.antispoofCheck = false;\n ok.livenessCheck = false;\n ok.elapsedMs = 0;\n dom.match.style.display = 'none';\n dom.retry.style.display = 'none';\n dom.source.style.display = 'none';\n document.body.style.background = 'black';\n await webCam();\n await detectionLoop(); // start detection loop\n startTime = human.now();\n current.face = await validationLoop(); // start validation loop\n dom.canvas.width = current.face.tensor?.shape[1] || options.minSize;\n dom.canvas.height = current.face.tensor?.shape[0] || options.minSize;\n dom.source.width = dom.canvas.width;\n dom.source.height = dom.canvas.height;\n dom.canvas.style.width = '';\n dom.match.style.display = 'flex';\n dom.save.style.display = 'flex';\n dom.delete.style.display = 'flex';\n dom.retry.style.display = 'block';\n if (!allOk()) { // is all criteria met?\n log('did not find valid face');\n return false;\n }\n return detectFace();\n}\n\nasync function init() {\n log('human version:', human.version, '| tfjs version:', human.tf.version['tfjs-core']);\n log('face embedding model:', humanConfig.face.description.enabled ? 'faceres' : '', humanConfig.face['mobilefacenet']?.enabled ? 'mobilefacenet' : '', humanConfig.face['insightface']?.enabled ? 'insightface' : '');\n log('options:', JSON.stringify(options).replace(/{|}|\"|\\[|\\]/g, '').replace(/,/g, ' '));\n printFPS('loading...');\n log('known face records:', await indexDb.count());\n await webCam(); // start webcam\n await human.load(); // preload all models\n printFPS('initializing...');\n dom.retry.addEventListener('click', main);\n dom.save.addEventListener('click', saveRecords);\n dom.delete.addEventListener('click', deleteRecord);\n await human.warmup(); // warmup function to initialize backend for future faster detection\n await main();\n}\n\nwindow.onload = init;\n", "let db: IDBDatabase; // instance of indexdb\n\nconst database = 'human';\nconst table = 'person';\n\nexport interface FaceRecord { id: number, name: string, descriptor: number[], image: ImageData }\n\nconst log = (...msg) => console.log('indexdb', ...msg); // eslint-disable-line no-console\n\nexport async function open() {\n if (db) return true;\n return new Promise((resolve) => {\n const request: IDBOpenDBRequest = indexedDB.open(database, 1);\n request.onerror = (evt) => log('error:', evt);\n request.onupgradeneeded = (evt: IDBVersionChangeEvent) => { // create if doesnt exist\n log('create:', evt.target);\n db = (evt.target as IDBOpenDBRequest).result;\n db.createObjectStore(table, { keyPath: 'id', autoIncrement: true });\n };\n request.onsuccess = (evt) => { // open\n db = (evt.target as IDBOpenDBRequest).result;\n log('open:', db);\n resolve(true);\n };\n });\n}\n\nexport async function load(): Promise {\n const faceDB: FaceRecord[] = [];\n if (!db) await open(); // open or create if not already done\n return new Promise((resolve) => {\n const cursor: IDBRequest = db.transaction([table], 'readwrite').objectStore(table).openCursor(null, 'next');\n cursor.onerror = (evt) => log('load error:', evt);\n cursor.onsuccess = (evt) => {\n if ((evt.target as IDBRequest).result) {\n faceDB.push((evt.target as IDBRequest).result.value);\n (evt.target as IDBRequest).result.continue();\n } else {\n resolve(faceDB);\n }\n };\n });\n}\n\nexport async function count(): Promise {\n if (!db) await open(); // open or create if not already done\n return new Promise((resolve) => {\n const store: IDBRequest = db.transaction([table], 'readwrite').objectStore(table).count();\n store.onerror = (evt) => log('count error:', evt);\n store.onsuccess = () => resolve(store.result);\n });\n}\n\nexport async function save(faceRecord: FaceRecord) {\n if (!db) await open(); // open or create if not already done\n const newRecord = { name: faceRecord.name, descriptor: faceRecord.descriptor, image: faceRecord.image }; // omit id as its autoincrement\n db.transaction([table], 'readwrite').objectStore(table).put(newRecord);\n log('save:', newRecord);\n}\n\nexport async function remove(faceRecord: FaceRecord) {\n if (!db) await open(); // open or create if not already done\n db.transaction([table], 'readwrite').objectStore(table).delete(faceRecord.id); // delete based on id\n log('delete:', faceRecord);\n}\n"], + "mappings": "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", + "names": ["H", "db", "database", "table", "log", "msg", "open", "resolve", "request", "evt", "load", "faceDB", "cursor", "count", "store", "save", "faceRecord", "newRecord", "remove", "humanConfig", "matchOptions", "options", "ok", "allOk", "current", "blink", "human", "dom", "timestamp", "fps", "startTime", "log", "msg", "printFPS", "webCam", "cameraOptions", "stream", "ready", "resolve", "detectionLoop", "_a", "now", "validationLoop", "interpolated", "gestures", "gesture", "y", "key", "val", "el", "saveRecords", "_b", "_c", "_d", "image", "rec", "save", "count", "deleteRecord", "remove", "detectFace", "db", "load", "descriptors", "desc", "res", "main", "init"] } diff --git a/demo/faceid/index.ts b/demo/faceid/index.ts index 0abf6ef1..eaecb971 100644 --- a/demo/faceid/index.ts +++ b/demo/faceid/index.ts @@ -103,20 +103,20 @@ async function webCam() { // initialize webcam const stream: MediaStream = await navigator.mediaDevices.getUserMedia(cameraOptions); const ready = new Promise((resolve) => { dom.video.onloadeddata = () => resolve(true); }); dom.video.srcObject = stream; - dom.video.play(); + void dom.video.play(); await ready; dom.canvas.width = dom.video.videoWidth; dom.canvas.height = dom.video.videoHeight; if (human.env.initial) log('video:', dom.video.videoWidth, dom.video.videoHeight, '|', stream.getVideoTracks()[0].label); dom.canvas.onclick = () => { // pause when clicked on screen and resume on next click - if (dom.video.paused) dom.video.play(); + if (dom.video.paused) void dom.video.play(); else dom.video.pause(); }; } async function detectionLoop() { // main detection loop if (!dom.video.paused) { - if (current.face && current.face.tensor) human.tf.dispose(current.face.tensor); // dispose previous tensor + if (current.face?.tensor) human.tf.dispose(current.face.tensor); // dispose previous tensor await human.detect(dom.video); // actual detection; were not capturing output in a local variable as it can also be reached via human.result const now = human.now(); fps.detect = 1000 / (now - timestamp.detect); @@ -126,8 +126,8 @@ async function detectionLoop() { // main detection loop } async function validationLoop(): Promise { // main screen refresh loop - const interpolated = await human.next(human.result); // smoothen result using last-known results - await human.draw.canvas(dom.video, dom.canvas); // draw canvas to screen + const interpolated = human.next(human.result); // smoothen result using last-known results + human.draw.canvas(dom.video, dom.canvas); // draw canvas to screen await human.draw.all(dom.canvas, interpolated); // draw labels, boxes, lines, etc. const now = human.now(); fps.draw = 1000 / (now - timestamp.draw); @@ -135,7 +135,7 @@ async function validationLoop(): Promise { // main screen refresh printFPS(`fps: ${fps.detect.toFixed(1).padStart(5, ' ')} detect | ${fps.draw.toFixed(1).padStart(5, ' ')} draw`); // write status ok.faceCount = human.result.face.length === 1; // must be exactly detected face if (ok.faceCount) { // skip the rest if no face - const gestures: string[] = Object.values(human.result.gesture).map((gesture) => (gesture as H.GestureResult).gesture); // flatten all gestures + const gestures: string[] = Object.values(human.result.gesture).map((gesture: H.GestureResult) => gesture.gesture); // flatten all gestures if (gestures.includes('blink left eye') || gestures.includes('blink right eye')) blink.start = human.now(); // blink starts when eyes get closed if (blink.start > 0 && !gestures.includes('blink left eye') && !gestures.includes('blink right eye')) blink.end = human.now(); // if blink started how long until eyes are back open ok.blinkDetected = ok.blinkDetected || (Math.abs(blink.end - blink.start) > options.blinkMin && Math.abs(blink.end - blink.start) < options.blinkMax); @@ -173,8 +173,8 @@ async function validationLoop(): Promise { // main screen refresh ok.elapsedMs = Math.trunc(human.now() - startTime); return new Promise((resolve) => { setTimeout(async () => { - const res = await validationLoop(); // run validation loop until conditions are met - if (res) resolve(human.result.face[0]); // recursive promise resolve + await validationLoop(); // run validation loop until conditions are met + resolve(human.result.face[0]); // recursive promise resolve }, 30); // use to slow down refresh from max refresh rate to target of 30 fps }); } @@ -210,7 +210,7 @@ async function detectFace() { } const db = await indexDb.load(); const descriptors = db.map((rec) => rec.descriptor).filter((desc) => desc.length > 0); - const res = await human.match(current.face.embedding, descriptors, matchOptions); + const res = human.match(current.face.embedding, descriptors, matchOptions); current.record = db[res.index] || null; if (current.record) { log(`best match: ${current.record.name} | id: ${current.record.id} | similarity: ${Math.round(1000 * res.similarity) / 10}%`); diff --git a/demo/typescript/index.js b/demo/typescript/index.js index 657dfb81..1fd213b1 100644 --- a/demo/typescript/index.js +++ b/demo/typescript/index.js @@ -4,6 +4,6 @@ author: ' */ -import*as c from"../../dist/human.esm.js";var w={async:!1,modelBasePath:"../../models",filter:{enabled:!0,equalization:!1,flip:!1},face:{enabled:!0,detector:{rotation:!1},mesh:{enabled:!0},attention:{enabled:!1},iris:{enabled:!0},description:{enabled:!0},emotion:{enabled:!0}},body:{enabled:!0},hand:{enabled:!0},object:{enabled:!1},gesture:{enabled:!0}},e=new c.Human(w);e.env.perfadd=!1;e.draw.options.font='small-caps 18px "Lato"';e.draw.options.lineHeight=20;var t={video:document.getElementById("video"),canvas:document.getElementById("canvas"),log:document.getElementById("log"),fps:document.getElementById("status"),perf:document.getElementById("performance")},n={detect:0,draw:0,tensors:0,start:0},s={detectFPS:0,drawFPS:0,frames:0,averageMs:0},i=(...a)=>{t.log.innerText+=a.join(" ")+` -`,console.log(...a)},r=a=>t.fps.innerText=a,b=a=>t.perf.innerText="tensors:"+e.tf.memory().numTensors+" | performance: "+JSON.stringify(a).replace(/"|{|}/g,"").replace(/,/g," | ");async function h(){r("starting webcam...");let a={audio:!1,video:{facingMode:"user",resizeMode:"none",width:{ideal:document.body.clientWidth},height:{ideal:document.body.clientHeight}}},d=await navigator.mediaDevices.getUserMedia(a),f=new Promise(p=>{t.video.onloadeddata=()=>p(!0)});t.video.srcObject=d,t.video.play(),await f,t.canvas.width=t.video.videoWidth,t.canvas.height=t.video.videoHeight;let o=d.getVideoTracks()[0],v=o.getCapabilities?o.getCapabilities():"",g=o.getSettings?o.getSettings():"",u=o.getConstraints?o.getConstraints():"";i("video:",t.video.videoWidth,t.video.videoHeight,o.label,{stream:d,track:o,settings:g,constraints:u,capabilities:v}),t.canvas.onclick=()=>{t.video.paused?t.video.play():t.video.pause()}}async function l(){if(!t.video.paused){n.start===0&&(n.start=e.now()),await e.detect(t.video);let a=e.tf.memory().numTensors;a-n.tensors!==0&&i("allocated tensors:",a-n.tensors),n.tensors=a,s.detectFPS=Math.round(1e3*1e3/(e.now()-n.detect))/1e3,s.frames++,s.averageMs=Math.round(1e3*(e.now()-n.start)/s.frames)/1e3,s.frames%100===0&&!t.video.paused&&i("performance",{...s,tensors:n.tensors})}n.detect=e.now(),requestAnimationFrame(l)}async function m(){if(!t.video.paused){let d=await e.next(e.result);e.config.filter.flip?await e.draw.canvas(d.canvas,t.canvas):await e.draw.canvas(t.video,t.canvas),await e.draw.all(t.canvas,d),b(d.performance)}let a=e.now();s.drawFPS=Math.round(1e3*1e3/(a-n.draw))/1e3,n.draw=a,r(t.video.paused?"paused":`fps: ${s.detectFPS.toFixed(1).padStart(5," ")} detect | ${s.drawFPS.toFixed(1).padStart(5," ")} draw`),setTimeout(m,30)}async function M(){i("human version:",e.version,"| tfjs version:",e.tf.version["tfjs-core"]),i("platform:",e.env.platform,"| agent:",e.env.agent),r("loading..."),await e.load(),i("backend:",e.tf.getBackend(),"| available:",e.env.backends),i("models stats:",e.getModelStats()),i("models loaded:",Object.values(e.models).filter(a=>a!==null).length),r("initializing..."),await e.warmup(),await h(),await l(),await m()}window.onload=M; +import*as c from"../../dist/human.esm.js";var w={async:!1,modelBasePath:"../../models",filter:{enabled:!0,equalization:!1,flip:!1},face:{enabled:!0,detector:{rotation:!1},mesh:{enabled:!0},attention:{enabled:!1},iris:{enabled:!0},description:{enabled:!0},emotion:{enabled:!0}},body:{enabled:!0},hand:{enabled:!0},object:{enabled:!1},gesture:{enabled:!0}},e=new c.Human(w);e.env.perfadd=!1;e.draw.options.font='small-caps 18px "Lato"';e.draw.options.lineHeight=20;var t={video:document.getElementById("video"),canvas:document.getElementById("canvas"),log:document.getElementById("log"),fps:document.getElementById("status"),perf:document.getElementById("performance")},n={detect:0,draw:0,tensors:0,start:0},o={detectFPS:0,drawFPS:0,frames:0,averageMs:0},i=(...a)=>{t.log.innerText+=a.join(" ")+` +`,console.log(...a)},r=a=>t.fps.innerText=a,b=a=>t.perf.innerText="tensors:"+e.tf.memory().numTensors.toString()+" | performance: "+JSON.stringify(a).replace(/"|{|}/g,"").replace(/,/g," | ");async function h(){r("starting webcam...");let a={audio:!1,video:{facingMode:"user",resizeMode:"none",width:{ideal:document.body.clientWidth},height:{ideal:document.body.clientHeight}}},d=await navigator.mediaDevices.getUserMedia(a),f=new Promise(p=>{t.video.onloadeddata=()=>p(!0)});t.video.srcObject=d,t.video.play(),await f,t.canvas.width=t.video.videoWidth,t.canvas.height=t.video.videoHeight;let s=d.getVideoTracks()[0],v=s.getCapabilities?s.getCapabilities():"",g=s.getSettings?s.getSettings():"",u=s.getConstraints?s.getConstraints():"";i("video:",t.video.videoWidth,t.video.videoHeight,s.label,{stream:d,track:s,settings:g,constraints:u,capabilities:v}),t.canvas.onclick=()=>{t.video.paused?t.video.play():t.video.pause()}}async function l(){if(!t.video.paused){n.start===0&&(n.start=e.now()),await e.detect(t.video);let a=e.tf.memory().numTensors;a-n.tensors!==0&&i("allocated tensors:",a-n.tensors),n.tensors=a,o.detectFPS=Math.round(1e3*1e3/(e.now()-n.detect))/1e3,o.frames++,o.averageMs=Math.round(1e3*(e.now()-n.start)/o.frames)/1e3,o.frames%100===0&&!t.video.paused&&i("performance",{...o,tensors:n.tensors})}n.detect=e.now(),requestAnimationFrame(l)}async function m(){if(!t.video.paused){let d=e.next(e.result);e.config.filter.flip?e.draw.canvas(d.canvas,t.canvas):e.draw.canvas(t.video,t.canvas),await e.draw.all(t.canvas,d),b(d.performance)}let a=e.now();o.drawFPS=Math.round(1e3*1e3/(a-n.draw))/1e3,n.draw=a,r(t.video.paused?"paused":`fps: ${o.detectFPS.toFixed(1).padStart(5," ")} detect | ${o.drawFPS.toFixed(1).padStart(5," ")} draw`),setTimeout(m,30)}async function M(){i("human version:",e.version,"| tfjs version:",e.tf.version["tfjs-core"]),i("platform:",e.env.platform,"| agent:",e.env.agent),r("loading..."),await e.load(),i("backend:",e.tf.getBackend(),"| available:",e.env.backends),i("models stats:",e.getModelStats()),i("models loaded:",Object.values(e.models).filter(a=>a!==null).length),r("initializing..."),await e.warmup(),await h(),await l(),await m()}window.onload=M; //# sourceMappingURL=index.js.map diff --git a/demo/typescript/index.js.map b/demo/typescript/index.js.map index d60e5866..c395667a 100644 --- a/demo/typescript/index.js.map +++ b/demo/typescript/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["index.ts"], - "sourcesContent": ["/**\n * Human demo for browsers\n * @default Human Library\n * @summary \n * @author \n * @copyright \n * @license MIT\n */\n\nimport * as H from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human\n\nconst humanConfig: Partial = { // user configuration for human, used to fine-tune behavior\n // backend: 'wasm' as const,\n // wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.18.0/dist/',\n // cacheSensitivity: 0,\n async: false,\n modelBasePath: '../../models',\n filter: { enabled: true, equalization: false, flip: false },\n face: { enabled: true, detector: { rotation: false }, mesh: { enabled: true }, attention: { enabled: false }, iris: { enabled: true }, description: { enabled: true }, emotion: { enabled: true } },\n body: { enabled: true },\n hand: { enabled: true },\n object: { enabled: false },\n gesture: { enabled: true },\n};\n\nconst human = new H.Human(humanConfig); // create instance of human with overrides from user configuration\n\nhuman.env.perfadd = false; // is performance data showing instant or total values\nhuman.draw.options.font = 'small-caps 18px \"Lato\"'; // set font used to draw labels when using draw methods\nhuman.draw.options.lineHeight = 20;\n// human.draw.options.fillPolygons = true;\n\nconst dom = { // grab instances of dom objects so we dont have to look them up later\n video: document.getElementById('video') as HTMLVideoElement,\n canvas: document.getElementById('canvas') as HTMLCanvasElement,\n log: document.getElementById('log') as HTMLPreElement,\n fps: document.getElementById('status') as HTMLPreElement,\n perf: document.getElementById('performance') as HTMLDivElement,\n};\nconst timestamp = { detect: 0, draw: 0, tensors: 0, start: 0 }; // holds information used to calculate performance and possible memory leaks\nconst fps = { detectFPS: 0, drawFPS: 0, frames: 0, averageMs: 0 }; // holds calculated fps information for both detect and screen refresh\n\nconst log = (...msg) => { // helper method to output messages\n dom.log.innerText += msg.join(' ') + '\\n';\n console.log(...msg); // eslint-disable-line no-console\n};\nconst status = (msg) => dom.fps.innerText = msg; // print status element\nconst perf = (msg) => dom.perf.innerText = 'tensors:' + human.tf.memory().numTensors + ' | performance: ' + JSON.stringify(msg).replace(/\"|{|}/g, '').replace(/,/g, ' | '); // print performance element\n\nasync function webCam() { // initialize webcam\n status('starting webcam...');\n // @ts-ignore resizeMode is not yet defined in tslib\n const options: MediaStreamConstraints = { audio: false, video: { facingMode: 'user', resizeMode: 'none', width: { ideal: document.body.clientWidth }, height: { ideal: document.body.clientHeight } } };\n const stream: MediaStream = await navigator.mediaDevices.getUserMedia(options);\n const ready = new Promise((resolve) => { dom.video.onloadeddata = () => resolve(true); });\n dom.video.srcObject = stream;\n dom.video.play();\n await ready;\n dom.canvas.width = dom.video.videoWidth;\n dom.canvas.height = dom.video.videoHeight;\n const track: MediaStreamTrack = stream.getVideoTracks()[0];\n const capabilities: MediaTrackCapabilities | string = track.getCapabilities ? track.getCapabilities() : '';\n const settings: MediaTrackSettings | string = track.getSettings ? track.getSettings() : '';\n const constraints: MediaTrackConstraints | string = track.getConstraints ? track.getConstraints() : '';\n log('video:', dom.video.videoWidth, dom.video.videoHeight, track.label, { stream, track, settings, constraints, capabilities });\n dom.canvas.onclick = () => { // pause when clicked on screen and resume on next click\n if (dom.video.paused) dom.video.play();\n else dom.video.pause();\n };\n}\n\nasync function detectionLoop() { // main detection loop\n if (!dom.video.paused) {\n if (timestamp.start === 0) timestamp.start = human.now();\n // log('profiling data:', await human.profile(dom.video));\n await human.detect(dom.video); // actual detection; were not capturing output in a local variable as it can also be reached via human.result\n const tensors = human.tf.memory().numTensors; // check current tensor usage for memory leaks\n if (tensors - timestamp.tensors !== 0) log('allocated tensors:', tensors - timestamp.tensors); // printed on start and each time there is a tensor leak\n timestamp.tensors = tensors;\n fps.detectFPS = Math.round(1000 * 1000 / (human.now() - timestamp.detect)) / 1000;\n fps.frames++;\n fps.averageMs = Math.round(1000 * (human.now() - timestamp.start) / fps.frames) / 1000;\n if (fps.frames % 100 === 0 && !dom.video.paused) log('performance', { ...fps, tensors: timestamp.tensors });\n }\n timestamp.detect = human.now();\n requestAnimationFrame(detectionLoop); // start new frame immediately\n}\n\nasync function drawLoop() { // main screen refresh loop\n if (!dom.video.paused) {\n const interpolated = await human.next(human.result); // smoothen result using last-known results\n if (human.config.filter.flip) await human.draw.canvas(interpolated.canvas as HTMLCanvasElement, dom.canvas); // draw processed image to screen canvas\n else await human.draw.canvas(dom.video, dom.canvas); // draw original video to screen canvas // better than using procesed image as this loop happens faster than processing loop\n await human.draw.all(dom.canvas, interpolated); // draw labels, boxes, lines, etc.\n perf(interpolated.performance); // write performance data\n }\n const now = human.now();\n fps.drawFPS = Math.round(1000 * 1000 / (now - timestamp.draw)) / 1000;\n timestamp.draw = now;\n status(dom.video.paused ? 'paused' : `fps: ${fps.detectFPS.toFixed(1).padStart(5, ' ')} detect | ${fps.drawFPS.toFixed(1).padStart(5, ' ')} draw`); // write status\n setTimeout(drawLoop, 30); // use to slow down refresh from max refresh rate to target of 30 fps\n}\n\nasync function main() { // main entry point\n log('human version:', human.version, '| tfjs version:', human.tf.version['tfjs-core']);\n log('platform:', human.env.platform, '| agent:', human.env.agent);\n status('loading...');\n await human.load(); // preload all models\n log('backend:', human.tf.getBackend(), '| available:', human.env.backends);\n log('models stats:', human.getModelStats());\n log('models loaded:', Object.values(human.models).filter((model) => model !== null).length);\n status('initializing...');\n await human.warmup(); // warmup function to initialize backend for future faster detection\n await webCam(); // start webcam\n await detectionLoop(); // start detection loop\n await drawLoop(); // start draw loop\n}\n\nwindow.onload = main;\n"], - "mappings": "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", + "sourcesContent": ["/**\n * Human demo for browsers\n * @default Human Library\n * @summary \n * @author \n * @copyright \n * @license MIT\n */\n\nimport * as H from '../../dist/human.esm.js'; // equivalent of @vladmandic/Human\n\nconst humanConfig: Partial = { // user configuration for human, used to fine-tune behavior\n // backend: 'wasm' as const,\n // wasmPath: 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@3.18.0/dist/',\n // cacheSensitivity: 0,\n async: false,\n modelBasePath: '../../models',\n filter: { enabled: true, equalization: false, flip: false },\n face: { enabled: true, detector: { rotation: false }, mesh: { enabled: true }, attention: { enabled: false }, iris: { enabled: true }, description: { enabled: true }, emotion: { enabled: true } },\n body: { enabled: true },\n hand: { enabled: true },\n object: { enabled: false },\n gesture: { enabled: true },\n};\n\nconst human = new H.Human(humanConfig); // create instance of human with overrides from user configuration\n\nhuman.env.perfadd = false; // is performance data showing instant or total values\nhuman.draw.options.font = 'small-caps 18px \"Lato\"'; // set font used to draw labels when using draw methods\nhuman.draw.options.lineHeight = 20;\n// human.draw.options.fillPolygons = true;\n\nconst dom = { // grab instances of dom objects so we dont have to look them up later\n video: document.getElementById('video') as HTMLVideoElement,\n canvas: document.getElementById('canvas') as HTMLCanvasElement,\n log: document.getElementById('log') as HTMLPreElement,\n fps: document.getElementById('status') as HTMLPreElement,\n perf: document.getElementById('performance') as HTMLDivElement,\n};\nconst timestamp = { detect: 0, draw: 0, tensors: 0, start: 0 }; // holds information used to calculate performance and possible memory leaks\nconst fps = { detectFPS: 0, drawFPS: 0, frames: 0, averageMs: 0 }; // holds calculated fps information for both detect and screen refresh\n\nconst log = (...msg) => { // helper method to output messages\n dom.log.innerText += msg.join(' ') + '\\n';\n console.log(...msg); // eslint-disable-line no-console\n};\nconst status = (msg) => dom.fps.innerText = msg; // print status element\nconst perf = (msg) => dom.perf.innerText = 'tensors:' + (human.tf.memory().numTensors as number).toString() + ' | performance: ' + JSON.stringify(msg).replace(/\"|{|}/g, '').replace(/,/g, ' | '); // print performance element\n\nasync function webCam() { // initialize webcam\n status('starting webcam...');\n // @ts-ignore resizeMode is not yet defined in tslib\n const options: MediaStreamConstraints = { audio: false, video: { facingMode: 'user', resizeMode: 'none', width: { ideal: document.body.clientWidth }, height: { ideal: document.body.clientHeight } } };\n const stream: MediaStream = await navigator.mediaDevices.getUserMedia(options);\n const ready = new Promise((resolve) => { dom.video.onloadeddata = () => resolve(true); });\n dom.video.srcObject = stream;\n void dom.video.play();\n await ready;\n dom.canvas.width = dom.video.videoWidth;\n dom.canvas.height = dom.video.videoHeight;\n const track: MediaStreamTrack = stream.getVideoTracks()[0];\n const capabilities: MediaTrackCapabilities | string = track.getCapabilities ? track.getCapabilities() : '';\n const settings: MediaTrackSettings | string = track.getSettings ? track.getSettings() : '';\n const constraints: MediaTrackConstraints | string = track.getConstraints ? track.getConstraints() : '';\n log('video:', dom.video.videoWidth, dom.video.videoHeight, track.label, { stream, track, settings, constraints, capabilities });\n dom.canvas.onclick = () => { // pause when clicked on screen and resume on next click\n if (dom.video.paused) void dom.video.play();\n else dom.video.pause();\n };\n}\n\nasync function detectionLoop() { // main detection loop\n if (!dom.video.paused) {\n if (timestamp.start === 0) timestamp.start = human.now();\n // log('profiling data:', await human.profile(dom.video));\n await human.detect(dom.video); // actual detection; were not capturing output in a local variable as it can also be reached via human.result\n const tensors = human.tf.memory().numTensors; // check current tensor usage for memory leaks\n if (tensors - timestamp.tensors !== 0) log('allocated tensors:', tensors - timestamp.tensors); // printed on start and each time there is a tensor leak\n timestamp.tensors = tensors;\n fps.detectFPS = Math.round(1000 * 1000 / (human.now() - timestamp.detect)) / 1000;\n fps.frames++;\n fps.averageMs = Math.round(1000 * (human.now() - timestamp.start) / fps.frames) / 1000;\n if (fps.frames % 100 === 0 && !dom.video.paused) log('performance', { ...fps, tensors: timestamp.tensors });\n }\n timestamp.detect = human.now();\n requestAnimationFrame(detectionLoop); // start new frame immediately\n}\n\nasync function drawLoop() { // main screen refresh loop\n if (!dom.video.paused) {\n const interpolated = human.next(human.result); // smoothen result using last-known results\n if (human.config.filter.flip) human.draw.canvas(interpolated.canvas as HTMLCanvasElement, dom.canvas); // draw processed image to screen canvas\n else human.draw.canvas(dom.video, dom.canvas); // draw original video to screen canvas // better than using procesed image as this loop happens faster than processing loop\n await human.draw.all(dom.canvas, interpolated); // draw labels, boxes, lines, etc.\n perf(interpolated.performance); // write performance data\n }\n const now = human.now();\n fps.drawFPS = Math.round(1000 * 1000 / (now - timestamp.draw)) / 1000;\n timestamp.draw = now;\n status(dom.video.paused ? 'paused' : `fps: ${fps.detectFPS.toFixed(1).padStart(5, ' ')} detect | ${fps.drawFPS.toFixed(1).padStart(5, ' ')} draw`); // write status\n setTimeout(drawLoop, 30); // use to slow down refresh from max refresh rate to target of 30 fps\n}\n\nasync function main() { // main entry point\n log('human version:', human.version, '| tfjs version:', human.tf.version['tfjs-core']);\n log('platform:', human.env.platform, '| agent:', human.env.agent);\n status('loading...');\n await human.load(); // preload all models\n log('backend:', human.tf.getBackend(), '| available:', human.env.backends);\n log('models stats:', human.getModelStats());\n log('models loaded:', Object.values(human.models).filter((model) => model !== null).length);\n status('initializing...');\n await human.warmup(); // warmup function to initialize backend for future faster detection\n await webCam(); // start webcam\n await detectionLoop(); // start detection loop\n await drawLoop(); // start draw loop\n}\n\nwindow.onload = main;\n"], + "mappings": "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", "names": ["H", "humanConfig", "human", "dom", "timestamp", "fps", "log", "msg", "status", "perf", "webCam", "options", "stream", "ready", "resolve", "track", "capabilities", "settings", "constraints", "detectionLoop", "tensors", "drawLoop", "interpolated", "now", "main", "model"] } diff --git a/demo/typescript/index.ts b/demo/typescript/index.ts index 80e3a2d8..f429a2b0 100644 --- a/demo/typescript/index.ts +++ b/demo/typescript/index.ts @@ -45,7 +45,7 @@ const log = (...msg) => { // helper method to output messages console.log(...msg); // eslint-disable-line no-console }; const status = (msg) => dom.fps.innerText = msg; // print status element -const perf = (msg) => dom.perf.innerText = 'tensors:' + human.tf.memory().numTensors + ' | performance: ' + JSON.stringify(msg).replace(/"|{|}/g, '').replace(/,/g, ' | '); // print performance element +const perf = (msg) => dom.perf.innerText = 'tensors:' + (human.tf.memory().numTensors as number).toString() + ' | performance: ' + JSON.stringify(msg).replace(/"|{|}/g, '').replace(/,/g, ' | '); // print performance element async function webCam() { // initialize webcam status('starting webcam...'); @@ -54,7 +54,7 @@ async function webCam() { // initialize webcam const stream: MediaStream = await navigator.mediaDevices.getUserMedia(options); const ready = new Promise((resolve) => { dom.video.onloadeddata = () => resolve(true); }); dom.video.srcObject = stream; - dom.video.play(); + void dom.video.play(); await ready; dom.canvas.width = dom.video.videoWidth; dom.canvas.height = dom.video.videoHeight; @@ -64,7 +64,7 @@ async function webCam() { // initialize webcam const constraints: MediaTrackConstraints | string = track.getConstraints ? track.getConstraints() : ''; log('video:', dom.video.videoWidth, dom.video.videoHeight, track.label, { stream, track, settings, constraints, capabilities }); dom.canvas.onclick = () => { // pause when clicked on screen and resume on next click - if (dom.video.paused) dom.video.play(); + if (dom.video.paused) void dom.video.play(); else dom.video.pause(); }; } @@ -88,9 +88,9 @@ async function detectionLoop() { // main detection loop async function drawLoop() { // main screen refresh loop if (!dom.video.paused) { - const interpolated = await human.next(human.result); // smoothen result using last-known results - if (human.config.filter.flip) await human.draw.canvas(interpolated.canvas as HTMLCanvasElement, dom.canvas); // draw processed image to screen canvas - else await human.draw.canvas(dom.video, dom.canvas); // draw original video to screen canvas // better than using procesed image as this loop happens faster than processing loop + const interpolated = human.next(human.result); // smoothen result using last-known results + if (human.config.filter.flip) human.draw.canvas(interpolated.canvas as HTMLCanvasElement, dom.canvas); // draw processed image to screen canvas + else human.draw.canvas(dom.video, dom.canvas); // draw original video to screen canvas // better than using procesed image as this loop happens faster than processing loop await human.draw.all(dom.canvas, interpolated); // draw labels, boxes, lines, etc. perf(interpolated.performance); // write performance data } diff --git a/src/body/blazepose.ts b/src/body/blazepose.ts index d9e4c095..c256dbcf 100644 --- a/src/body/blazepose.ts +++ b/src/body/blazepose.ts @@ -38,7 +38,7 @@ export async function loadDetect(config: Config): Promise { inputSize.detector[0] = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[1].size) : 0; inputSize.detector[1] = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[2].size) : 0; } else if (config.debug && models.detector) log('cached model:', models.detector['modelUrl']); - await detect.createAnchors(); + detect.createAnchors(); return models.detector as GraphModel; } @@ -59,7 +59,7 @@ export async function load(config: Config): Promise<[GraphModel | null, GraphMod return [models.detector, models.landmarks]; } -async function prepareImage(input: Tensor, size: number): Promise { +function prepareImage(input: Tensor, size: number): Tensor { const t: Record = {}; if (!input.shape || !input.shape[1] || !input.shape[2]) return input; let final: Tensor; @@ -120,7 +120,7 @@ function rescaleKeypoints(keypoints: BodyKeypoint[], outputSize: [number, number return keypoints; } -async function fixKeypoints(keypoints: BodyKeypoint[]) { +function fixKeypoints(keypoints: BodyKeypoint[]) { // palm z-coord is incorrect around near-zero so we approximate it const leftPalm = keypoints.find((k) => k.part === 'leftPalm') as BodyKeypoint; const leftWrist = keypoints.find((k) => k.part === 'leftWrist') as BodyKeypoint; @@ -220,7 +220,7 @@ export async function predict(input: Tensor, config: Config): Promise= minScore) { const boxes = await t.boxes.array(); const boxRaw: Box = boxes[i]; diff --git a/src/body/movenet.ts b/src/body/movenet.ts index 99b51b2e..d67a71ea 100644 --- a/src/body/movenet.ts +++ b/src/body/movenet.ts @@ -42,7 +42,7 @@ export async function load(config: Config): Promise { return model; } -async function parseSinglePose(res, config, image) { +function parseSinglePose(res, config, image) { const kpt = res[0][0]; const keypoints: BodyKeypoint[] = []; let score = 0; @@ -80,7 +80,7 @@ async function parseSinglePose(res, config, image) { return bodies; } -async function parseMultiPose(res, config, image) { +function parseMultiPose(res, config, image) { const bodies: BodyResult[] = []; for (let id = 0; id < res[0].length; id++) { const kpt = res[0][id]; @@ -174,8 +174,8 @@ export async function predict(input: Tensor, config: Config): Promise kpt && kpt.position); // filter invalid keypoints + body.keypoints = body.keypoints.filter((kpt) => kpt?.position); // filter invalid keypoints for (const kpt of body.keypoints) { kpt.position = [ kpt.position[0] * (outputSize[0] + cache.padding[2][0] + cache.padding[2][1]) / outputSize[0] - cache.padding[2][0], diff --git a/src/body/posenet.ts b/src/body/posenet.ts index 99710711..0095eab1 100644 --- a/src/body/posenet.ts +++ b/src/body/posenet.ts @@ -19,7 +19,7 @@ const localMaximumRadius = 1; const outputStride = 16; const squaredNmsRadius = 50 ** 2; -function traverse(edgeId, sourceKeypoint, targetId, scores, offsets, displacements, offsetRefineStep = 2) { +function traverse(edgeId: number, sourceKeypoint, targetId, scores, offsets, displacements, offsetRefineStep = 2) { const getDisplacement = (point) => ({ y: displacements.get(point.y, point.x, edgeId), x: displacements.get(point.y, point.x, (displacements.shape[2] / 2) + edgeId), @@ -81,8 +81,8 @@ export function decodePose(root, scores, offsets, displacementsFwd, displacement return keypoints; } -function scoreIsMaximumInLocalWindow(keypointId, score, heatmapY, heatmapX, scores) { - const [height, width] = scores.shape; +function scoreIsMaximumInLocalWindow(keypointId, score: number, heatmapY: number, heatmapX: number, scores) { + const [height, width]: [number, number] = scores.shape; let localMaximum = true; const yStart = Math.max(heatmapY - localMaximumRadius, 0); const yEnd = Math.min(heatmapY + localMaximumRadius + 1, height); @@ -172,7 +172,7 @@ export async function predict(input: Tensor, config: Config): Promise tensor.buffer())); for (const t of res) tf.dispose(t); - const decoded = await decode(buffers[0], buffers[1], buffers[2], buffers[3], config.body.maxDetected, config.body.minConfidence); + const decoded = decode(buffers[0], buffers[1], buffers[2], buffers[3], config.body.maxDetected, config.body.minConfidence); if (!model.inputs[0].shape) return []; const scaled = utils.scalePoses(decoded, [input.shape[1], input.shape[2]], [model.inputs[0].shape[2], model.inputs[0].shape[1]]); return scaled; diff --git a/src/body/posenetutils.ts b/src/body/posenetutils.ts index 12a8b5c1..b8523b5a 100644 --- a/src/body/posenetutils.ts +++ b/src/body/posenetutils.ts @@ -154,14 +154,14 @@ export class MaxHeap { } } -export function getOffsetPoint(y, x, keypoint, offsets) { +export function getOffsetPoint(y, x, keypoint: number, offsets) { return { y: offsets.get(y, x, keypoint), x: offsets.get(y, x, keypoint + count), }; } -export function getImageCoords(part, outputStride, offsets) { +export function getImageCoords(part, outputStride: number, offsets) { const { heatmapY, heatmapX, id: keypoint } = part; const { y, x } = getOffsetPoint(heatmapY, heatmapX, keypoint, offsets); return { @@ -190,7 +190,7 @@ export function squaredDistance(y1, x1, y2, x2) { return dy * dy + dx * dx; } -export function addVectors(a, b) { +export function addVectors(a: { x: number, y: number }, b: { x: number, y: number }) { return { x: a.x + b.x, y: a.y + b.y }; } diff --git a/src/draw/body.ts b/src/draw/body.ts index bbeb547d..14580a22 100644 --- a/src/draw/body.ts +++ b/src/draw/body.ts @@ -5,8 +5,8 @@ import type { BodyResult } from '../result'; import type { AnyCanvas, DrawOptions } from '../exports'; /** draw detected bodies */ -export async function body(inCanvas: AnyCanvas, result: BodyResult[], drawOptions?: Partial) { - const localOptions = mergeDeep(options, drawOptions); +export function body(inCanvas: AnyCanvas, result: BodyResult[], drawOptions?: Partial) { + const localOptions: DrawOptions = mergeDeep(options, drawOptions); if (!result || !inCanvas) return; const ctx = getCanvasContext(inCanvas); if (!ctx) return; diff --git a/src/draw/draw.ts b/src/draw/draw.ts index da8fb738..ff898eb5 100644 --- a/src/draw/draw.ts +++ b/src/draw/draw.ts @@ -24,8 +24,8 @@ export { object } from './object'; export { gesture } from './gesture'; /** draw combined person results instead of individual detection result objects */ -export async function person(inCanvas: AnyCanvas, result: PersonResult[], drawOptions?: Partial) { - const localOptions = mergeDeep(options, drawOptions); +export function person(inCanvas: AnyCanvas, result: PersonResult[], drawOptions?: Partial) { + const localOptions: DrawOptions = mergeDeep(options, drawOptions); if (!result || !inCanvas) return; const ctx = getCanvasContext(inCanvas); if (!ctx) return; @@ -52,7 +52,7 @@ export async function person(inCanvas: AnyCanvas, result: PersonResult[], drawOp } /** draw processed canvas */ -export async function canvas(input: AnyCanvas | HTMLImageElement | HTMLVideoElement, output: AnyCanvas) { +export function canvas(input: AnyCanvas | HTMLImageElement | HTMLVideoElement, output: AnyCanvas) { if (!input || !output) return; const ctx = getCanvasContext(output); if (!ctx) return; diff --git a/src/draw/face.ts b/src/draw/face.ts index 24b771ee..c36e08b6 100644 --- a/src/draw/face.ts +++ b/src/draw/face.ts @@ -23,7 +23,7 @@ function drawLabels(f: FaceResult, ctx: CanvasRenderingContext2D | OffscreenCanv if (emotion.length > 3) emotion.length = 3; labels.push(emotion.join(' ')); } - if (f.rotation && f.rotation.angle && f.rotation.gaze) { + if (f.rotation?.angle && f.rotation?.gaze) { if (f.rotation.angle.roll) labels.push(`roll: ${rad2deg(f.rotation.angle.roll)}° yaw:${rad2deg(f.rotation.angle.yaw)}° pitch:${rad2deg(f.rotation.angle.pitch)}°`); if (f.rotation.gaze.bearing) labels.push(`gaze: ${rad2deg(f.rotation.gaze.bearing)}°`); } @@ -44,7 +44,7 @@ function drawLabels(f: FaceResult, ctx: CanvasRenderingContext2D | OffscreenCanv function drawIrisElipse(f: FaceResult, ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) { // iris: array[center, left, top, right, bottom] - if (f.annotations && f.annotations.leftEyeIris && f.annotations.leftEyeIris[0]) { + if (f.annotations?.leftEyeIris && f.annotations?.leftEyeIris[0]) { ctx.strokeStyle = opt.useDepth ? 'rgba(255, 200, 255, 0.3)' : opt.color; ctx.beginPath(); const sizeX = Math.abs(f.annotations.leftEyeIris[3][0] - f.annotations.leftEyeIris[1][0]) / 2; @@ -56,7 +56,7 @@ function drawIrisElipse(f: FaceResult, ctx: CanvasRenderingContext2D | Offscreen ctx.fill(); } } - if (f.annotations && f.annotations.rightEyeIris && f.annotations.rightEyeIris[0]) { + if (f.annotations?.rightEyeIris && f.annotations?.rightEyeIris[0]) { ctx.strokeStyle = opt.useDepth ? 'rgba(255, 200, 255, 0.3)' : opt.color; ctx.beginPath(); const sizeX = Math.abs(f.annotations.rightEyeIris[3][0] - f.annotations.rightEyeIris[1][0]) / 2; @@ -149,7 +149,7 @@ function drawFaceBoxes(f: FaceResult, ctx) { } /** draw detected faces */ -export async function face(inCanvas: AnyCanvas, result: FaceResult[], drawOptions?: Partial) { +export function face(inCanvas: AnyCanvas, result: FaceResult[], drawOptions?: Partial) { opt = mergeDeep(options, drawOptions); if (!result || !inCanvas) return; const ctx = getCanvasContext(inCanvas); diff --git a/src/draw/gesture.ts b/src/draw/gesture.ts index 61d47fd4..532078cf 100644 --- a/src/draw/gesture.ts +++ b/src/draw/gesture.ts @@ -5,8 +5,8 @@ import type { GestureResult } from '../result'; import type { AnyCanvas, DrawOptions } from '../exports'; /** draw detected gestures */ -export async function gesture(inCanvas: AnyCanvas, result: GestureResult[], drawOptions?: Partial) { - const localOptions = mergeDeep(options, drawOptions); +export function gesture(inCanvas: AnyCanvas, result: GestureResult[], drawOptions?: Partial) { + const localOptions: DrawOptions = mergeDeep(options, drawOptions); if (!result || !inCanvas) return; if (localOptions.drawGestures) { const ctx = getCanvasContext(inCanvas); diff --git a/src/draw/hand.ts b/src/draw/hand.ts index bffe5cc8..e78b1258 100644 --- a/src/draw/hand.ts +++ b/src/draw/hand.ts @@ -5,8 +5,8 @@ import type { HandResult } from '../result'; import type { AnyCanvas, DrawOptions, Point } from '../exports'; /** draw detected hands */ -export async function hand(inCanvas: AnyCanvas, result: HandResult[], drawOptions?: Partial) { - const localOptions = mergeDeep(options, drawOptions); +export function hand(inCanvas: AnyCanvas, result: HandResult[], drawOptions?: Partial) { + const localOptions: DrawOptions = mergeDeep(options, drawOptions); if (!result || !inCanvas) return; const ctx = getCanvasContext(inCanvas); if (!ctx) return; diff --git a/src/draw/object.ts b/src/draw/object.ts index 65015202..56a27a1d 100644 --- a/src/draw/object.ts +++ b/src/draw/object.ts @@ -5,8 +5,8 @@ import type { ObjectResult } from '../result'; import type { AnyCanvas, DrawOptions } from '../exports'; /** draw detected objects */ -export async function object(inCanvas: AnyCanvas, result: ObjectResult[], drawOptions?: Partial) { - const localOptions = mergeDeep(options, drawOptions); +export function object(inCanvas: AnyCanvas, result: ObjectResult[], drawOptions?: Partial) { + const localOptions: DrawOptions = mergeDeep(options, drawOptions); if (!result || !inCanvas) return; const ctx = getCanvasContext(inCanvas); if (!ctx) return; diff --git a/src/draw/options.ts b/src/draw/options.ts index e2bbd8e8..aef68034 100644 --- a/src/draw/options.ts +++ b/src/draw/options.ts @@ -44,23 +44,23 @@ export interface DrawOptions { /** currently set draw options {@link DrawOptions} */ export const options: DrawOptions = { - color: 'rgba(173, 216, 230, 0.6)', // 'lightblue' with light alpha channel - labelColor: 'rgba(173, 216, 230, 1)', // 'lightblue' with dark alpha channel - shadowColor: 'black', - alpha: 0.5, - font: 'small-caps 16px "Segoe UI"', - lineHeight: 18, - lineWidth: 4, - pointSize: 2, - roundRect: 8, - drawPoints: false, - drawLabels: true, - drawBoxes: true, - drawAttention: true, - drawGestures: true, - drawPolygons: true, - drawGaze: true, - fillPolygons: false, - useDepth: true, - useCurves: false, + color: 'rgba(173, 216, 230, 0.6)' as string, // 'lightblue' with light alpha channel + labelColor: 'rgba(173, 216, 230, 1)' as string, // 'lightblue' with dark alpha channel + shadowColor: 'black' as string, + alpha: 0.5 as number, + font: 'small-caps 16px "Segoe UI"' as string, + lineHeight: 18 as number, + lineWidth: 4 as number, + pointSize: 2 as number, + roundRect: 8 as number, + drawPoints: false as boolean, + drawLabels: true as boolean, + drawBoxes: true as boolean, + drawAttention: true as boolean, + drawGestures: true as boolean, + drawPolygons: true as boolean, + drawGaze: true as boolean, + fillPolygons: false as boolean, + useDepth: true as boolean, + useCurves: false as boolean, }; diff --git a/src/face/face.ts b/src/face/face.ts index efa3a5bb..f87c310b 100644 --- a/src/face/face.ts +++ b/src/face/face.ts @@ -200,7 +200,7 @@ export const detectFace = async (instance: Human /* instance of human */, input: // if (faces[i]?.annotations?.leftEyeIris) delete faces[i].annotations.leftEyeIris; // if (faces[i]?.annotations?.rightEyeIris) delete faces[i].annotations.rightEyeIris; } - const irisSize = (faces[i].annotations && faces[i].annotations.leftEyeIris && faces[i].annotations.leftEyeIris[0] && faces[i].annotations.rightEyeIris && faces[i].annotations.rightEyeIris[0] + const irisSize = (faces[i]?.annotations?.leftEyeIris?.[0] && faces[i]?.annotations?.rightEyeIris?.[0] && (faces[i].annotations.leftEyeIris.length > 0) && (faces[i].annotations.rightEyeIris.length > 0) && (faces[i].annotations.leftEyeIris[0] !== null) && (faces[i].annotations.rightEyeIris[0] !== null)) ? Math.max(Math.abs(faces[i].annotations.leftEyeIris[3][0] - faces[i].annotations.leftEyeIris[1][0]), Math.abs(faces[i].annotations.rightEyeIris[4][1] - faces[i].annotations.rightEyeIris[2][1])) / input.shape[2] diff --git a/src/face/faceboxes.ts b/src/face/faceboxes.ts index bc35dd59..f7c7ccee 100644 --- a/src/face/faceboxes.ts +++ b/src/face/faceboxes.ts @@ -56,11 +56,11 @@ export class FaceBoxes { } } -export async function load(config) { +export async function load(config: Config) { const model = await loadModel(config.face.detector?.modelPath); - if (config.debug) log(`load model: ${config.face.detector.modelPath.match(/\/(.*)\./)[1]}`); + if (config.face.detector?.modelPath && config.debug) log(`load model: ${config.face.detector.modelPath?.match(/\/(.*)\./)?.[1] || ''}`); const faceboxes = new FaceBoxes(model, config); - if (config.face.mesh.enabled && config.debug) log(`load model: ${config.face.mesh.modelPath.match(/\/(.*)\./)[1]}`); - if (config.face.iris.enabled && config.debug) log(`load model: ${config.face.iris.modelPath.match(/\/(.*)\./)[1]}`); + if (config.face.mesh?.enabled && config.face.mesh?.modelPath && config.debug) log(`load model: ${config.face.mesh.modelPath.match(/\/(.*)\./)?.[1] || ''}`); + if (config.face.iris?.enabled && config.face.iris?.modelPath && config.debug) log(`load model: ${config.face.iris.modelPath?.match(/\/(.*)\./)?.[1] || ''}`); return faceboxes; } diff --git a/src/face/facemeshutil.ts b/src/face/facemeshutil.ts index a743b9cc..7e8f563a 100644 --- a/src/face/facemeshutil.ts +++ b/src/face/facemeshutil.ts @@ -69,7 +69,7 @@ export const calculateLandmarksBoundingBox = (landmarks) => { export const fixedRotationMatrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; -export const normalizeRadians = (angle) => angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI)); +export const normalizeRadians = (angle: number) => angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI)); export const computeRotation = (point1, point2) => normalizeRadians(Math.PI / 2 - Math.atan2(-(point2[1] - point1[1]), point2[0] - point1[0])); @@ -120,7 +120,7 @@ export const rotatePoint = (homogeneousCoordinate, rotationMatrix) => [dot(homog export const xyDistanceBetweenPoints = (a, b) => Math.sqrt(((a[0] - b[0]) ** 2) + ((a[1] - b[1]) ** 2)); -export function generateAnchors(inputSize) { +export function generateAnchors(inputSize: number) { const spec = inputSize === 192 ? { strides: [4], anchors: [1] } // facemesh-detector : { strides: [inputSize / 16, inputSize / 8], anchors: [2, 6] }; // blazeface diff --git a/src/face/faceres.ts b/src/face/faceres.ts index b511a473..1b64c3a3 100644 --- a/src/face/faceres.ts +++ b/src/face/faceres.ts @@ -40,8 +40,8 @@ export async function load(config: Config): Promise { export function enhance(input): Tensor { const tensor = (input.image || input.tensor || input) as Tensor; // input received from detector is already normalized to 0..1, input is also assumed to be straightened if (!model?.inputs[0].shape) return tensor; // model has no shape so no point continuing - const crop = tf.image.resizeBilinear(tensor, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false); - const norm = tf.mul(crop, constants.tf255); + const crop: Tensor = tf.image.resizeBilinear(tensor, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false); + const norm: Tensor = tf.mul(crop, constants.tf255); tf.dispose(crop); return norm; /* @@ -74,10 +74,10 @@ export async function predict(image: Tensor, config: Config, idx: number, count: skipped = 0; return new Promise(async (resolve) => { const obj = { - age: 0, - gender: 'unknown', - genderScore: 0, - descriptor: [], + age: 0 as number, + gender: 'unknown' as Gender, + genderScore: 0 as number, + descriptor: [] as number[], }; if (config.face.description?.enabled) { @@ -85,7 +85,7 @@ export async function predict(image: Tensor, config: Config, idx: number, count: const resT = model?.execute(enhanced) as Tensor[]; lastTime = now(); tf.dispose(enhanced); - const genderT = await resT.find((t) => t.shape[1] === 1) as Tensor; + const genderT = resT.find((t) => t.shape[1] === 1) as Tensor; const gender = await genderT.data(); const confidence = Math.trunc(200 * Math.abs((gender[0] - 0.5))) / 100; if (confidence > (config.face.description.minConfidence || 0)) { @@ -93,7 +93,7 @@ export async function predict(image: Tensor, config: Config, idx: number, count: obj.genderScore = Math.min(0.99, confidence); } const argmax = tf.argMax(resT.find((t) => t.shape[1] === 100), 1); - const age = (await argmax.data())[0]; + const age: number = (await argmax.data())[0]; tf.dispose(argmax); const ageT = resT.find((t) => t.shape[1] === 100) as Tensor; const all = await ageT.data(); @@ -102,7 +102,7 @@ export async function predict(image: Tensor, config: Config, idx: number, count: const desc = resT.find((t) => t.shape[1] === 1024); // const reshape = desc.reshape([128, 8]); // reshape large 1024-element descriptor to 128 x 8 // const reduce = reshape.logSumExp(1); // reduce 2nd dimension by calculating logSumExp on it which leaves us with 128-element descriptor - const descriptor = desc ? await desc.data() : []; + const descriptor = desc ? await desc.data() : [] as number[]; obj.descriptor = Array.from(descriptor); resT.forEach((t) => tf.dispose(t)); } diff --git a/src/hand/handpose.ts b/src/hand/handpose.ts index 40f294b3..853a5b5a 100644 --- a/src/hand/handpose.ts +++ b/src/hand/handpose.ts @@ -96,7 +96,7 @@ export async function load(config: Config): Promise<[GraphModel | null, GraphMod if (config.debug) log('cached model:', handDetectorModel['modelUrl']); if (config.debug) log('cached model:', handPoseModel['modelUrl']); } - const handDetector = new handdetector.HandDetector(handDetectorModel); - handPipeline = new handpipeline.HandPipeline(handDetector, handPoseModel); + const handDetector = handDetectorModel ? new handdetector.HandDetector(handDetectorModel) : undefined; + if (handDetector && handPoseModel) handPipeline = new handpipeline.HandPipeline(handDetector, handPoseModel); return [handDetectorModel, handPoseModel]; } diff --git a/src/hand/handposedetector.ts b/src/hand/handposedetector.ts index c1507fae..43b4fc51 100644 --- a/src/hand/handposedetector.ts +++ b/src/hand/handposedetector.ts @@ -9,6 +9,7 @@ import * as anchors from './handposeanchors'; import { constants } from '../tfjs/constants'; import type { Tensor, GraphModel } from '../tfjs/types'; import type { Point } from '../result'; +import type { Config } from '../config'; export class HandDetector { model: GraphModel; @@ -18,11 +19,11 @@ export class HandDetector { inputSizeTensor: Tensor; doubleInputSizeTensor: Tensor; - constructor(model) { + constructor(model: GraphModel) { this.model = model; this.anchors = anchors.anchors.map((anchor) => [anchor.x, anchor.y]); this.anchorsTensor = tf.tensor2d(this.anchors); - this.inputSize = (this.model && this.model.inputs && this.model.inputs[0].shape) ? this.model.inputs[0].shape[2] : 0; + this.inputSize = this?.model?.inputs?.[0]?.shape?.[2] || 0; this.inputSizeTensor = tf.tensor1d([this.inputSize, this.inputSize]); this.doubleInputSizeTensor = tf.tensor1d([this.inputSize * 2, this.inputSize * 2]); } @@ -40,20 +41,20 @@ export class HandDetector { t.endPoints = tf.mul(t.add, this.inputSizeTensor); const res = tf.concat2d([t.startPoints, t.endPoints], 1); Object.keys(t).forEach((tensor) => tf.dispose(t[tensor])); - return res; + return res as Tensor; } - normalizeLandmarks(rawPalmLandmarks, index) { + normalizeLandmarks(rawPalmLandmarks, index: number) { const t: Record = {}; t.reshape = tf.reshape(rawPalmLandmarks, [-1, 7, 2]); t.div = tf.div(t.reshape, this.inputSizeTensor); - t.landmarks = tf.add(t.div, this.anchors[index]); + t.landmarks = tf.add(t.div, this.anchors[index] ? this.anchors[index] : 0); const res = tf.mul(t.landmarks, this.inputSizeTensor); Object.keys(t).forEach((tensor) => tf.dispose(t[tensor])); - return res; + return res as Tensor; } - async predict(input, config): Promise<{ startPoint: Point; endPoint: Point, palmLandmarks: Point[]; confidence: number }[]> { + async predict(input: Tensor, config: Config): Promise<{ startPoint: Point; endPoint: Point, palmLandmarks: Point[]; confidence: number }[]> { const t: Record = {}; t.resize = tf.image.resizeBilinear(input, [this.inputSize, this.inputSize]); t.div = tf.div(t.resize, constants.tf127); @@ -67,7 +68,7 @@ export class HandDetector { t.boxes = tf.slice(t.predictions, [0, 1], [-1, 4]); t.norm = this.normalizeBoxes(t.boxes); // box detection is flaky so we look for 3x boxes than we need results - t.nms = await tf.image.nonMaxSuppressionAsync(t.norm, t.scores, 3 * config.hand.maxDetected, config.hand.iouThreshold, config.hand.minConfidence); + t.nms = await tf.image.nonMaxSuppressionAsync(t.norm, t.scores, 3 * (config.hand?.maxDetected || 1), config.hand.iouThreshold, config.hand.minConfidence); const nms = await t.nms.array() as number[]; const hands: { startPoint: Point; endPoint: Point; palmLandmarks: Point[]; confidence: number }[] = []; for (const index of nms) { @@ -81,7 +82,7 @@ export class HandDetector { const endPoint = box.slice(2, 4) as unknown as Point; const palmLandmarks = await p.palmLandmarks.array(); const hand = { startPoint, endPoint, palmLandmarks, confidence: scores[index] }; - const scaled = util.scaleBoxCoordinates(hand, [input.shape[2] / this.inputSize, input.shape[1] / this.inputSize]); + const scaled = util.scaleBoxCoordinates(hand, [(input.shape[2] || 1) / this.inputSize, (input.shape[1] || 0) / this.inputSize]); hands.push(scaled); Object.keys(p).forEach((tensor) => tf.dispose(p[tensor])); } diff --git a/src/hand/handposepipeline.ts b/src/hand/handposepipeline.ts index 704fb8bb..80f43500 100644 --- a/src/hand/handposepipeline.ts +++ b/src/hand/handposepipeline.ts @@ -30,7 +30,7 @@ export class HandPipeline { constructor(handDetector, handPoseModel) { this.handDetector = handDetector; this.handPoseModel = handPoseModel; - this.inputSize = this.handPoseModel && this.handPoseModel.inputs[0].shape ? this.handPoseModel.inputs[0].shape[2] : 0; + this.inputSize = this.handPoseModel?.inputs?.[0].shape?.[2] || 0; this.storedBoxes = []; this.skipped = Number.MAX_SAFE_INTEGER; this.detectedHands = 0; diff --git a/src/human.ts b/src/human.ts index dcc16099..c6513c04 100644 --- a/src/human.ts +++ b/src/human.ts @@ -295,7 +295,7 @@ export class Human { if (this.env.initial) { // print version info on first run and check for correct backend setup if (this.config.debug) log(`version: ${this.version}`); - if (this.config.debug) log(`tfjs version: ${this.tf.version['tfjs-core']}`); + if (this.config.debug) log(`tfjs version: ${this.tf.version['tfjs-core'] as string}`); if (!await backend.check(this)) log('error: backend check failed'); await tf.ready(); if (this.env.browser) { @@ -321,7 +321,7 @@ export class Human { /** emit event */ emit = (event: string) => { - if (this.events && this.events.dispatchEvent) this.events.dispatchEvent(new Event(event)); + if (this.events?.dispatchEvent) this.events.dispatchEvent(new Event(event)); }; /** Runs interpolation using last known result and returns smoothened result diff --git a/src/image/enhance.ts b/src/image/enhance.ts index 4df16f54..34aeec47 100644 --- a/src/image/enhance.ts +++ b/src/image/enhance.ts @@ -20,5 +20,5 @@ export async function histogramEqualization(inputImage: Tensor): Promise const rgb = tf.stack([enh[0], enh[1], enh[2]], 2); const reshape = tf.reshape(rgb, [1, squeeze.shape[0], squeeze.shape[1], 3]); tf.dispose([...channels, ...min, ...max, ...sub, ...range, ...fact, ...enh, rgb, squeeze]); - return reshape; // output shape is [1, height, width, 3] + return reshape as Tensor; // output shape is [1, height, width, 3] } diff --git a/src/image/image.ts b/src/image/image.ts index 7ff470ae..1aa93834 100644 --- a/src/image/image.ts +++ b/src/image/image.ts @@ -25,7 +25,7 @@ const last: { inputSum: number, cacheDiff: number, sumMethod: number, inputTenso }; export function canvas(width: number, height: number): AnyCanvas { - let c; + let c: AnyCanvas; if (env.browser) { // browser defines canvas object if (env.worker) { // if runing in web worker use OffscreenCanvas if (typeof OffscreenCanvas === 'undefined') throw new Error('canvas error: attempted to run in web worker but OffscreenCanvas is not supported'); @@ -42,6 +42,7 @@ export function canvas(width: number, height: number): AnyCanvas { else if (typeof globalThis.Canvas !== 'undefined') c = new globalThis.Canvas(width, height); // else throw new Error('canvas error: attempted to use canvas in nodejs without canvas support installed'); } + // @ts-ignore its either defined or we already threw an error return c; } @@ -98,7 +99,7 @@ export async function process(input: Input, config: Config, getTensor: boolean = } } // at the end shape must be [1, height, width, 3] - if (tensor == null || (tensor as Tensor).shape.length !== 4 || (tensor as Tensor).shape[0] !== 1 || (tensor as Tensor).shape[3] !== 3) throw new Error(`input error: attempted to use tensor with unrecognized shape: ${(input as Tensor).shape}`); + if (tensor == null || tensor.shape.length !== 4 || tensor.shape[0] !== 1 || tensor.shape[3] !== 3) throw new Error(`input error: attempted to use tensor with unrecognized shape: ${((input as Tensor).shape).toString()}`); if ((tensor).dtype === 'int32') { const cast = tf.cast(tensor, 'float32'); tf.dispose(tensor); @@ -111,14 +112,14 @@ export async function process(input: Input, config: Config, getTensor: boolean = if (config.debug) log('input stream is not ready'); return { tensor: null, canvas: inCanvas }; // video may become temporarily unavailable due to onresize } - const originalWidth = input['naturalWidth'] || input['videoWidth'] || input['width'] || (input['shape'] && (input['shape'][1] > 0)); - const originalHeight = input['naturalHeight'] || input['videoHeight'] || input['height'] || (input['shape'] && (input['shape'][2] > 0)); + const originalWidth: number = input['naturalWidth'] || input['videoWidth'] || input['width'] || (input['shape'] && (input['shape'][1] > 0)); + const originalHeight: number = input['naturalHeight'] || input['videoHeight'] || input['height'] || (input['shape'] && (input['shape'][2] > 0)); if (!originalWidth || !originalHeight) { if (config.debug) log('cannot determine input dimensions'); return { tensor: null, canvas: inCanvas }; // video may become temporarily unavailable due to onresize } - let targetWidth = originalWidth; - let targetHeight = originalHeight; + let targetWidth: number = originalWidth; + let targetHeight: number = originalHeight; if (targetWidth > maxSize) { targetWidth = maxSize; targetHeight = Math.trunc(targetWidth * originalHeight / originalWidth); @@ -129,9 +130,9 @@ export async function process(input: Input, config: Config, getTensor: boolean = } // create our canvas and resize it if needed - if ((config.filter.width || 0) > 0) targetWidth = config.filter.width; - else if ((config.filter.height || 0) > 0) targetWidth = originalWidth * ((config.filter.height || 0) / originalHeight); - if ((config.filter.height || 0) > 0) targetHeight = config.filter.height; + if ((config.filter?.width || 0) > 0) targetWidth = config.filter.width as number; + else if ((config.filter?.height || 0) > 0) targetWidth = originalWidth * ((config.filter.height || 0) / originalHeight); + if ((config.filter.height || 0) > 0) targetHeight = config.filter.height as number; else if ((config.filter.width || 0) > 0) targetHeight = originalHeight * ((config.filter.width || 0) / originalWidth); if (!targetWidth || !targetHeight) throw new Error('input error: cannot determine dimension'); if (!inCanvas || (inCanvas.width !== targetWidth) || (inCanvas.height !== targetHeight)) inCanvas = canvas(targetWidth, targetHeight); @@ -227,8 +228,8 @@ export async function process(input: Input, config: Config, getTensor: boolean = pixels = rgb; } if (!pixels) throw new Error('input error: cannot create tensor'); - const casted = tf.cast(pixels, 'float32'); - const tensor = config.filter.equalization ? await enhance.histogramEqualization(casted) : tf.expandDims(casted, 0); + const casted: Tensor = tf.cast(pixels, 'float32'); + const tensor: Tensor = config.filter.equalization ? await enhance.histogramEqualization(casted) : tf.expandDims(casted, 0); tf.dispose([pixels, casted]); return { tensor, canvas: (config.filter.return ? outCanvas : null) }; } diff --git a/src/image/imagefx.ts b/src/image/imagefx.ts index 243cd699..d1d3281d 100644 --- a/src/image/imagefx.ts +++ b/src/image/imagefx.ts @@ -9,7 +9,7 @@ import * as shaders from './imagefxshaders'; import { canvas } from './image'; import { log } from '../util/util'; -const collect = (source, prefix, collection) => { +const collect = (source, prefix: string, collection) => { const r = new RegExp('\\b' + prefix + ' \\w+ (\\w+)', 'ig'); source.replace(r, (match, name) => { collection[name] = 0; @@ -37,7 +37,7 @@ class GLProgram { this.gl.attachShader(this.id, fragmentShader); this.gl.linkProgram(this.id); if (!this.gl.getProgramParameter(this.id, this.gl.LINK_STATUS)) { - log(`filter: gl link failed: ${this.gl.getProgramInfoLog(this.id)}`); + log(`filter: gl link failed: ${this.gl.getProgramInfoLog(this.id) || 'unknown'}`); return; } this.gl.useProgram(this.id); @@ -57,7 +57,7 @@ class GLProgram { this.gl.shaderSource(shader, source); this.gl.compileShader(shader); if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) { - log(`filter: gl compile failed: ${this.gl.getShaderInfoLog(shader)}`); + log(`filter: gl compile failed: ${this.gl.getShaderInfoLog(shader) || 'unknown'}`); return null; } return shader; @@ -174,7 +174,7 @@ export function GLImageFilter() { } const filter = { - colorMatrix: (matrix) => { // general color matrix filter + colorMatrix: (matrix: number[]) => { // general color matrix filter const m = new Float32Array(matrix); m[4] /= 255; m[9] /= 255; @@ -189,7 +189,7 @@ export function GLImageFilter() { draw(); }, - brightness: (brightness) => { + brightness: (brightness: number) => { const b = (brightness || 0) + 1; filter.colorMatrix([ b, 0, 0, 0, 0, @@ -199,7 +199,7 @@ export function GLImageFilter() { ]); }, - saturation: (amount) => { + saturation: (amount: number) => { const x = (amount || 0) * 2 / 3 + 1; const y = ((x - 1) * -0.5); filter.colorMatrix([ @@ -214,7 +214,7 @@ export function GLImageFilter() { filter.saturation(-1); }, - contrast: (amount) => { + contrast: (amount: number) => { const v = (amount || 0) + 1; const o = -128 * (v - 1); filter.colorMatrix([ @@ -229,7 +229,7 @@ export function GLImageFilter() { filter.contrast(-2); }, - hue: (rotation) => { + hue: (rotation: number) => { rotation = (rotation || 0) / 180 * Math.PI; const cos = Math.cos(rotation); const sin = Math.sin(rotation); @@ -316,7 +316,7 @@ export function GLImageFilter() { ]); }, - convolution: (matrix) => { // general convolution Filter + convolution: (matrix: number[]) => { // general convolution Filter const m = new Float32Array(matrix); const pixelSizeX = 1 / fxcanvas.width; const pixelSizeY = 1 / fxcanvas.height; @@ -364,7 +364,7 @@ export function GLImageFilter() { ]); }, - emboss: (size) => { + emboss: (size: number) => { const s = size || 1; // @ts-ignore this filter.convolution.call(this, [ @@ -374,7 +374,7 @@ export function GLImageFilter() { ]); }, - blur: (size) => { + blur: (size: number) => { const blurSizeX = (size / 7) / fxcanvas.width; const blurSizeY = (size / 7) / fxcanvas.height; const program = compileShader(shaders.blur); @@ -387,7 +387,7 @@ export function GLImageFilter() { draw(); }, - pixelate: (size) => { + pixelate: (size: number) => { const blurSizeX = (size) / fxcanvas.width; const blurSizeY = (size) / fxcanvas.height; const program = compileShader(shaders.pixelate); diff --git a/src/models.ts b/src/models.ts index c1def00f..2768972f 100644 --- a/src/models.ts +++ b/src/models.ts @@ -158,7 +158,7 @@ export function validateModel(newInstance: Human | null, model: GraphModel | nul interface Op { name: string, category: string, op: string } const url = model['modelUrl'] as string; const executor = model['executor']; - if (executor && executor.graph.nodes) { + if (executor?.graph?.nodes) { for (const kernel of Object.values(executor.graph.nodes)) { const op = (kernel as Op).op.toLowerCase(); if (!ops.includes(op)) ops.push(op); diff --git a/src/tfjs/backend.ts b/src/tfjs/backend.ts index cf9e4b51..a7a0dc85 100644 --- a/src/tfjs/backend.ts +++ b/src/tfjs/backend.ts @@ -21,7 +21,7 @@ function registerCustomOps() { const kernelMod = { kernelName: 'FloorMod', backendName: tf.getBackend(), - kernelFunc: (op) => tf.tidy(() => tf.floorDiv(op.inputs.a / op.inputs.b) * op.inputs.b + tf.mod(op.inputs.a, op.inputs.b)), + kernelFunc: (op) => tf.tidy(() => tf.add(tf.mul(tf.floorDiv(op.inputs.a / op.inputs.b), op.inputs.b), tf.mod(op.inputs.a, op.inputs.b))), }; tf.registerKernel(kernelMod); env.kernels.push('floormod'); @@ -71,8 +71,8 @@ export async function check(instance: Human, force = false) { } // check available backends - if (instance.config.backend === 'humangl') await humangl.register(instance); - const available = Object.keys(tf.engine().registryFactory); + if (instance.config.backend === 'humangl') humangl.register(instance); + const available = Object.keys(tf.engine().registryFactory as Record); if (instance.config.debug) log('available backends:', available); if (!available.includes(instance.config.backend)) { @@ -87,7 +87,7 @@ export async function check(instance: Human, force = false) { if (instance.config.backend === 'wasm') { if (tf.env().flagRegistry.CANVAS2D_WILL_READ_FREQUENTLY) tf.env().set('CANVAS2D_WILL_READ_FREQUENTLY', true); if (instance.config.debug) log('wasm path:', instance.config.wasmPath); - if (typeof tf.setWasmPaths !== 'undefined') await tf.setWasmPaths(instance.config.wasmPath, instance.config.wasmPlatformFetch); + if (typeof tf.setWasmPaths !== 'undefined') tf.setWasmPaths(instance.config.wasmPath, instance.config.wasmPlatformFetch); else throw new Error('backend error: attempting to use wasm backend but wasm path is not set'); let mt = false; let simd = false; @@ -127,7 +127,7 @@ export async function check(instance: Human, force = false) { } if (tf.backend().getGPGPUContext) { const gl = await tf.backend().getGPGPUContext().gl; - if (instance.config.debug) log(`gl version:${gl.getParameter(gl.VERSION)} renderer:${gl.getParameter(gl.RENDERER)}`); + if (instance.config.debug) log(`gl version:${gl.getParameter(gl.VERSION) as string} renderer:${gl.getParameter(gl.RENDERER) as string}`); } } @@ -165,5 +165,5 @@ export function fakeOps(kernelNames: string[], config) { }; tf.registerKernel(kernelConfig); } - env.kernels = tf.getKernelsForBackend(tf.getBackend()).map((kernel) => kernel.kernelName.toLowerCase()); // re-scan registered ops + env.kernels = tf.getKernelsForBackend(tf.getBackend()).map((kernel) => (kernel.kernelName as string).toLowerCase()); // re-scan registered ops } diff --git a/src/tfjs/humangl.ts b/src/tfjs/humangl.ts index 966cec3a..e9ff70d2 100644 --- a/src/tfjs/humangl.ts +++ b/src/tfjs/humangl.ts @@ -11,9 +11,9 @@ import type { AnyCanvas } from '../exports'; export const config = { name: 'humangl', priority: 999, - canvas: null, - gl: null, - extensions: [], + canvas: null as null | AnyCanvas, + gl: null as null | WebGL2RenderingContext, + extensions: [] as string[] | null, webGLattr: { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2 alpha: false, antialias: false, @@ -42,7 +42,7 @@ function extensions(): void { * * @returns void */ -export async function register(instance: Human): Promise { +export function register(instance: Human): void { // force backend reload if gl context is not valid if (instance.config.backend !== 'humangl') return; if ((config.name in tf.engine().registry) && (!config.gl || !config.gl.getParameter(config.gl.VERSION))) { @@ -56,7 +56,7 @@ export async function register(instance: Human): Promise { } if (!tf.findBackend(config.name)) { try { - config.canvas = await image.canvas(100, 100); + config.canvas = image.canvas(100, 100); } catch (err) { log('error: cannot create canvas:', err); return; @@ -74,7 +74,7 @@ export async function register(instance: Human): Promise { return; } if (config.canvas) { - config.canvas.addEventListener('webglcontextlost', async (e) => { + config.canvas.addEventListener('webglcontextlost', (e) => { log('error: humangl:', e.type); log('possible browser memory leak using webgl or conflict with multiple backend registrations'); instance.emit('error'); @@ -121,7 +121,7 @@ export async function register(instance: Human): Promise { } const current = tf.backend().getGPGPUContext ? tf.backend().getGPGPUContext().gl : null; if (current) { - log(`humangl webgl version:${current.getParameter(current.VERSION)} renderer:${current.getParameter(current.RENDERER)}`); + log(`humangl webgl version:${current.getParameter(current.VERSION) as string} renderer:${current.getParameter(current.RENDERER) as string}`); } else { log('error: no current gl context:', current, config.gl); return; diff --git a/src/tfjs/load.ts b/src/tfjs/load.ts index 5c8efbad..cb2c9837 100644 --- a/src/tfjs/load.ts +++ b/src/tfjs/load.ts @@ -23,7 +23,7 @@ export interface ModelInfo { export const modelStats: Record = {}; -async function httpHandler(url, init?): Promise { +async function httpHandler(url: string, init?: RequestInit): Promise { if (options.debug) log('load model fetch:', url, init); return fetch(url, init); } @@ -55,7 +55,7 @@ export async function loadModel(modelPath: string | undefined): Promise httpHandler(url, init) }; + const tfLoadOptions = typeof fetch === 'undefined' ? {} : { fetchFunc: (url: string, init?: RequestInit) => httpHandler(url, init) }; const model: GraphModel = new tf.GraphModel(modelStats[shortModelName].inCache ? cachedModelName : modelUrl, tfLoadOptions) as unknown as GraphModel; // create model prototype and decide if load from cache or from original modelurl let loaded = false; try { @@ -81,6 +81,6 @@ export async function loadModel(modelPath: string | undefined): Promise kernel.kernelName.toLowerCase()); + this.kernels = tf.getKernelsForBackend(tf.getBackend()).map((kernel) => (kernel.kernelName as string).toLowerCase()); } catch { /**/ } } diff --git a/src/util/interpolate.ts b/src/util/interpolate.ts index c2ae8509..4d2f2268 100644 --- a/src/util/interpolate.ts +++ b/src/util/interpolate.ts @@ -2,7 +2,7 @@ * Results interpolation for smoothening of video detection results inbetween detected frames */ -import type { Result, FaceResult, BodyResult, HandResult, ObjectResult, GestureResult, PersonResult, Box, Point, BodyLandmark, BodyAnnotation } from '../result'; +import type { Result, FaceResult, BodyResult, HandResult, ObjectResult, PersonResult, Box, Point, BodyLandmark, BodyAnnotation } from '../result'; import type { Config } from '../config'; import * as moveNetCoords from '../body/movenetcoords'; @@ -103,7 +103,7 @@ export function calc(newResult: Result, config: Config): Result { annotations = bufferedResult.hand[i].annotations; } else if (newResult.hand[i].annotations) { for (const key of Object.keys(newResult.hand[i].annotations)) { // update annotations - annotations[key] = newResult.hand[i].annotations[key] && newResult.hand[i].annotations[key][0] + annotations[key] = newResult.hand[i]?.annotations?.[key]?.[0] ? newResult.hand[i].annotations[key] .map((val, j: number) => val .map((coord: number, k: number) => ((bufferedFactor - 1) * bufferedResult.hand[i].annotations[key][j][k] + coord) / bufferedFactor)) @@ -173,7 +173,7 @@ export function calc(newResult: Result, config: Config): Result { } // just copy latest gestures without interpolation - if (newResult.gesture) bufferedResult.gesture = newResult.gesture as GestureResult[]; + if (newResult.gesture) bufferedResult.gesture = newResult.gesture; // append interpolation performance data const t1 = now(); diff --git a/src/util/persons.ts b/src/util/persons.ts index 76373e66..8244cf3e 100644 --- a/src/util/persons.ts +++ b/src/util/persons.ts @@ -59,7 +59,7 @@ export function join(faces: FaceResult[], bodies: BodyResult[], hands: HandResul person.box = [minX, minY, Math.max(...x) - minX, Math.max(...y) - minY]; // create new overarching box // shape is known so we calculate boxRaw as well - if (shape && shape[1] && shape[2]) person.boxRaw = [person.box[0] / shape[2], person.box[1] / shape[1], person.box[2] / shape[2], person.box[3] / shape[1]]; + if (shape?.[1] && shape?.[2]) person.boxRaw = [person.box[0] / shape[2], person.box[1] / shape[1], person.box[2] / shape[2], person.box[3] / shape[1]]; persons.push(person); } diff --git a/src/util/profile.ts b/src/util/profile.ts index c2685f98..71220f5d 100644 --- a/src/util/profile.ts +++ b/src/util/profile.ts @@ -7,15 +7,15 @@ import { log } from './util'; export const data = {}; -export type ProfileData = { +export interface ProfileData { newBytes: number, peakBytes: number, newTensors: number, - kernels: Array<{ + kernels: { id: number, kernelTimeMs: number, totalBytesSnapshot: number, - }>, + }[], } export function run(modelName: string, profileData: ProfileData): void { // profileData is tfjs internal type diff --git a/src/warmup.ts b/src/warmup.ts index bb51e529..ebe61167 100644 --- a/src/warmup.ts +++ b/src/warmup.ts @@ -10,6 +10,7 @@ import { env } from './util/env'; import type { Config } from './config'; import type { Result } from './result'; import type { Human, Models } from './human'; +import type { Tensor } from './exports'; async function warmupBitmap(instance: Human): Promise { const b64toBlob = (base64: string, type = 'application/octet-stream') => fetch(`data:${type};base64,${base64}`).then((res) => res.blob()); @@ -76,10 +77,10 @@ async function warmupNode(instance: Human): Promise { let img; if (instance.config.warmup === 'face') img = atob(sample.face); else img = atob(sample.body); - let res; + let res: Result; if (('node' in tf) && (tf.getBackend() === 'tensorflow')) { - const data = tf['node'].decodeJpeg(img); // eslint-disable-line import/namespace - const expanded = data.expandDims(0); + const data: Tensor = tf['node'].decodeJpeg(img); // eslint-disable-line import/namespace + const expanded: Tensor = tf.expandDims(data, 0); instance.tf.dispose(data); // log('Input:', expanded); res = await instance.detect(expanded, instance.config); @@ -94,6 +95,7 @@ async function warmupNode(instance: Human): Promise { res = await instance.detect(input, instance.config); */ } + // @ts-ignore return res; } @@ -118,8 +120,8 @@ export async function runCompile(allModels: Models) { const numTensorsStart = tf.engine().state.numTensors; const compiledModels: string[] = []; for (const [modelName, model] of Object.entries(allModels).filter(([key, val]) => (key !== null && val !== null))) { - const shape = (model.inputs && model.inputs[0] && model.inputs[0].shape) ? [...model.inputs[0].shape] : [1, 64, 64, 3]; - const dtype = (model.inputs && model.inputs[0] && model.inputs[0].dtype) ? model.inputs[0].dtype : 'float32'; + const shape = (model.inputs?.[0]?.shape) ? [...model.inputs[0].shape] : [1, 64, 64, 3]; + const dtype: string = (model.inputs?.[0]?.dtype) ? model.inputs[0].dtype : 'float32'; for (let dim = 0; dim < shape.length; dim++) { if (shape[dim] === -1) shape[dim] = dim === 0 ? 1 : 64; // override batch number and any dynamic dimensions } diff --git a/test/build.log b/test/build.log index 90130f9d..98853a91 100644 --- a/test/build.log +++ b/test/build.log @@ -1,39 +1,39 @@ -2022-08-21 13:32:23 DATA:  Build {"name":"@vladmandic/human","version":"2.9.4"} -2022-08-21 13:32:23 INFO:  Application: {"name":"@vladmandic/human","version":"2.9.4"} -2022-08-21 13:32:23 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true} -2022-08-21 13:32:23 INFO:  Toolchain: {"build":"0.7.10","esbuild":"0.15.5","typescript":"4.7.4","typedoc":"0.23.10","eslint":"8.22.0"} -2022-08-21 13:32:23 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]} -2022-08-21 13:32:23 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]} -2022-08-21 13:32:23 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":159,"outputBytes":608} -2022-08-21 13:32:23 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":75,"inputBytes":652939,"outputBytes":306172} -2022-08-21 13:32:23 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":167,"outputBytes":612} -2022-08-21 13:32:23 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":75,"inputBytes":652943,"outputBytes":306176} -2022-08-21 13:32:23 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":206,"outputBytes":664} -2022-08-21 13:32:23 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":75,"inputBytes":652995,"outputBytes":306226} -2022-08-21 13:32:23 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1125,"outputBytes":358} -2022-08-21 13:32:23 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1088,"outputBytes":583} -2022-08-21 13:32:23 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":75,"inputBytes":652914,"outputBytes":305046} -2022-08-21 13:32:23 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":11,"inputBytes":1344,"outputBytes":2787569} -2022-08-21 13:32:23 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":75,"inputBytes":3439900,"outputBytes":1667925} -2022-08-21 13:32:23 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":75,"inputBytes":3439900,"outputBytes":3070714} -2022-08-21 13:32:28 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":30} -2022-08-21 13:32:29 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":77,"generated":true} -2022-08-21 13:32:29 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6699,"outputBytes":3141} -2022-08-21 13:32:29 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15549,"outputBytes":7741} -2022-08-21 13:32:39 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":111,"errors":0,"warnings":0} -2022-08-21 13:32:39 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"} -2022-08-21 13:32:39 STATE: Copy: {"input":"tfjs/tfjs.esm.d.ts"} -2022-08-21 13:32:39 INFO:  Done... -2022-08-21 13:32:40 STATE: API-Extractor: {"succeeeded":true,"errors":0,"warnings":198} -2022-08-21 13:32:40 STATE: Copy: {"input":"types/human.d.ts"} -2022-08-21 13:32:40 INFO:  Analyze models: {"folders":8,"result":"models/models.json"} -2022-08-21 13:32:40 STATE: Models {"folder":"./models","models":13} -2022-08-21 13:32:40 STATE: Models {"folder":"../human-models/models","models":42} -2022-08-21 13:32:40 STATE: Models {"folder":"../blazepose/model/","models":4} -2022-08-21 13:32:40 STATE: Models {"folder":"../anti-spoofing/model","models":1} -2022-08-21 13:32:40 STATE: Models {"folder":"../efficientpose/models","models":3} -2022-08-21 13:32:40 STATE: Models {"folder":"../insightface/models","models":5} -2022-08-21 13:32:40 STATE: Models {"folder":"../movenet/models","models":3} -2022-08-21 13:32:40 STATE: Models {"folder":"../nanodet/models","models":4} -2022-08-21 13:32:40 STATE: Models: {"count":57,"totalSize":383017442} -2022-08-21 13:32:40 INFO:  Human Build complete... {"logFile":"test/build.log"} +2022-08-21 15:21:09 DATA:  Build {"name":"@vladmandic/human","version":"2.9.4"} +2022-08-21 15:21:09 INFO:  Application: {"name":"@vladmandic/human","version":"2.9.4"} +2022-08-21 15:21:09 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true} +2022-08-21 15:21:09 INFO:  Toolchain: {"build":"0.7.10","esbuild":"0.15.5","typescript":"4.7.4","typedoc":"0.23.10","eslint":"8.22.0"} +2022-08-21 15:21:09 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]} +2022-08-21 15:21:09 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]} +2022-08-21 15:21:09 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":159,"outputBytes":608} +2022-08-21 15:21:09 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":75,"inputBytes":653284,"outputBytes":306632} +2022-08-21 15:21:09 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":167,"outputBytes":612} +2022-08-21 15:21:09 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":75,"inputBytes":653288,"outputBytes":306636} +2022-08-21 15:21:09 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":206,"outputBytes":664} +2022-08-21 15:21:09 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":75,"inputBytes":653340,"outputBytes":306686} +2022-08-21 15:21:09 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1125,"outputBytes":358} +2022-08-21 15:21:09 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1088,"outputBytes":583} +2022-08-21 15:21:09 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":75,"inputBytes":653259,"outputBytes":305505} +2022-08-21 15:21:09 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":11,"inputBytes":1344,"outputBytes":2787569} +2022-08-21 15:21:09 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":75,"inputBytes":3440245,"outputBytes":1668404} +2022-08-21 15:21:09 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":75,"inputBytes":3440245,"outputBytes":3071598} +2022-08-21 15:21:14 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":30} +2022-08-21 15:21:16 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":77,"generated":true} +2022-08-21 15:21:16 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":6714,"outputBytes":3134} +2022-08-21 15:21:16 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15501,"outputBytes":7733} +2022-08-21 15:21:27 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":111,"errors":0,"warnings":0} +2022-08-21 15:21:27 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"} +2022-08-21 15:21:27 STATE: Copy: {"input":"tfjs/tfjs.esm.d.ts"} +2022-08-21 15:21:27 INFO:  Done... +2022-08-21 15:21:27 STATE: API-Extractor: {"succeeeded":true,"errors":0,"warnings":198} +2022-08-21 15:21:27 STATE: Copy: {"input":"types/human.d.ts"} +2022-08-21 15:21:27 INFO:  Analyze models: {"folders":8,"result":"models/models.json"} +2022-08-21 15:21:27 STATE: Models {"folder":"./models","models":13} +2022-08-21 15:21:27 STATE: Models {"folder":"../human-models/models","models":42} +2022-08-21 15:21:27 STATE: Models {"folder":"../blazepose/model/","models":4} +2022-08-21 15:21:27 STATE: Models {"folder":"../anti-spoofing/model","models":1} +2022-08-21 15:21:27 STATE: Models {"folder":"../efficientpose/models","models":3} +2022-08-21 15:21:27 STATE: Models {"folder":"../insightface/models","models":5} +2022-08-21 15:21:27 STATE: Models {"folder":"../movenet/models","models":3} +2022-08-21 15:21:27 STATE: Models {"folder":"../nanodet/models","models":4} +2022-08-21 15:21:28 STATE: Models: {"count":57,"totalSize":383017442} +2022-08-21 15:21:28 INFO:  Human Build complete... {"logFile":"test/build.log"} diff --git a/test/test.log b/test/test.log index 48c8e65e..0d427f90 100644 --- a/test/test.log +++ b/test/test.log @@ -1,970 +1,970 @@ -2022-08-20 09:36:24 INFO:  @vladmandic/human version 2.9.4 -2022-08-20 09:36:24 INFO:  User: vlado Platform: linux Arch: x64 Node: v18.1.0 -2022-08-20 09:36:24 INFO:  demos: [{"cmd":"../demo/nodejs/node.js","args":[]},{"cmd":"../demo/nodejs/node-simple.js","args":[]},{"cmd":"../demo/nodejs/node-fetch.js","args":[]},{"cmd":"../demo/nodejs/node-event.js","args":["samples/in/ai-body.jpg"]},{"cmd":"../demo/nodejs/node-similarity.js","args":["samples/in/ai-face.jpg","samples/in/ai-upper.jpg"]},{"cmd":"../demo/nodejs/node-canvas.js","args":["samples/in/ai-body.jpg","samples/out/ai-body.jpg"]},{"cmd":"../demo/multithread/node-multiprocess.js","args":[]},{"cmd":"../demo/facematch/node-match.js","args":[]}] -2022-08-20 09:36:24 INFO:  {"cmd":"../demo/nodejs/node.js","args":[]} start -2022-08-20 09:36:25 INFO:  {"cmd":"../demo/nodejs/node-simple.js","args":[]} start -2022-08-20 09:36:26 INFO:  {"cmd":"../demo/nodejs/node-fetch.js","args":[]} start -2022-08-20 09:36:30 INFO:  {"cmd":"../demo/nodejs/node-event.js","args":["samples/in/ai-body.jpg"]} start -2022-08-20 09:36:31 INFO:  {"cmd":"../demo/nodejs/node-similarity.js","args":["samples/in/ai-face.jpg","samples/in/ai-upper.jpg"]} start -2022-08-20 09:36:31 INFO:  {"cmd":"../demo/nodejs/node-canvas.js","args":["samples/in/ai-body.jpg","samples/out/ai-body.jpg"]} start -2022-08-20 09:36:32 INFO:  {"cmd":"../demo/multithread/node-multiprocess.js","args":[]} start -2022-08-20 09:36:33 INFO:  {"cmd":"../demo/facematch/node-match.js","args":[]} start -2022-08-20 09:36:35 INFO:  tests: ["test-node.js","test-node-gpu.js","test-node-wasm.js"] -2022-08-20 09:36:35 INFO:  -2022-08-20 09:36:35 INFO:  test-node.js start -2022-08-20 09:36:35 INFO:  test-node.js test: configuration validation -2022-08-20 09:36:35 STATE: test-node.js passed: configuration default validation [] -2022-08-20 09:36:35 STATE: test-node.js passed: configuration invalid validation [{"reason":"unknown property","where":"config.invalid = true"}] -2022-08-20 09:36:35 INFO:  test-node.js test: model load -2022-08-20 09:36:35 STATE: test-node.js passed: models loaded 23 12 [{"name":"ssrnetage","loaded":false,"url":null},{"name":"gear","loaded":false,"url":null},{"name":"blazeposedetect","loaded":false,"url":null},{"name":"blazepose","loaded":false,"url":null},{"name":"centernet","loaded":true,"url":"file://models/mb3-centernet.json"},{"name":"efficientpose","loaded":false,"url":null},{"name":"mobilefacenet","loaded":false,"url":null},{"name":"insightface","loaded":false,"url":null},{"name":"emotion","loaded":true,"url":"file://models/emotion.json"},{"name":"facedetect","loaded":true,"url":"file://models/blazeface.json"},{"name":"faceiris","loaded":true,"url":"file://models/iris.json"},{"name":"facemesh","loaded":true,"url":"file://models/facemesh.json"},{"name":"faceres","loaded":true,"url":"file://models/faceres.json"},{"name":"ssrnetgender","loaded":false,"url":null},{"name":"handpose","loaded":false,"url":null},{"name":"handskeleton","loaded":true,"url":"file://models/handlandmark-full.json"},{"name":"handtrack","loaded":true,"url":"file://models/handtrack.json"},{"name":"liveness","loaded":true,"url":"file://models/liveness.json"},{"name":"movenet","loaded":true,"url":"file://models/movenet-lightning.json"},{"name":"nanodet","loaded":false,"url":null},{"name":"posenet","loaded":false,"url":null},{"name":"segmentation","loaded":true,"url":"file://models/selfie.json"},{"name":"antispoof","loaded":true,"url":"file://models/antispoof.json"}] -2022-08-20 09:36:35 INFO:  test-node.js test: warmup -2022-08-20 09:36:35 STATE: test-node.js passed: create human -2022-08-20 09:36:35 INFO:  test-node.js human version: 2.9.4 -2022-08-20 09:36:35 INFO:  test-node.js platform: linux x64 agent: NodeJS v18.1.0 -2022-08-20 09:36:35 INFO:  test-node.js tfjs version: 3.19.0 -2022-08-20 09:36:35 INFO:  test-node.js env: {"browser":false,"node":true,"platform":"linux x64","agent":"NodeJS v18.1.0","backends":["cpu","tensorflow"],"initial":false,"tfjs":{"version":"3.19.0"},"offscreen":false,"perfadd":false,"tensorflow":{"version":"2.7.3-dev20220521","gpu":false},"wasm":{"supported":true,"backend":false},"webgl":{"supported":false,"backend":false},"webgpu":{"supported":false,"backend":false},"cpu":{"flags":[]},"kernels":169} -2022-08-20 09:36:35 STATE: test-node.js passed: set backend: tensorflow -2022-08-20 09:36:35 STATE: test-node.js tensors 1921 -2022-08-20 09:36:35 STATE: test-node.js passed: load models -2022-08-20 09:36:35 STATE: test-node.js result: defined models: 23 loaded models: 12 -2022-08-20 09:36:35 STATE: test-node.js passed: warmup: none default -2022-08-20 09:36:35 DATA:  test-node.js result: face: 0 body: 0 hand: 0 gesture: 0 object: 0 person: 0 {} {} {} -2022-08-20 09:36:35 DATA:  test-node.js result: performance: load: null total: null -2022-08-20 09:36:35 STATE: test-node.js passed: warmup none result match -2022-08-20 09:36:35 STATE: test-node.js event: image -2022-08-20 09:36:35 STATE: test-node.js event: detect -2022-08-20 09:36:35 STATE: test-node.js event: warmup -2022-08-20 09:36:35 STATE: test-node.js passed: warmup: face default -2022-08-20 09:36:35 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.42,"keypoints":4} -2022-08-20 09:36:35 DATA:  test-node.js result: performance: load: null total: 329 -2022-08-20 09:36:35 STATE: test-node.js passed: warmup face result match -2022-08-20 09:36:35 STATE: test-node.js event: image -2022-08-20 09:36:36 STATE: test-node.js event: detect -2022-08-20 09:36:36 STATE: test-node.js event: warmup -2022-08-20 09:36:36 STATE: test-node.js passed: warmup: body default -2022-08-20 09:36:36 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:36 DATA:  test-node.js result: performance: load: null total: 241 -2022-08-20 09:36:36 STATE: test-node.js passed: warmup body result match -2022-08-20 09:36:36 STATE: test-node.js details: {"face":{"boxScore":0.92,"faceScore":1,"age":23.7,"gender":"female","genderScore":0.97},"emotion":[{"score":0.63,"emotion":"angry"},{"score":0.22,"emotion":"fear"}],"body":{"score":0.92,"keypoints":17},"hand":{"boxScore":0.52,"fingerScore":0.73,"keypoints":21},"gestures":[{"face":0,"gesture":"facing right"},{"face":0,"gesture":"mouth 10% open"},{"hand":0,"gesture":"pinky forward"},{"hand":0,"gesture":"palm up"},{"hand":0,"gesture":"open palm"},{"iris":0,"gesture":"looking left"},{"iris":0,"gesture":"looking up"}]} -2022-08-20 09:36:36 INFO:  test-node.js test: details verification -2022-08-20 09:36:36 STATE: test-node.js start default -2022-08-20 09:36:36 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:36 STATE: test-node.js event: image -2022-08-20 09:36:36 STATE: test-node.js event: detect -2022-08-20 09:36:36 STATE: test-node.js passed: detect: samples/in/ai-body.jpg default -2022-08-20 09:36:36 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:36 DATA:  test-node.js result: performance: load: null total: 222 -2022-08-20 09:36:36 STATE: test-node.js passed: details face length 1 -2022-08-20 09:36:36 STATE: test-node.js passed: details face score 1 0.93 1 -2022-08-20 09:36:36 STATE: test-node.js passed: details face age/gender 23.7 female 0.97 85.47 -2022-08-20 09:36:36 STATE: test-node.js passed: details face arrays 4 478 1024 -2022-08-20 09:36:36 STATE: test-node.js passed: details face emotion 2 {"score":0.59,"emotion":"angry"} -2022-08-20 09:36:36 STATE: test-node.js passed: details face anti-spoofing 0.79 -2022-08-20 09:36:36 STATE: test-node.js passed: details face liveness 0.83 -2022-08-20 09:36:36 STATE: test-node.js passed: details body length 1 -2022-08-20 09:36:36 STATE: test-node.js passed: details body 0.92 17 6 -2022-08-20 09:36:36 STATE: test-node.js passed: details hand length 1 -2022-08-20 09:36:36 STATE: test-node.js passed: details hand 0.51 0.73 point -2022-08-20 09:36:36 STATE: test-node.js passed: details hand arrays 21 5 7 -2022-08-20 09:36:36 STATE: test-node.js passed: details gesture length 7 -2022-08-20 09:36:36 STATE: test-node.js passed: details gesture first {"face":0,"gesture":"facing right"} -2022-08-20 09:36:36 STATE: test-node.js passed: details object length 1 -2022-08-20 09:36:36 STATE: test-node.js passed: details object 0.72 person -2022-08-20 09:36:36 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996928} -2022-08-20 09:36:36 STATE: test-node.js event: image -2022-08-20 09:36:36 STATE: test-node.js event: detect -2022-08-20 09:36:36 STATE: test-node.js passed: tensor shape: [1,1200,1200,4] dtype: float32 -2022-08-20 09:36:37 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1200,1200,4] {"checksum":1371996928} -2022-08-20 09:36:37 STATE: test-node.js event: image -2022-08-20 09:36:37 STATE: test-node.js event: detect -2022-08-20 09:36:37 STATE: test-node.js passed: tensor shape: [1200,1200,4] dtype: float32 -2022-08-20 09:36:37 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:37 STATE: test-node.js event: image -2022-08-20 09:36:37 STATE: test-node.js event: detect -2022-08-20 09:36:37 STATE: test-node.js passed: tensor shape: [1,1200,1200,3] dtype: float32 -2022-08-20 09:36:37 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:37 STATE: test-node.js event: image -2022-08-20 09:36:38 STATE: test-node.js event: detect -2022-08-20 09:36:38 STATE: test-node.js passed: tensor shape: [1200,1200,3] dtype: float32 -2022-08-20 09:36:38 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996871} -2022-08-20 09:36:38 STATE: test-node.js event: image -2022-08-20 09:36:38 STATE: test-node.js event: detect -2022-08-20 09:36:38 STATE: test-node.js passed: tensor shape: [1,1200,1200,4] dtype: int32 -2022-08-20 09:36:38 INFO:  test-node.js test default -2022-08-20 09:36:38 STATE: test-node.js start async -2022-08-20 09:36:38 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:38 STATE: test-node.js event: image -2022-08-20 09:36:38 STATE: test-node.js event: detect -2022-08-20 09:36:38 STATE: test-node.js passed: detect: samples/in/ai-body.jpg async -2022-08-20 09:36:38 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:38 DATA:  test-node.js result: performance: load: null total: 212 -2022-08-20 09:36:38 STATE: test-node.js passed: default result face match 1 female 0.97 -2022-08-20 09:36:38 INFO:  test-node.js test sync -2022-08-20 09:36:38 STATE: test-node.js start sync -2022-08-20 09:36:39 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:39 STATE: test-node.js event: image -2022-08-20 09:36:39 STATE: test-node.js event: detect -2022-08-20 09:36:39 STATE: test-node.js passed: detect: samples/in/ai-body.jpg sync -2022-08-20 09:36:39 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:39 DATA:  test-node.js result: performance: load: null total: 207 -2022-08-20 09:36:39 STATE: test-node.js passed: default sync 1 female 0.97 -2022-08-20 09:36:39 INFO:  test-node.js test: image process -2022-08-20 09:36:39 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:39 STATE: test-node.js passed: image input null [1,256,256,3] -2022-08-20 09:36:39 INFO:  test-node.js test: image null -2022-08-20 09:36:39 STATE: test-node.js passed: invalid input could not convert input to tensor -2022-08-20 09:36:39 INFO:  test-node.js test face similarity -2022-08-20 09:36:39 STATE: test-node.js start face similarity -2022-08-20 09:36:39 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:39 STATE: test-node.js event: image -2022-08-20 09:36:39 STATE: test-node.js event: detect -2022-08-20 09:36:39 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face similarity -2022-08-20 09:36:39 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} -2022-08-20 09:36:39 DATA:  test-node.js result: performance: load: null total: 202 -2022-08-20 09:36:39 STATE: test-node.js start face similarity -2022-08-20 09:36:39 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:39 STATE: test-node.js event: image -2022-08-20 09:36:39 STATE: test-node.js event: detect -2022-08-20 09:36:39 STATE: test-node.js passed: detect: samples/in/ai-body.jpg face similarity -2022-08-20 09:36:39 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:39 DATA:  test-node.js result: performance: load: null total: 205 -2022-08-20 09:36:39 STATE: test-node.js start face similarity -2022-08-20 09:36:39 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} -2022-08-20 09:36:39 STATE: test-node.js event: image -2022-08-20 09:36:40 STATE: test-node.js event: detect -2022-08-20 09:36:40 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg face similarity -2022-08-20 09:36:40 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 4 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.71,"class":"person"} {"score":0.75,"keypoints":7} -2022-08-20 09:36:40 DATA:  test-node.js result: performance: load: null total: 186 -2022-08-20 09:36:40 STATE: test-node.js passed: face descriptor -2022-08-20 09:36:40 STATE: test-node.js passed: face similarity {"similarity":[1,0.44727452329649126,0.5567935850640406],"descriptors":[1024,1024,1024]} -2022-08-20 09:36:40 INFO:  test-node.js test object -2022-08-20 09:36:40 STATE: test-node.js start object -2022-08-20 09:36:40 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:40 STATE: test-node.js event: image -2022-08-20 09:36:40 STATE: test-node.js event: detect -2022-08-20 09:36:40 STATE: test-node.js passed: detect: samples/in/ai-body.jpg object -2022-08-20 09:36:40 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:40 DATA:  test-node.js result: performance: load: null total: 215 -2022-08-20 09:36:40 STATE: test-node.js passed: centernet -2022-08-20 09:36:40 STATE: test-node.js start object -2022-08-20 09:36:41 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:41 STATE: test-node.js event: image -2022-08-20 09:36:41 STATE: test-node.js event: detect -2022-08-20 09:36:41 STATE: test-node.js passed: detect: samples/in/ai-body.jpg object -2022-08-20 09:36:41 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 3 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:41 DATA:  test-node.js result: performance: load: null total: 218 -2022-08-20 09:36:41 STATE: test-node.js passed: nanodet -2022-08-20 09:36:41 INFO:  test-node.js test sensitive -2022-08-20 09:36:41 STATE: test-node.js start sensitive -2022-08-20 09:36:41 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:41 STATE: test-node.js event: image -2022-08-20 09:36:41 STATE: test-node.js event: detect -2022-08-20 09:36:41 STATE: test-node.js passed: detect: samples/in/ai-body.jpg sensitive -2022-08-20 09:36:41 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:36:41 DATA:  test-node.js result: performance: load: null total: 167 -2022-08-20 09:36:41 STATE: test-node.js passed: sensitive result match -2022-08-20 09:36:41 STATE: test-node.js passed: sensitive face result match -2022-08-20 09:36:41 STATE: test-node.js passed: sensitive face emotion result [{"score":0.59,"emotion":"angry"},{"score":0.29,"emotion":"fear"}] -2022-08-20 09:36:41 STATE: test-node.js passed: sensitive body result match -2022-08-20 09:36:41 STATE: test-node.js passed: sensitive hand result match -2022-08-20 09:36:41 INFO:  test-node.js test body -2022-08-20 09:36:41 STATE: test-node.js start blazepose -2022-08-20 09:36:43 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:43 STATE: test-node.js event: image -2022-08-20 09:36:43 STATE: test-node.js event: detect -2022-08-20 09:36:43 STATE: test-node.js passed: detect: samples/in/ai-body.jpg blazepose -2022-08-20 09:36:43 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.99,"keypoints":39} -2022-08-20 09:36:43 DATA:  test-node.js result: performance: load: null total: 227 -2022-08-20 09:36:43 STATE: test-node.js passed: blazepose -2022-08-20 09:36:43 STATE: test-node.js start efficientpose -2022-08-20 09:36:44 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:44 STATE: test-node.js event: image -2022-08-20 09:36:44 STATE: test-node.js event: detect -2022-08-20 09:36:44 STATE: test-node.js passed: detect: samples/in/ai-body.jpg efficientpose -2022-08-20 09:36:44 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.75,"keypoints":13} -2022-08-20 09:36:44 DATA:  test-node.js result: performance: load: null total: 246 -2022-08-20 09:36:44 STATE: test-node.js passed: efficientpose -2022-08-20 09:36:44 STATE: test-node.js start posenet -2022-08-20 09:36:45 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:45 STATE: test-node.js event: image -2022-08-20 09:36:45 STATE: test-node.js event: detect -2022-08-20 09:36:45 STATE: test-node.js passed: detect: samples/in/ai-body.jpg posenet -2022-08-20 09:36:45 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.96,"keypoints":16} -2022-08-20 09:36:45 DATA:  test-node.js result: performance: load: null total: 187 -2022-08-20 09:36:45 STATE: test-node.js passed: posenet -2022-08-20 09:36:45 STATE: test-node.js start movenet -2022-08-20 09:36:46 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:46 STATE: test-node.js event: image -2022-08-20 09:36:46 STATE: test-node.js event: detect -2022-08-20 09:36:46 STATE: test-node.js passed: detect: samples/in/ai-body.jpg movenet -2022-08-20 09:36:46 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:36:46 DATA:  test-node.js result: performance: load: null total: 179 -2022-08-20 09:36:46 STATE: test-node.js passed: movenet -2022-08-20 09:36:46 INFO:  test-node.js test face matching -2022-08-20 09:36:46 STATE: test-node.js passed: face database 40 -2022-08-20 09:36:46 STATE: test-node.js passed: face match {"first":{"index":4,"similarity":0.7827852615252829}} {"second":{"index":4,"similarity":0.5002052633015844}} {"third":{"index":4,"similarity":0.5401587887998899}} -2022-08-20 09:36:46 INFO:  test-node.js test face similarity alternative -2022-08-20 09:36:46 STATE: test-node.js start face embeddings -2022-08-20 09:36:46 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:46 STATE: test-node.js event: image -2022-08-20 09:36:46 STATE: test-node.js event: detect -2022-08-20 09:36:46 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face embeddings -2022-08-20 09:36:46 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:36:46 DATA:  test-node.js result: performance: load: null total: 189 -2022-08-20 09:36:46 STATE: test-node.js passed: mobilefacenet {"embedding":192} -2022-08-20 09:36:46 STATE: test-node.js start face embeddings -2022-08-20 09:36:47 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:47 STATE: test-node.js event: image -2022-08-20 09:36:47 STATE: test-node.js event: detect -2022-08-20 09:36:47 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face embeddings -2022-08-20 09:36:47 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:36:47 DATA:  test-node.js result: performance: load: null total: 189 -2022-08-20 09:36:47 STATE: test-node.js passed: insightface {"embedding":512} -2022-08-20 09:36:47 INFO:  test-node.js test face attention -2022-08-20 09:36:47 STATE: test-node.js start face attention -2022-08-20 09:36:48 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:48 STATE: test-node.js event: image -2022-08-20 09:36:48 STATE: test-node.js event: detect -2022-08-20 09:36:48 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face attention -2022-08-20 09:36:48 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:36:48 DATA:  test-node.js result: performance: load: null total: 175 -2022-08-20 09:36:48 STATE: test-node.js passed: face attention -2022-08-20 09:36:48 INFO:  test-node.js test detectors -2022-08-20 09:36:48 STATE: test-node.js start detectors -2022-08-20 09:36:48 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:48 STATE: test-node.js event: image -2022-08-20 09:36:48 STATE: test-node.js event: detect -2022-08-20 09:36:48 STATE: test-node.js passed: detect: samples/in/ai-body.jpg detectors -2022-08-20 09:36:48 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:36:48 DATA:  test-node.js result: performance: load: null total: 82 -2022-08-20 09:36:48 STATE: test-node.js passed: detector result face match -2022-08-20 09:36:48 STATE: test-node.js passed: detector result hand match -2022-08-20 09:36:48 INFO:  test-node.js test: multi-instance -2022-08-20 09:36:48 STATE: test-node.js start multi instance -2022-08-20 09:36:48 STATE: test-node.js event: image -2022-08-20 09:36:48 STATE: test-node.js event: detect -2022-08-20 09:36:48 STATE: test-node.js passed: detect: random multi instance -2022-08-20 09:36:48 DATA:  test-node.js result: face: 0 body: 1 hand: 0 gesture: 0 object: 0 person: 0 {} {} {"score":0,"keypoints":0} -2022-08-20 09:36:48 DATA:  test-node.js result: performance: load: null total: 83 -2022-08-20 09:36:48 INFO:  test-node.js test: first instance -2022-08-20 09:36:48 STATE: test-node.js start multi instance -2022-08-20 09:36:48 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} -2022-08-20 09:36:48 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg multi instance -2022-08-20 09:36:48 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:36:48 DATA:  test-node.js result: performance: load: null total: 79 -2022-08-20 09:36:48 INFO:  test-node.js test: second instance -2022-08-20 09:36:48 STATE: test-node.js start multi instance -2022-08-20 09:36:48 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} -2022-08-20 09:36:49 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg multi instance -2022-08-20 09:36:49 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:36:49 DATA:  test-node.js result: performance: load: null total: 85 -2022-08-20 09:36:49 INFO:  test-node.js test: concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js start concurrent -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:49 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} -2022-08-20 09:36:49 STATE: test-node.js event: image -2022-08-20 09:36:49 STATE: test-node.js event: image -2022-08-20 09:36:49 STATE: test-node.js event: image -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 947 -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 947 -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 947 -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 947 -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 947 -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 947 -2022-08-20 09:36:50 STATE: test-node.js event: detect -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 693 -2022-08-20 09:36:50 STATE: test-node.js event: detect -2022-08-20 09:36:50 STATE: test-node.js event: detect -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 694 -2022-08-20 09:36:50 STATE: test-node.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:36:50 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:36:50 DATA:  test-node.js result: performance: load: null total: 694 -2022-08-20 09:36:50 INFO:  test-node.js test: monkey-patch -2022-08-20 09:36:50 STATE: test-node.js event: image -2022-08-20 09:36:50 STATE: test-node.js event: detect -2022-08-20 09:36:50 STATE: test-node.js passed: monkey patch -2022-08-20 09:36:50 STATE: test-node.js passed: segmentation [65536] -2022-08-20 09:36:50 STATE: test-node.js passeed: equal usage -2022-08-20 09:36:50 INFO:  test-node.js test: input compare -2022-08-20 09:36:50 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:50 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} -2022-08-20 09:36:50 STATE: test-node.js passed: image compare 0 23.275441687091504 -2022-08-20 09:36:50 INFO:  test-node.js events: {"image":29,"detect":29,"warmup":2} -2022-08-20 09:36:50 INFO:  test-node.js tensors 4105 -2022-08-20 09:36:50 INFO:  test-node.js test complete: 15407 ms -2022-08-20 09:36:50 INFO:  -2022-08-20 09:36:50 INFO:  test-node-gpu.js start -2022-08-20 09:36:51 INFO:  test-node-gpu.js test: configuration validation -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: configuration default validation [] -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: configuration invalid validation [{"reason":"unknown property","where":"config.invalid = true"}] -2022-08-20 09:36:51 INFO:  test-node-gpu.js test: model load -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: models loaded 23 12 [{"name":"ssrnetage","loaded":false,"url":null},{"name":"gear","loaded":false,"url":null},{"name":"blazeposedetect","loaded":false,"url":null},{"name":"blazepose","loaded":false,"url":null},{"name":"centernet","loaded":true,"url":"file://models/mb3-centernet.json"},{"name":"efficientpose","loaded":false,"url":null},{"name":"mobilefacenet","loaded":false,"url":null},{"name":"insightface","loaded":false,"url":null},{"name":"emotion","loaded":true,"url":"file://models/emotion.json"},{"name":"facedetect","loaded":true,"url":"file://models/blazeface.json"},{"name":"faceiris","loaded":true,"url":"file://models/iris.json"},{"name":"facemesh","loaded":true,"url":"file://models/facemesh.json"},{"name":"faceres","loaded":true,"url":"file://models/faceres.json"},{"name":"ssrnetgender","loaded":false,"url":null},{"name":"handpose","loaded":false,"url":null},{"name":"handskeleton","loaded":true,"url":"file://models/handlandmark-full.json"},{"name":"handtrack","loaded":true,"url":"file://models/handtrack.json"},{"name":"liveness","loaded":true,"url":"file://models/liveness.json"},{"name":"movenet","loaded":true,"url":"file://models/movenet-lightning.json"},{"name":"nanodet","loaded":false,"url":null},{"name":"posenet","loaded":false,"url":null},{"name":"segmentation","loaded":true,"url":"file://models/selfie.json"},{"name":"antispoof","loaded":true,"url":"file://models/antispoof.json"}] -2022-08-20 09:36:51 INFO:  test-node-gpu.js test: warmup -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: create human -2022-08-20 09:36:51 INFO:  test-node-gpu.js human version: 2.9.4 -2022-08-20 09:36:51 INFO:  test-node-gpu.js platform: linux x64 agent: NodeJS v18.1.0 -2022-08-20 09:36:51 INFO:  test-node-gpu.js tfjs version: 3.19.0 -2022-08-20 09:36:51 INFO:  test-node-gpu.js env: {"browser":false,"node":true,"platform":"linux x64","agent":"NodeJS v18.1.0","backends":["cpu","tensorflow"],"initial":false,"tfjs":{"version":"3.19.0"},"offscreen":false,"perfadd":false,"tensorflow":{"version":"2.7.3-dev20220521","gpu":true},"wasm":{"supported":true,"backend":false},"webgl":{"supported":false,"backend":false},"webgpu":{"supported":false,"backend":false},"cpu":{"flags":[]},"kernels":169} -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: set backend: tensorflow -2022-08-20 09:36:51 STATE: test-node-gpu.js tensors 1921 -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: load models -2022-08-20 09:36:51 STATE: test-node-gpu.js result: defined models: 23 loaded models: 12 -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: warmup: none default -2022-08-20 09:36:51 DATA:  test-node-gpu.js result: face: 0 body: 0 hand: 0 gesture: 0 object: 0 person: 0 {} {} {} -2022-08-20 09:36:51 DATA:  test-node-gpu.js result: performance: load: null total: null -2022-08-20 09:36:51 STATE: test-node-gpu.js passed: warmup none result match -2022-08-20 09:36:52 STATE: test-node-gpu.js event: image -2022-08-20 09:36:56 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:56 STATE: test-node-gpu.js event: warmup -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: warmup: face default -2022-08-20 09:36:56 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.42,"keypoints":4} -2022-08-20 09:36:56 DATA:  test-node-gpu.js result: performance: load: null total: 4057 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: warmup face result match -2022-08-20 09:36:56 STATE: test-node-gpu.js event: image -2022-08-20 09:36:56 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:56 STATE: test-node-gpu.js event: warmup -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: warmup: body default -2022-08-20 09:36:56 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:56 DATA:  test-node-gpu.js result: performance: load: null total: 151 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: warmup body result match -2022-08-20 09:36:56 STATE: test-node-gpu.js details: {"face":{"boxScore":0.92,"faceScore":1,"age":23.7,"gender":"female","genderScore":0.97},"emotion":[{"score":0.63,"emotion":"angry"},{"score":0.22,"emotion":"fear"}],"body":{"score":0.92,"keypoints":17},"hand":{"boxScore":0.52,"fingerScore":0.73,"keypoints":21},"gestures":[{"face":0,"gesture":"facing right"},{"face":0,"gesture":"mouth 10% open"},{"hand":0,"gesture":"pinky forward"},{"hand":0,"gesture":"palm up"},{"hand":0,"gesture":"open palm"},{"iris":0,"gesture":"looking left"},{"iris":0,"gesture":"looking up"}]} -2022-08-20 09:36:56 INFO:  test-node-gpu.js test: details verification -2022-08-20 09:36:56 STATE: test-node-gpu.js start default -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:56 STATE: test-node-gpu.js event: image -2022-08-20 09:36:56 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg default -2022-08-20 09:36:56 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:56 DATA:  test-node-gpu.js result: performance: load: null total: 151 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face length 1 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face score 1 0.93 1 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face age/gender 23.7 female 0.97 85.47 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face arrays 4 478 1024 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face emotion 2 {"score":0.59,"emotion":"angry"} -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face anti-spoofing 0.79 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details face liveness 0.83 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details body length 1 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details body 0.92 17 6 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details hand length 1 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details hand 0.51 0.73 point -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details hand arrays 21 5 7 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details gesture length 7 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details gesture first {"face":0,"gesture":"facing right"} -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details object length 1 -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: details object 0.72 person -2022-08-20 09:36:56 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996928} -2022-08-20 09:36:56 STATE: test-node-gpu.js event: image -2022-08-20 09:36:57 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:57 STATE: test-node-gpu.js passed: tensor shape: [1,1200,1200,4] dtype: float32 -2022-08-20 09:36:57 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1200,1200,4] {"checksum":1371996928} -2022-08-20 09:36:57 STATE: test-node-gpu.js event: image -2022-08-20 09:36:57 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:57 STATE: test-node-gpu.js passed: tensor shape: [1200,1200,4] dtype: float32 -2022-08-20 09:36:57 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:57 STATE: test-node-gpu.js event: image -2022-08-20 09:36:57 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:57 STATE: test-node-gpu.js passed: tensor shape: [1,1200,1200,3] dtype: float32 -2022-08-20 09:36:57 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:57 STATE: test-node-gpu.js event: image -2022-08-20 09:36:58 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: tensor shape: [1200,1200,3] dtype: float32 -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996871} -2022-08-20 09:36:58 STATE: test-node-gpu.js event: image -2022-08-20 09:36:58 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: tensor shape: [1,1200,1200,4] dtype: int32 -2022-08-20 09:36:58 INFO:  test-node-gpu.js test default -2022-08-20 09:36:58 STATE: test-node-gpu.js start async -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:58 STATE: test-node-gpu.js event: image -2022-08-20 09:36:58 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg async -2022-08-20 09:36:58 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:58 DATA:  test-node-gpu.js result: performance: load: null total: 146 -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: default result face match 1 female 0.97 -2022-08-20 09:36:58 INFO:  test-node-gpu.js test sync -2022-08-20 09:36:58 STATE: test-node-gpu.js start sync -2022-08-20 09:36:58 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:58 STATE: test-node-gpu.js event: image -2022-08-20 09:36:59 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg sync -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: performance: load: null total: 136 -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: default sync 1 female 0.97 -2022-08-20 09:36:59 INFO:  test-node-gpu.js test: image process -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: image input null [1,256,256,3] -2022-08-20 09:36:59 INFO:  test-node-gpu.js test: image null -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: invalid input could not convert input to tensor -2022-08-20 09:36:59 INFO:  test-node-gpu.js test face similarity -2022-08-20 09:36:59 STATE: test-node-gpu.js start face similarity -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:36:59 STATE: test-node-gpu.js event: image -2022-08-20 09:36:59 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face similarity -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: performance: load: null total: 127 -2022-08-20 09:36:59 STATE: test-node-gpu.js start face similarity -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:59 STATE: test-node-gpu.js event: image -2022-08-20 09:36:59 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg face similarity -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: performance: load: null total: 144 -2022-08-20 09:36:59 STATE: test-node-gpu.js start face similarity -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} -2022-08-20 09:36:59 STATE: test-node-gpu.js event: image -2022-08-20 09:36:59 STATE: test-node-gpu.js event: detect -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg face similarity -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 4 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.71,"class":"person"} {"score":0.75,"keypoints":7} -2022-08-20 09:36:59 DATA:  test-node-gpu.js result: performance: load: null total: 131 -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: face descriptor -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: face similarity {"similarity":[1,0.447238756461232,0.556914029877052],"descriptors":[1024,1024,1024]} -2022-08-20 09:36:59 INFO:  test-node-gpu.js test object -2022-08-20 09:36:59 STATE: test-node-gpu.js start object -2022-08-20 09:36:59 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:36:59 STATE: test-node-gpu.js event: image -2022-08-20 09:37:00 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:00 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg object -2022-08-20 09:37:00 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:00 DATA:  test-node-gpu.js result: performance: load: null total: 149 -2022-08-20 09:37:00 STATE: test-node-gpu.js passed: centernet -2022-08-20 09:37:00 STATE: test-node-gpu.js start object -2022-08-20 09:37:00 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:00 STATE: test-node-gpu.js event: image -2022-08-20 09:37:01 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg object -2022-08-20 09:37:01 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 3 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:01 DATA:  test-node-gpu.js result: performance: load: null total: 543 -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: nanodet -2022-08-20 09:37:01 INFO:  test-node-gpu.js test sensitive -2022-08-20 09:37:01 STATE: test-node-gpu.js start sensitive -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:01 STATE: test-node-gpu.js event: image -2022-08-20 09:37:01 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg sensitive -2022-08-20 09:37:01 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:01 DATA:  test-node-gpu.js result: performance: load: null total: 135 -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: sensitive result match -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: sensitive face result match -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: sensitive face emotion result [{"score":0.59,"emotion":"angry"},{"score":0.29,"emotion":"fear"}] -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: sensitive body result match -2022-08-20 09:37:01 STATE: test-node-gpu.js passed: sensitive hand result match -2022-08-20 09:37:01 INFO:  test-node-gpu.js test body -2022-08-20 09:37:01 STATE: test-node-gpu.js start blazepose -2022-08-20 09:37:03 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:03 STATE: test-node-gpu.js event: image -2022-08-20 09:37:03 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:03 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg blazepose -2022-08-20 09:37:03 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.99,"keypoints":39} -2022-08-20 09:37:03 DATA:  test-node-gpu.js result: performance: load: null total: 270 -2022-08-20 09:37:03 STATE: test-node-gpu.js passed: blazepose -2022-08-20 09:37:03 STATE: test-node-gpu.js start efficientpose -2022-08-20 09:37:04 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:04 STATE: test-node-gpu.js event: image -2022-08-20 09:37:04 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:04 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg efficientpose -2022-08-20 09:37:04 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.75,"keypoints":13} -2022-08-20 09:37:04 DATA:  test-node-gpu.js result: performance: load: null total: 880 -2022-08-20 09:37:04 STATE: test-node-gpu.js passed: efficientpose -2022-08-20 09:37:04 STATE: test-node-gpu.js start posenet -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:05 STATE: test-node-gpu.js event: image -2022-08-20 09:37:05 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg posenet -2022-08-20 09:37:05 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.96,"keypoints":16} -2022-08-20 09:37:05 DATA:  test-node-gpu.js result: performance: load: null total: 132 -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: posenet -2022-08-20 09:37:05 STATE: test-node-gpu.js start movenet -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:05 STATE: test-node-gpu.js event: image -2022-08-20 09:37:05 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg movenet -2022-08-20 09:37:05 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:05 DATA:  test-node-gpu.js result: performance: load: null total: 122 -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: movenet -2022-08-20 09:37:05 INFO:  test-node-gpu.js test face matching -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: face database 40 -2022-08-20 09:37:05 STATE: test-node-gpu.js passed: face match {"first":{"index":4,"similarity":0.7828184453007331}} {"second":{"index":4,"similarity":0.5001334216773398}} {"third":{"index":4,"similarity":0.5403054967489764}} -2022-08-20 09:37:05 INFO:  test-node-gpu.js test face similarity alternative -2022-08-20 09:37:05 STATE: test-node-gpu.js start face embeddings -2022-08-20 09:37:06 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:06 STATE: test-node-gpu.js event: image -2022-08-20 09:37:06 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:06 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face embeddings -2022-08-20 09:37:06 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:06 DATA:  test-node-gpu.js result: performance: load: null total: 151 -2022-08-20 09:37:06 STATE: test-node-gpu.js passed: mobilefacenet {"embedding":192} -2022-08-20 09:37:06 STATE: test-node-gpu.js start face embeddings -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:07 STATE: test-node-gpu.js event: image -2022-08-20 09:37:07 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face embeddings -2022-08-20 09:37:07 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:07 DATA:  test-node-gpu.js result: performance: load: null total: 169 -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: insightface {"embedding":512} -2022-08-20 09:37:07 INFO:  test-node-gpu.js test face attention -2022-08-20 09:37:07 STATE: test-node-gpu.js start face attention -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:07 STATE: test-node-gpu.js event: image -2022-08-20 09:37:07 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face attention -2022-08-20 09:37:07 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:07 DATA:  test-node-gpu.js result: performance: load: null total: 227 -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: face attention -2022-08-20 09:37:07 INFO:  test-node-gpu.js test detectors -2022-08-20 09:37:07 STATE: test-node-gpu.js start detectors -2022-08-20 09:37:07 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:07 STATE: test-node-gpu.js event: image -2022-08-20 09:37:08 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg detectors -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: performance: load: null total: 197 -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: detector result face match -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: detector result hand match -2022-08-20 09:37:08 INFO:  test-node-gpu.js test: multi-instance -2022-08-20 09:37:08 STATE: test-node-gpu.js start multi instance -2022-08-20 09:37:08 STATE: test-node-gpu.js event: image -2022-08-20 09:37:08 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: detect: random multi instance -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: face: 0 body: 1 hand: 0 gesture: 0 object: 0 person: 0 {} {} {"score":0,"keypoints":0} -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: performance: load: null total: 38 -2022-08-20 09:37:08 INFO:  test-node-gpu.js test: first instance -2022-08-20 09:37:08 STATE: test-node-gpu.js start multi instance -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg multi instance -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: performance: load: null total: 35 -2022-08-20 09:37:08 INFO:  test-node-gpu.js test: second instance -2022-08-20 09:37:08 STATE: test-node-gpu.js start multi instance -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg multi instance -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:08 DATA:  test-node-gpu.js result: performance: load: null total: 39 -2022-08-20 09:37:08 INFO:  test-node-gpu.js test: concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js start concurrent -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} -2022-08-20 09:37:08 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} -2022-08-20 09:37:09 STATE: test-node-gpu.js event: image -2022-08-20 09:37:09 STATE: test-node-gpu.js event: image -2022-08-20 09:37:09 STATE: test-node-gpu.js event: image -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 579 -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 579 -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 579 -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 580 -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 579 -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 580 -2022-08-20 09:37:09 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 315 -2022-08-20 09:37:09 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:09 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 315 -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:09 DATA:  test-node-gpu.js result: performance: load: null total: 315 -2022-08-20 09:37:09 INFO:  test-node-gpu.js test: monkey-patch -2022-08-20 09:37:09 STATE: test-node-gpu.js event: image -2022-08-20 09:37:09 STATE: test-node-gpu.js event: detect -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: monkey patch -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: segmentation [65536] -2022-08-20 09:37:09 STATE: test-node-gpu.js passeed: equal usage -2022-08-20 09:37:09 INFO:  test-node-gpu.js test: input compare -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} -2022-08-20 09:37:09 STATE: test-node-gpu.js passed: image compare 0 23.275441687091504 -2022-08-20 09:37:09 INFO:  test-node-gpu.js events: {"image":29,"detect":29,"warmup":2} -2022-08-20 09:37:09 INFO:  test-node-gpu.js tensors 4105 -2022-08-20 09:37:09 INFO:  test-node-gpu.js test complete: 17997 ms -2022-08-20 09:37:10 INFO:  -2022-08-20 09:37:10 INFO:  test-node-wasm.js start -2022-08-20 09:37:11 DATA:  test-node-wasm.js stdout: 2022-08-20 09:37:11 INFO:  { supported: true, backend: true, simd: true, multithread: false } -2022-08-20 09:37:11 STATE: test-node-wasm.js passed: model server: https://vladmandic.github.io/human/models/ -2022-08-20 09:37:11 INFO:  test-node-wasm.js test: configuration validation -2022-08-20 09:37:11 STATE: test-node-wasm.js passed: configuration default validation [] -2022-08-20 09:37:11 STATE: test-node-wasm.js passed: configuration invalid validation [{"reason":"unknown property","where":"config.invalid = true"}] -2022-08-20 09:37:11 INFO:  test-node-wasm.js test: model load -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: models loaded 23 12 [{"name":"ssrnetage","loaded":false,"url":null},{"name":"gear","loaded":false,"url":null},{"name":"blazeposedetect","loaded":false,"url":null},{"name":"blazepose","loaded":false,"url":null},{"name":"centernet","loaded":true,"url":"https://vladmandic.github.io/human/models/mb3-centernet.json"},{"name":"efficientpose","loaded":false,"url":null},{"name":"mobilefacenet","loaded":false,"url":null},{"name":"insightface","loaded":false,"url":null},{"name":"emotion","loaded":true,"url":"https://vladmandic.github.io/human/models/emotion.json"},{"name":"facedetect","loaded":true,"url":"https://vladmandic.github.io/human/models/blazeface.json"},{"name":"faceiris","loaded":true,"url":"https://vladmandic.github.io/human/models/iris.json"},{"name":"facemesh","loaded":true,"url":"https://vladmandic.github.io/human/models/facemesh.json"},{"name":"faceres","loaded":true,"url":"https://vladmandic.github.io/human/models/faceres.json"},{"name":"ssrnetgender","loaded":false,"url":null},{"name":"handpose","loaded":false,"url":null},{"name":"handskeleton","loaded":true,"url":"https://vladmandic.github.io/human/models/handlandmark-full.json"},{"name":"handtrack","loaded":true,"url":"https://vladmandic.github.io/human/models/handtrack.json"},{"name":"liveness","loaded":true,"url":"https://vladmandic.github.io/human/models/liveness.json"},{"name":"movenet","loaded":true,"url":"https://vladmandic.github.io/human/models/movenet-lightning.json"},{"name":"nanodet","loaded":false,"url":null},{"name":"posenet","loaded":false,"url":null},{"name":"segmentation","loaded":true,"url":"https://vladmandic.github.io/human/models/selfie.json"},{"name":"antispoof","loaded":true,"url":"https://vladmandic.github.io/human/models/antispoof.json"}] -2022-08-20 09:37:13 INFO:  test-node-wasm.js test: warmup -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: create human -2022-08-20 09:37:13 INFO:  test-node-wasm.js human version: 2.9.4 -2022-08-20 09:37:13 INFO:  test-node-wasm.js platform: linux x64 agent: NodeJS v18.1.0 -2022-08-20 09:37:13 INFO:  test-node-wasm.js tfjs version: 3.19.0 -2022-08-20 09:37:13 INFO:  test-node-wasm.js env: {"browser":false,"node":true,"platform":"linux x64","agent":"NodeJS v18.1.0","backends":["cpu","wasm"],"initial":false,"tfjs":{"version":"3.19.0"},"offscreen":false,"perfadd":false,"tensorflow":{},"wasm":{"supported":true,"backend":true,"simd":true,"multithread":false},"webgl":{"supported":false,"backend":false},"webgpu":{"supported":false,"backend":false},"cpu":{"flags":[]},"kernels":126} -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: set backend: wasm -2022-08-20 09:37:13 STATE: test-node-wasm.js tensors 1921 -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: load models -2022-08-20 09:37:13 STATE: test-node-wasm.js result: defined models: 23 loaded models: 12 -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: warmup: none default -2022-08-20 09:37:13 DATA:  test-node-wasm.js result: face: 0 body: 0 hand: 0 gesture: 0 object: 0 person: 0 {} {} {} -2022-08-20 09:37:13 DATA:  test-node-wasm.js result: performance: load: null total: null -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: warmup none result match -2022-08-20 09:37:13 STATE: test-node-wasm.js event: image -2022-08-20 09:37:13 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:13 STATE: test-node-wasm.js event: warmup -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: warmup: face default -2022-08-20 09:37:13 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} -2022-08-20 09:37:13 DATA:  test-node-wasm.js result: performance: load: null total: 561 -2022-08-20 09:37:13 STATE: test-node-wasm.js passed: warmup face result match -2022-08-20 09:37:13 STATE: test-node-wasm.js event: image -2022-08-20 09:37:14 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:14 STATE: test-node-wasm.js event: warmup -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: warmup: body default -2022-08-20 09:37:14 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:14 DATA:  test-node-wasm.js result: performance: load: null total: 396 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: warmup body result match -2022-08-20 09:37:14 STATE: test-node-wasm.js details: {"face":{"boxScore":0.93,"faceScore":1,"age":23.7,"gender":"female","genderScore":0.97},"emotion":[{"score":0.59,"emotion":"angry"},{"score":0.29,"emotion":"fear"}],"body":{"score":0.92,"keypoints":17},"hand":{"boxScore":0.51,"fingerScore":0.73,"keypoints":21},"gestures":[{"face":0,"gesture":"facing right"},{"face":0,"gesture":"mouth 21% open"},{"hand":0,"gesture":"pinky forward"},{"hand":0,"gesture":"palm up"},{"hand":0,"gesture":"open palm"},{"iris":0,"gesture":"looking left"},{"iris":0,"gesture":"looking up"}]} -2022-08-20 09:37:14 INFO:  test-node-wasm.js test: details verification -2022-08-20 09:37:14 STATE: test-node-wasm.js start default -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:14 STATE: test-node-wasm.js event: image -2022-08-20 09:37:14 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg default -2022-08-20 09:37:14 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:14 DATA:  test-node-wasm.js result: performance: load: null total: 342 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face length 1 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face score 1 0.93 1 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face age/gender 23.7 female 0.97 85.47 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face arrays 4 478 1024 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face emotion 2 {"score":0.59,"emotion":"angry"} -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face anti-spoofing 0.79 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details face liveness 0.83 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details body length 1 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details body 0.92 17 6 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details hand length 1 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details hand 0.51 0.73 point -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details hand arrays 21 5 7 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details gesture length 7 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details gesture first {"face":0,"gesture":"facing right"} -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details object length 1 -2022-08-20 09:37:14 STATE: test-node-wasm.js passed: details object 0.72 person -2022-08-20 09:37:15 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1413675264} -2022-08-20 09:37:15 STATE: test-node-wasm.js event: image -2022-08-20 09:37:15 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:15 STATE: test-node-wasm.js passed: tensor shape: [1,1200,1200,4] dtype: float32 -2022-08-20 09:37:15 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1200,1200,4] {"checksum":1413675264} -2022-08-20 09:37:15 STATE: test-node-wasm.js event: image -2022-08-20 09:37:15 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:15 STATE: test-node-wasm.js passed: tensor shape: [1200,1200,4] dtype: float32 -2022-08-20 09:37:16 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:16 STATE: test-node-wasm.js event: image -2022-08-20 09:37:16 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:16 STATE: test-node-wasm.js passed: tensor shape: [1,1200,1200,3] dtype: float32 -2022-08-20 09:37:16 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:16 STATE: test-node-wasm.js event: image -2022-08-20 09:37:17 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:17 STATE: test-node-wasm.js passed: tensor shape: [1200,1200,3] dtype: float32 -2022-08-20 09:37:17 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996871} -2022-08-20 09:37:17 STATE: test-node-wasm.js event: image -2022-08-20 09:37:17 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:17 STATE: test-node-wasm.js passed: tensor shape: [1,1200,1200,4] dtype: int32 -2022-08-20 09:37:17 INFO:  test-node-wasm.js test default -2022-08-20 09:37:17 STATE: test-node-wasm.js start async -2022-08-20 09:37:17 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:17 STATE: test-node-wasm.js event: image -2022-08-20 09:37:18 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg async -2022-08-20 09:37:18 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:18 DATA:  test-node-wasm.js result: performance: load: null total: 334 -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: default result face match 1 female 0.97 -2022-08-20 09:37:18 INFO:  test-node-wasm.js test sync -2022-08-20 09:37:18 STATE: test-node-wasm.js start sync -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:18 STATE: test-node-wasm.js event: image -2022-08-20 09:37:18 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg sync -2022-08-20 09:37:18 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:18 DATA:  test-node-wasm.js result: performance: load: null total: 327 -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: default sync 1 female 0.97 -2022-08-20 09:37:18 INFO:  test-node-wasm.js test: image process -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: image input null [1,256,256,3] -2022-08-20 09:37:18 INFO:  test-node-wasm.js test: image null -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: invalid input could not convert input to tensor -2022-08-20 09:37:18 INFO:  test-node-wasm.js test face similarity -2022-08-20 09:37:18 STATE: test-node-wasm.js start face similarity -2022-08-20 09:37:18 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:18 STATE: test-node-wasm.js event: image -2022-08-20 09:37:19 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face similarity -2022-08-20 09:37:19 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} -2022-08-20 09:37:19 DATA:  test-node-wasm.js result: performance: load: null total: 304 -2022-08-20 09:37:19 STATE: test-node-wasm.js start face similarity -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:19 STATE: test-node-wasm.js event: image -2022-08-20 09:37:19 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg face similarity -2022-08-20 09:37:19 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:19 DATA:  test-node-wasm.js result: performance: load: null total: 325 -2022-08-20 09:37:19 STATE: test-node-wasm.js start face similarity -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} -2022-08-20 09:37:19 STATE: test-node-wasm.js event: image -2022-08-20 09:37:19 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg face similarity -2022-08-20 09:37:19 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 4 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.71,"class":"person"} {"score":0.75,"keypoints":7} -2022-08-20 09:37:19 DATA:  test-node-wasm.js result: performance: load: null total: 293 -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: face descriptor -2022-08-20 09:37:19 STATE: test-node-wasm.js passed: face similarity {"similarity":[1,0.5266119940661309,0.4858842904087851],"descriptors":[1024,1024,1024]} -2022-08-20 09:37:19 INFO:  test-node-wasm.js test object -2022-08-20 09:37:19 STATE: test-node-wasm.js start object -2022-08-20 09:37:20 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:20 STATE: test-node-wasm.js event: image -2022-08-20 09:37:20 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:20 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg object -2022-08-20 09:37:20 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} -2022-08-20 09:37:20 DATA:  test-node-wasm.js result: performance: load: null total: 321 -2022-08-20 09:37:20 STATE: test-node-wasm.js passed: centernet -2022-08-20 09:37:20 STATE: test-node-wasm.js start object -2022-08-20 09:37:21 WARN:  test-node-wasm.js missing kernel ops {"title":"object","model":"nanodet","url":"https://vladmandic.github.io/human-models/models/nanodet.json","missing":["sparsetodense"],"backkend":"wasm"} -2022-08-20 09:37:21 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:21 STATE: test-node-wasm.js event: image -2022-08-20 09:37:21 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:21 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg object -2022-08-20 09:37:21 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:21 DATA:  test-node-wasm.js result: performance: load: null total: 213 -2022-08-20 09:37:21 ERROR: test-node-wasm.js failed: nanodet [] -2022-08-20 09:37:21 INFO:  test-node-wasm.js test sensitive -2022-08-20 09:37:21 STATE: test-node-wasm.js start sensitive -2022-08-20 09:37:21 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:21 STATE: test-node-wasm.js event: image -2022-08-20 09:37:22 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:22 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg sensitive -2022-08-20 09:37:22 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:22 DATA:  test-node-wasm.js result: performance: load: null total: 235 -2022-08-20 09:37:22 STATE: test-node-wasm.js passed: sensitive result match -2022-08-20 09:37:22 STATE: test-node-wasm.js passed: sensitive face result match -2022-08-20 09:37:22 STATE: test-node-wasm.js passed: sensitive face emotion result [{"score":0.46,"emotion":"neutral"},{"score":0.24,"emotion":"fear"},{"score":0.17,"emotion":"sad"}] -2022-08-20 09:37:22 STATE: test-node-wasm.js passed: sensitive body result match -2022-08-20 09:37:22 STATE: test-node-wasm.js passed: sensitive hand result match -2022-08-20 09:37:22 INFO:  test-node-wasm.js test body -2022-08-20 09:37:22 STATE: test-node-wasm.js start blazepose -2022-08-20 09:37:23 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:23 STATE: test-node-wasm.js event: image -2022-08-20 09:37:24 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:24 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg blazepose -2022-08-20 09:37:24 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.99,"keypoints":39} -2022-08-20 09:37:24 DATA:  test-node-wasm.js result: performance: load: null total: 389 -2022-08-20 09:37:24 STATE: test-node-wasm.js passed: blazepose -2022-08-20 09:37:24 STATE: test-node-wasm.js start efficientpose -2022-08-20 09:37:24 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:24 STATE: test-node-wasm.js event: image -2022-08-20 09:37:25 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:25 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg efficientpose -2022-08-20 09:37:25 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.75,"keypoints":13} -2022-08-20 09:37:25 DATA:  test-node-wasm.js result: performance: load: null total: 636 -2022-08-20 09:37:25 STATE: test-node-wasm.js passed: efficientpose -2022-08-20 09:37:25 STATE: test-node-wasm.js start posenet -2022-08-20 09:37:25 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:25 STATE: test-node-wasm.js event: image -2022-08-20 09:37:26 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg posenet -2022-08-20 09:37:26 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.96,"keypoints":16} -2022-08-20 09:37:26 DATA:  test-node-wasm.js result: performance: load: null total: 281 -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: posenet -2022-08-20 09:37:26 STATE: test-node-wasm.js start movenet -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:26 STATE: test-node-wasm.js event: image -2022-08-20 09:37:26 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg movenet -2022-08-20 09:37:26 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:26 DATA:  test-node-wasm.js result: performance: load: null total: 235 -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: movenet -2022-08-20 09:37:26 INFO:  test-node-wasm.js test face matching -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: face database 40 -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: face match {"first":{"index":4,"similarity":0.7827852754786533}} {"second":{"index":4,"similarity":0.5660821189104794}} {"third":{"index":4,"similarity":0.45074189882665594}} -2022-08-20 09:37:26 INFO:  test-node-wasm.js test face similarity alternative -2022-08-20 09:37:26 STATE: test-node-wasm.js start face embeddings -2022-08-20 09:37:26 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:26 STATE: test-node-wasm.js event: image -2022-08-20 09:37:27 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:27 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face embeddings -2022-08-20 09:37:27 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:27 DATA:  test-node-wasm.js result: performance: load: null total: 235 -2022-08-20 09:37:27 STATE: test-node-wasm.js passed: mobilefacenet {"embedding":192} -2022-08-20 09:37:27 STATE: test-node-wasm.js start face embeddings -2022-08-20 09:37:27 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:27 STATE: test-node-wasm.js event: image -2022-08-20 09:37:27 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:27 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face embeddings -2022-08-20 09:37:27 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:27 DATA:  test-node-wasm.js result: performance: load: null total: 278 -2022-08-20 09:37:27 STATE: test-node-wasm.js passed: insightface {"embedding":512} -2022-08-20 09:37:27 INFO:  test-node-wasm.js test face attention -2022-08-20 09:37:27 STATE: test-node-wasm.js start face attention -2022-08-20 09:37:28 WARN:  test-node-wasm.js missing kernel ops {"title":"face attention","model":"facemesh","url":"https://vladmandic.github.io/human-models/models/facemesh-attention.json","missing":["atan2"],"backkend":"wasm"} -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:28 STATE: test-node-wasm.js event: image -2022-08-20 09:37:28 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face attention -2022-08-20 09:37:28 DATA:  test-node-wasm.js result: face: 0 body: 1 hand: 1 gesture: 2 object: 0 person: 0 {} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:28 DATA:  test-node-wasm.js result: performance: load: null total: 119 -2022-08-20 09:37:28 ERROR: test-node-wasm.js failed: face attention {"annotations":0} -2022-08-20 09:37:28 INFO:  test-node-wasm.js test detectors -2022-08-20 09:37:28 STATE: test-node-wasm.js start detectors -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:28 STATE: test-node-wasm.js event: image -2022-08-20 09:37:28 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg detectors -2022-08-20 09:37:28 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:28 DATA:  test-node-wasm.js result: performance: load: null total: 114 -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: detector result face match -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: detector result hand match -2022-08-20 09:37:28 INFO:  test-node-wasm.js test: multi-instance -2022-08-20 09:37:28 STATE: test-node-wasm.js start multi instance -2022-08-20 09:37:28 STATE: test-node-wasm.js event: image -2022-08-20 09:37:28 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: detect: random multi instance -2022-08-20 09:37:28 DATA:  test-node-wasm.js result: face: 0 body: 1 hand: 0 gesture: 0 object: 0 person: 0 {} {} {"score":0,"keypoints":0} -2022-08-20 09:37:28 DATA:  test-node-wasm.js result: performance: load: null total: 97 -2022-08-20 09:37:28 INFO:  test-node-wasm.js test: first instance -2022-08-20 09:37:28 STATE: test-node-wasm.js start multi instance -2022-08-20 09:37:28 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg multi instance -2022-08-20 09:37:29 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:29 DATA:  test-node-wasm.js result: performance: load: null total: 110 -2022-08-20 09:37:29 INFO:  test-node-wasm.js test: second instance -2022-08-20 09:37:29 STATE: test-node-wasm.js start multi instance -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg multi instance -2022-08-20 09:37:29 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:29 DATA:  test-node-wasm.js result: performance: load: null total: 106 -2022-08-20 09:37:29 INFO:  test-node-wasm.js test: concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js start concurrent -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} -2022-08-20 09:37:29 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:30 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:30 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} -2022-08-20 09:37:30 STATE: test-node-wasm.js event: image -2022-08-20 09:37:30 STATE: test-node-wasm.js event: image -2022-08-20 09:37:30 STATE: test-node-wasm.js event: image -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 1283 -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 1283 -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 1284 -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 1284 -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 1284 -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 1284 -2022-08-20 09:37:31 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 972 -2022-08-20 09:37:31 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:31 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 972 -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg concurrent -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} -2022-08-20 09:37:31 DATA:  test-node-wasm.js result: performance: load: null total: 972 -2022-08-20 09:37:31 INFO:  test-node-wasm.js test: monkey-patch -2022-08-20 09:37:31 STATE: test-node-wasm.js event: image -2022-08-20 09:37:31 STATE: test-node-wasm.js event: detect -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: monkey patch -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: segmentation [65536] -2022-08-20 09:37:31 STATE: test-node-wasm.js passeed: equal usage -2022-08-20 09:37:31 INFO:  test-node-wasm.js test: input compare -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} -2022-08-20 09:37:31 STATE: test-node-wasm.js passed: image compare 0 23.280073018790848 -2022-08-20 09:37:31 INFO:  test-node-wasm.js events: {"image":29,"detect":29,"warmup":2} -2022-08-20 09:37:31 INFO:  test-node-wasm.js tensors 4107 -2022-08-20 09:37:31 INFO:  test-node-wasm.js test complete: 19995 ms -2022-08-20 09:37:31 STATE: all tests complete -2022-08-20 09:37:31 INFO:  status {"test":"../demo/nodejs/node.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/nodejs/node-simple.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/nodejs/node-fetch.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/nodejs/node-event.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/nodejs/node-similarity.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/nodejs/node-canvas.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/multithread/node-multiprocess.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"../demo/facematch/node-match.js","passed":1,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"test-node.js","passed":125,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"test-node-gpu.js","passed":125,"failed":0} -2022-08-20 09:37:31 INFO:  status {"test":"test-node-wasm.js","passed":124,"failed":2} -2022-08-20 09:37:31 INFO:  failures {"count":2} -2022-08-20 09:37:31 WARN:  failed {"test":"test-node-wasm.js","message":["error",["failed: nanodet",[]]]} -2022-08-20 09:37:31 WARN:  failed {"test":"test-node-wasm.js","message":["error",["failed: face attention",{"annotations":0}]]} +2022-08-21 15:21:45 INFO:  @vladmandic/human version 2.9.4 +2022-08-21 15:21:45 INFO:  User: vlado Platform: linux Arch: x64 Node: v18.1.0 +2022-08-21 15:21:45 INFO:  demos: [{"cmd":"../demo/nodejs/node.js","args":[]},{"cmd":"../demo/nodejs/node-simple.js","args":[]},{"cmd":"../demo/nodejs/node-fetch.js","args":[]},{"cmd":"../demo/nodejs/node-event.js","args":["samples/in/ai-body.jpg"]},{"cmd":"../demo/nodejs/node-similarity.js","args":["samples/in/ai-face.jpg","samples/in/ai-upper.jpg"]},{"cmd":"../demo/nodejs/node-canvas.js","args":["samples/in/ai-body.jpg","samples/out/ai-body.jpg"]},{"cmd":"../demo/multithread/node-multiprocess.js","args":[]},{"cmd":"../demo/facematch/node-match.js","args":[]}] +2022-08-21 15:21:45 INFO:  {"cmd":"../demo/nodejs/node.js","args":[]} start +2022-08-21 15:21:46 INFO:  {"cmd":"../demo/nodejs/node-simple.js","args":[]} start +2022-08-21 15:21:47 INFO:  {"cmd":"../demo/nodejs/node-fetch.js","args":[]} start +2022-08-21 15:21:49 INFO:  {"cmd":"../demo/nodejs/node-event.js","args":["samples/in/ai-body.jpg"]} start +2022-08-21 15:21:49 INFO:  {"cmd":"../demo/nodejs/node-similarity.js","args":["samples/in/ai-face.jpg","samples/in/ai-upper.jpg"]} start +2022-08-21 15:21:50 INFO:  {"cmd":"../demo/nodejs/node-canvas.js","args":["samples/in/ai-body.jpg","samples/out/ai-body.jpg"]} start +2022-08-21 15:21:51 INFO:  {"cmd":"../demo/multithread/node-multiprocess.js","args":[]} start +2022-08-21 15:21:52 INFO:  {"cmd":"../demo/facematch/node-match.js","args":[]} start +2022-08-21 15:21:54 INFO:  tests: ["test-node.js","test-node-gpu.js","test-node-wasm.js"] +2022-08-21 15:21:54 INFO:  +2022-08-21 15:21:54 INFO:  test-node.js start +2022-08-21 15:21:54 INFO:  test-node.js test: configuration validation +2022-08-21 15:21:54 STATE: test-node.js passed: configuration default validation [] +2022-08-21 15:21:54 STATE: test-node.js passed: configuration invalid validation [{"reason":"unknown property","where":"config.invalid = true"}] +2022-08-21 15:21:54 INFO:  test-node.js test: model load +2022-08-21 15:21:54 STATE: test-node.js passed: models loaded 23 12 [{"name":"ssrnetage","loaded":false,"url":null},{"name":"gear","loaded":false,"url":null},{"name":"blazeposedetect","loaded":false,"url":null},{"name":"blazepose","loaded":false,"url":null},{"name":"centernet","loaded":true,"url":"file://models/mb3-centernet.json"},{"name":"efficientpose","loaded":false,"url":null},{"name":"mobilefacenet","loaded":false,"url":null},{"name":"insightface","loaded":false,"url":null},{"name":"emotion","loaded":true,"url":"file://models/emotion.json"},{"name":"facedetect","loaded":true,"url":"file://models/blazeface.json"},{"name":"faceiris","loaded":true,"url":"file://models/iris.json"},{"name":"facemesh","loaded":true,"url":"file://models/facemesh.json"},{"name":"faceres","loaded":true,"url":"file://models/faceres.json"},{"name":"ssrnetgender","loaded":false,"url":null},{"name":"handpose","loaded":false,"url":null},{"name":"handskeleton","loaded":true,"url":"file://models/handlandmark-full.json"},{"name":"handtrack","loaded":true,"url":"file://models/handtrack.json"},{"name":"liveness","loaded":true,"url":"file://models/liveness.json"},{"name":"movenet","loaded":true,"url":"file://models/movenet-lightning.json"},{"name":"nanodet","loaded":false,"url":null},{"name":"posenet","loaded":false,"url":null},{"name":"segmentation","loaded":true,"url":"file://models/selfie.json"},{"name":"antispoof","loaded":true,"url":"file://models/antispoof.json"}] +2022-08-21 15:21:54 INFO:  test-node.js test: warmup +2022-08-21 15:21:54 STATE: test-node.js passed: create human +2022-08-21 15:21:54 INFO:  test-node.js human version: 2.9.4 +2022-08-21 15:21:54 INFO:  test-node.js platform: linux x64 agent: NodeJS v18.1.0 +2022-08-21 15:21:54 INFO:  test-node.js tfjs version: 3.19.0 +2022-08-21 15:21:54 INFO:  test-node.js env: {"browser":false,"node":true,"platform":"linux x64","agent":"NodeJS v18.1.0","backends":["cpu","tensorflow"],"initial":false,"tfjs":{"version":"3.19.0"},"offscreen":false,"perfadd":false,"tensorflow":{"version":"2.7.3-dev20220521","gpu":false},"wasm":{"supported":true,"backend":false},"webgl":{"supported":false,"backend":false},"webgpu":{"supported":false,"backend":false},"cpu":{"flags":[]},"kernels":169} +2022-08-21 15:21:54 STATE: test-node.js passed: set backend: tensorflow +2022-08-21 15:21:54 STATE: test-node.js tensors 1921 +2022-08-21 15:21:54 STATE: test-node.js passed: load models +2022-08-21 15:21:54 STATE: test-node.js result: defined models: 23 loaded models: 12 +2022-08-21 15:21:54 STATE: test-node.js passed: warmup: none default +2022-08-21 15:21:54 DATA:  test-node.js result: face: 0 body: 0 hand: 0 gesture: 0 object: 0 person: 0 {} {} {} +2022-08-21 15:21:54 DATA:  test-node.js result: performance: load: null total: null +2022-08-21 15:21:54 STATE: test-node.js passed: warmup none result match +2022-08-21 15:21:54 STATE: test-node.js event: image +2022-08-21 15:21:54 STATE: test-node.js event: detect +2022-08-21 15:21:54 STATE: test-node.js event: warmup +2022-08-21 15:21:54 STATE: test-node.js passed: warmup: face default +2022-08-21 15:21:54 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.42,"keypoints":4} +2022-08-21 15:21:54 DATA:  test-node.js result: performance: load: null total: 341 +2022-08-21 15:21:54 STATE: test-node.js passed: warmup face result match +2022-08-21 15:21:54 STATE: test-node.js event: image +2022-08-21 15:21:54 STATE: test-node.js event: detect +2022-08-21 15:21:54 STATE: test-node.js event: warmup +2022-08-21 15:21:54 STATE: test-node.js passed: warmup: body default +2022-08-21 15:21:54 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:21:54 DATA:  test-node.js result: performance: load: null total: 238 +2022-08-21 15:21:54 STATE: test-node.js passed: warmup body result match +2022-08-21 15:21:54 STATE: test-node.js details: {"face":{"boxScore":0.92,"faceScore":1,"age":23.7,"gender":"female","genderScore":0.97},"emotion":[{"score":0.63,"emotion":"angry"},{"score":0.22,"emotion":"fear"}],"body":{"score":0.92,"keypoints":17},"hand":{"boxScore":0.52,"fingerScore":0.73,"keypoints":21},"gestures":[{"face":0,"gesture":"facing right"},{"face":0,"gesture":"mouth 10% open"},{"hand":0,"gesture":"pinky forward"},{"hand":0,"gesture":"palm up"},{"hand":0,"gesture":"open palm"},{"iris":0,"gesture":"looking left"},{"iris":0,"gesture":"looking up"}]} +2022-08-21 15:21:54 INFO:  test-node.js test: details verification +2022-08-21 15:21:54 STATE: test-node.js start default +2022-08-21 15:21:55 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:55 STATE: test-node.js event: image +2022-08-21 15:21:55 STATE: test-node.js event: detect +2022-08-21 15:21:55 STATE: test-node.js passed: detect: samples/in/ai-body.jpg default +2022-08-21 15:21:55 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:21:55 DATA:  test-node.js result: performance: load: null total: 225 +2022-08-21 15:21:55 STATE: test-node.js passed: details face length 1 +2022-08-21 15:21:55 STATE: test-node.js passed: details face score 1 0.93 1 +2022-08-21 15:21:55 STATE: test-node.js passed: details face age/gender 23.7 female 0.97 85.47 +2022-08-21 15:21:55 STATE: test-node.js passed: details face arrays 4 478 1024 +2022-08-21 15:21:55 STATE: test-node.js passed: details face emotion 2 {"score":0.59,"emotion":"angry"} +2022-08-21 15:21:55 STATE: test-node.js passed: details face anti-spoofing 0.79 +2022-08-21 15:21:55 STATE: test-node.js passed: details face liveness 0.83 +2022-08-21 15:21:55 STATE: test-node.js passed: details body length 1 +2022-08-21 15:21:55 STATE: test-node.js passed: details body 0.92 17 6 +2022-08-21 15:21:55 STATE: test-node.js passed: details hand length 1 +2022-08-21 15:21:55 STATE: test-node.js passed: details hand 0.51 0.73 point +2022-08-21 15:21:55 STATE: test-node.js passed: details hand arrays 21 5 7 +2022-08-21 15:21:55 STATE: test-node.js passed: details gesture length 7 +2022-08-21 15:21:55 STATE: test-node.js passed: details gesture first {"face":0,"gesture":"facing right"} +2022-08-21 15:21:55 STATE: test-node.js passed: details object length 1 +2022-08-21 15:21:55 STATE: test-node.js passed: details object 0.72 person +2022-08-21 15:21:55 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996928} +2022-08-21 15:21:55 STATE: test-node.js event: image +2022-08-21 15:21:55 STATE: test-node.js event: detect +2022-08-21 15:21:55 STATE: test-node.js passed: tensor shape: [1,1200,1200,4] dtype: float32 +2022-08-21 15:21:55 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1200,1200,4] {"checksum":1371996928} +2022-08-21 15:21:55 STATE: test-node.js event: image +2022-08-21 15:21:56 STATE: test-node.js event: detect +2022-08-21 15:21:56 STATE: test-node.js passed: tensor shape: [1200,1200,4] dtype: float32 +2022-08-21 15:21:56 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:56 STATE: test-node.js event: image +2022-08-21 15:21:56 STATE: test-node.js event: detect +2022-08-21 15:21:56 STATE: test-node.js passed: tensor shape: [1,1200,1200,3] dtype: float32 +2022-08-21 15:21:56 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:56 STATE: test-node.js event: image +2022-08-21 15:21:56 STATE: test-node.js event: detect +2022-08-21 15:21:56 STATE: test-node.js passed: tensor shape: [1200,1200,3] dtype: float32 +2022-08-21 15:21:57 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996871} +2022-08-21 15:21:57 STATE: test-node.js event: image +2022-08-21 15:21:57 STATE: test-node.js event: detect +2022-08-21 15:21:57 STATE: test-node.js passed: tensor shape: [1,1200,1200,4] dtype: int32 +2022-08-21 15:21:57 INFO:  test-node.js test default +2022-08-21 15:21:57 STATE: test-node.js start async +2022-08-21 15:21:57 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:57 STATE: test-node.js event: image +2022-08-21 15:21:57 STATE: test-node.js event: detect +2022-08-21 15:21:57 STATE: test-node.js passed: detect: samples/in/ai-body.jpg async +2022-08-21 15:21:57 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:21:57 DATA:  test-node.js result: performance: load: null total: 207 +2022-08-21 15:21:57 STATE: test-node.js passed: default result face match 1 female 0.97 +2022-08-21 15:21:57 INFO:  test-node.js test sync +2022-08-21 15:21:57 STATE: test-node.js start sync +2022-08-21 15:21:57 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:57 STATE: test-node.js event: image +2022-08-21 15:21:58 STATE: test-node.js event: detect +2022-08-21 15:21:58 STATE: test-node.js passed: detect: samples/in/ai-body.jpg sync +2022-08-21 15:21:58 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:21:58 DATA:  test-node.js result: performance: load: null total: 206 +2022-08-21 15:21:58 STATE: test-node.js passed: default sync 1 female 0.97 +2022-08-21 15:21:58 INFO:  test-node.js test: image process +2022-08-21 15:21:58 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:21:58 STATE: test-node.js passed: image input null [1,256,256,3] +2022-08-21 15:21:58 INFO:  test-node.js test: image null +2022-08-21 15:21:58 STATE: test-node.js passed: invalid input could not convert input to tensor +2022-08-21 15:21:58 INFO:  test-node.js test face similarity +2022-08-21 15:21:58 STATE: test-node.js start face similarity +2022-08-21 15:21:58 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:21:58 STATE: test-node.js event: image +2022-08-21 15:21:58 STATE: test-node.js event: detect +2022-08-21 15:21:58 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face similarity +2022-08-21 15:21:58 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} +2022-08-21 15:21:58 DATA:  test-node.js result: performance: load: null total: 198 +2022-08-21 15:21:58 STATE: test-node.js start face similarity +2022-08-21 15:21:58 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:58 STATE: test-node.js event: image +2022-08-21 15:21:58 STATE: test-node.js event: detect +2022-08-21 15:21:58 STATE: test-node.js passed: detect: samples/in/ai-body.jpg face similarity +2022-08-21 15:21:58 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:21:58 DATA:  test-node.js result: performance: load: null total: 215 +2022-08-21 15:21:58 STATE: test-node.js start face similarity +2022-08-21 15:21:58 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} +2022-08-21 15:21:58 STATE: test-node.js event: image +2022-08-21 15:21:58 STATE: test-node.js event: detect +2022-08-21 15:21:58 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg face similarity +2022-08-21 15:21:58 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 4 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.71,"class":"person"} {"score":0.75,"keypoints":7} +2022-08-21 15:21:58 DATA:  test-node.js result: performance: load: null total: 186 +2022-08-21 15:21:58 STATE: test-node.js passed: face descriptor +2022-08-21 15:21:58 STATE: test-node.js passed: face similarity {"similarity":[1,0.44727452329649126,0.5567935850640406],"descriptors":[1024,1024,1024]} +2022-08-21 15:21:58 INFO:  test-node.js test object +2022-08-21 15:21:58 STATE: test-node.js start object +2022-08-21 15:21:59 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:21:59 STATE: test-node.js event: image +2022-08-21 15:21:59 STATE: test-node.js event: detect +2022-08-21 15:21:59 STATE: test-node.js passed: detect: samples/in/ai-body.jpg object +2022-08-21 15:21:59 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:21:59 DATA:  test-node.js result: performance: load: null total: 208 +2022-08-21 15:21:59 STATE: test-node.js passed: centernet +2022-08-21 15:21:59 STATE: test-node.js start object +2022-08-21 15:22:00 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:00 STATE: test-node.js event: image +2022-08-21 15:22:00 STATE: test-node.js event: detect +2022-08-21 15:22:00 STATE: test-node.js passed: detect: samples/in/ai-body.jpg object +2022-08-21 15:22:00 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 3 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:00 DATA:  test-node.js result: performance: load: null total: 217 +2022-08-21 15:22:00 STATE: test-node.js passed: nanodet +2022-08-21 15:22:00 INFO:  test-node.js test sensitive +2022-08-21 15:22:00 STATE: test-node.js start sensitive +2022-08-21 15:22:00 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:00 STATE: test-node.js event: image +2022-08-21 15:22:00 STATE: test-node.js event: detect +2022-08-21 15:22:00 STATE: test-node.js passed: detect: samples/in/ai-body.jpg sensitive +2022-08-21 15:22:00 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:00 DATA:  test-node.js result: performance: load: null total: 163 +2022-08-21 15:22:00 STATE: test-node.js passed: sensitive result match +2022-08-21 15:22:00 STATE: test-node.js passed: sensitive face result match +2022-08-21 15:22:00 STATE: test-node.js passed: sensitive face emotion result [{"score":0.59,"emotion":"angry"},{"score":0.29,"emotion":"fear"}] +2022-08-21 15:22:00 STATE: test-node.js passed: sensitive body result match +2022-08-21 15:22:00 STATE: test-node.js passed: sensitive hand result match +2022-08-21 15:22:00 INFO:  test-node.js test body +2022-08-21 15:22:00 STATE: test-node.js start blazepose +2022-08-21 15:22:02 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:02 STATE: test-node.js event: image +2022-08-21 15:22:02 STATE: test-node.js event: detect +2022-08-21 15:22:02 STATE: test-node.js passed: detect: samples/in/ai-body.jpg blazepose +2022-08-21 15:22:02 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.99,"keypoints":39} +2022-08-21 15:22:02 DATA:  test-node.js result: performance: load: null total: 215 +2022-08-21 15:22:02 STATE: test-node.js passed: blazepose +2022-08-21 15:22:02 STATE: test-node.js start efficientpose +2022-08-21 15:22:03 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:03 STATE: test-node.js event: image +2022-08-21 15:22:03 STATE: test-node.js event: detect +2022-08-21 15:22:03 STATE: test-node.js passed: detect: samples/in/ai-body.jpg efficientpose +2022-08-21 15:22:03 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.75,"keypoints":13} +2022-08-21 15:22:03 DATA:  test-node.js result: performance: load: null total: 243 +2022-08-21 15:22:03 STATE: test-node.js passed: efficientpose +2022-08-21 15:22:03 STATE: test-node.js start posenet +2022-08-21 15:22:04 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:04 STATE: test-node.js event: image +2022-08-21 15:22:04 STATE: test-node.js event: detect +2022-08-21 15:22:04 STATE: test-node.js passed: detect: samples/in/ai-body.jpg posenet +2022-08-21 15:22:04 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.96,"keypoints":16} +2022-08-21 15:22:04 DATA:  test-node.js result: performance: load: null total: 187 +2022-08-21 15:22:04 STATE: test-node.js passed: posenet +2022-08-21 15:22:04 STATE: test-node.js start movenet +2022-08-21 15:22:04 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:04 STATE: test-node.js event: image +2022-08-21 15:22:04 STATE: test-node.js event: detect +2022-08-21 15:22:04 STATE: test-node.js passed: detect: samples/in/ai-body.jpg movenet +2022-08-21 15:22:04 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:04 DATA:  test-node.js result: performance: load: null total: 172 +2022-08-21 15:22:04 STATE: test-node.js passed: movenet +2022-08-21 15:22:04 INFO:  test-node.js test face matching +2022-08-21 15:22:04 STATE: test-node.js passed: face database 40 +2022-08-21 15:22:04 STATE: test-node.js passed: face match {"first":{"index":4,"similarity":0.7827852615252829}} {"second":{"index":4,"similarity":0.5002052633015844}} {"third":{"index":4,"similarity":0.5401587887998899}} +2022-08-21 15:22:04 INFO:  test-node.js test face similarity alternative +2022-08-21 15:22:04 STATE: test-node.js start face embeddings +2022-08-21 15:22:05 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:05 STATE: test-node.js event: image +2022-08-21 15:22:05 STATE: test-node.js event: detect +2022-08-21 15:22:05 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face embeddings +2022-08-21 15:22:05 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:05 DATA:  test-node.js result: performance: load: null total: 189 +2022-08-21 15:22:05 STATE: test-node.js passed: mobilefacenet {"embedding":192} +2022-08-21 15:22:05 STATE: test-node.js start face embeddings +2022-08-21 15:22:05 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:05 STATE: test-node.js event: image +2022-08-21 15:22:06 STATE: test-node.js event: detect +2022-08-21 15:22:06 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face embeddings +2022-08-21 15:22:06 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:06 DATA:  test-node.js result: performance: load: null total: 201 +2022-08-21 15:22:06 STATE: test-node.js passed: insightface {"embedding":512} +2022-08-21 15:22:06 INFO:  test-node.js test face attention +2022-08-21 15:22:06 STATE: test-node.js start face attention +2022-08-21 15:22:06 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:06 STATE: test-node.js event: image +2022-08-21 15:22:06 STATE: test-node.js event: detect +2022-08-21 15:22:06 STATE: test-node.js passed: detect: samples/in/ai-face.jpg face attention +2022-08-21 15:22:06 DATA:  test-node.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:06 DATA:  test-node.js result: performance: load: null total: 176 +2022-08-21 15:22:06 STATE: test-node.js passed: face attention +2022-08-21 15:22:06 INFO:  test-node.js test detectors +2022-08-21 15:22:06 STATE: test-node.js start detectors +2022-08-21 15:22:06 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:06 STATE: test-node.js event: image +2022-08-21 15:22:06 STATE: test-node.js event: detect +2022-08-21 15:22:06 STATE: test-node.js passed: detect: samples/in/ai-body.jpg detectors +2022-08-21 15:22:06 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:06 DATA:  test-node.js result: performance: load: null total: 88 +2022-08-21 15:22:06 STATE: test-node.js passed: detector result face match +2022-08-21 15:22:06 STATE: test-node.js passed: detector result hand match +2022-08-21 15:22:06 INFO:  test-node.js test: multi-instance +2022-08-21 15:22:06 STATE: test-node.js start multi instance +2022-08-21 15:22:06 STATE: test-node.js event: image +2022-08-21 15:22:07 STATE: test-node.js event: detect +2022-08-21 15:22:07 STATE: test-node.js passed: detect: random multi instance +2022-08-21 15:22:07 DATA:  test-node.js result: face: 0 body: 1 hand: 0 gesture: 0 object: 0 person: 0 {} {} {"score":0,"keypoints":0} +2022-08-21 15:22:07 DATA:  test-node.js result: performance: load: null total: 84 +2022-08-21 15:22:07 INFO:  test-node.js test: first instance +2022-08-21 15:22:07 STATE: test-node.js start multi instance +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} +2022-08-21 15:22:07 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg multi instance +2022-08-21 15:22:07 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:07 DATA:  test-node.js result: performance: load: null total: 85 +2022-08-21 15:22:07 INFO:  test-node.js test: second instance +2022-08-21 15:22:07 STATE: test-node.js start multi instance +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} +2022-08-21 15:22:07 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg multi instance +2022-08-21 15:22:07 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:07 DATA:  test-node.js result: performance: load: null total: 79 +2022-08-21 15:22:07 INFO:  test-node.js test: concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js start concurrent +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} +2022-08-21 15:22:07 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:08 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:08 STATE: test-node.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289024} +2022-08-21 15:22:08 STATE: test-node.js event: image +2022-08-21 15:22:08 STATE: test-node.js event: image +2022-08-21 15:22:08 STATE: test-node.js event: image +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 948 +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 948 +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 949 +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 949 +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 949 +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 949 +2022-08-21 15:22:08 STATE: test-node.js event: detect +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 710 +2022-08-21 15:22:08 STATE: test-node.js event: detect +2022-08-21 15:22:08 STATE: test-node.js event: detect +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 710 +2022-08-21 15:22:08 STATE: test-node.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:08 DATA:  test-node.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:08 DATA:  test-node.js result: performance: load: null total: 710 +2022-08-21 15:22:08 INFO:  test-node.js test: monkey-patch +2022-08-21 15:22:08 STATE: test-node.js event: image +2022-08-21 15:22:08 STATE: test-node.js event: detect +2022-08-21 15:22:08 STATE: test-node.js passed: monkey patch +2022-08-21 15:22:08 STATE: test-node.js passed: segmentation [65536] +2022-08-21 15:22:08 STATE: test-node.js passeed: equal usage +2022-08-21 15:22:08 INFO:  test-node.js test: input compare +2022-08-21 15:22:08 STATE: test-node.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:09 STATE: test-node.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796864} +2022-08-21 15:22:09 STATE: test-node.js passed: image compare 0 23.275441687091504 +2022-08-21 15:22:09 INFO:  test-node.js events: {"image":29,"detect":29,"warmup":2} +2022-08-21 15:22:09 INFO:  test-node.js tensors 4105 +2022-08-21 15:22:09 INFO:  test-node.js test complete: 14891 ms +2022-08-21 15:22:09 INFO:  +2022-08-21 15:22:09 INFO:  test-node-gpu.js start +2022-08-21 15:22:10 INFO:  test-node-gpu.js test: configuration validation +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: configuration default validation [] +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: configuration invalid validation [{"reason":"unknown property","where":"config.invalid = true"}] +2022-08-21 15:22:10 INFO:  test-node-gpu.js test: model load +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: models loaded 23 12 [{"name":"ssrnetage","loaded":false,"url":null},{"name":"gear","loaded":false,"url":null},{"name":"blazeposedetect","loaded":false,"url":null},{"name":"blazepose","loaded":false,"url":null},{"name":"centernet","loaded":true,"url":"file://models/mb3-centernet.json"},{"name":"efficientpose","loaded":false,"url":null},{"name":"mobilefacenet","loaded":false,"url":null},{"name":"insightface","loaded":false,"url":null},{"name":"emotion","loaded":true,"url":"file://models/emotion.json"},{"name":"facedetect","loaded":true,"url":"file://models/blazeface.json"},{"name":"faceiris","loaded":true,"url":"file://models/iris.json"},{"name":"facemesh","loaded":true,"url":"file://models/facemesh.json"},{"name":"faceres","loaded":true,"url":"file://models/faceres.json"},{"name":"ssrnetgender","loaded":false,"url":null},{"name":"handpose","loaded":false,"url":null},{"name":"handskeleton","loaded":true,"url":"file://models/handlandmark-full.json"},{"name":"handtrack","loaded":true,"url":"file://models/handtrack.json"},{"name":"liveness","loaded":true,"url":"file://models/liveness.json"},{"name":"movenet","loaded":true,"url":"file://models/movenet-lightning.json"},{"name":"nanodet","loaded":false,"url":null},{"name":"posenet","loaded":false,"url":null},{"name":"segmentation","loaded":true,"url":"file://models/selfie.json"},{"name":"antispoof","loaded":true,"url":"file://models/antispoof.json"}] +2022-08-21 15:22:10 INFO:  test-node-gpu.js test: warmup +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: create human +2022-08-21 15:22:10 INFO:  test-node-gpu.js human version: 2.9.4 +2022-08-21 15:22:10 INFO:  test-node-gpu.js platform: linux x64 agent: NodeJS v18.1.0 +2022-08-21 15:22:10 INFO:  test-node-gpu.js tfjs version: 3.19.0 +2022-08-21 15:22:10 INFO:  test-node-gpu.js env: {"browser":false,"node":true,"platform":"linux x64","agent":"NodeJS v18.1.0","backends":["cpu","tensorflow"],"initial":false,"tfjs":{"version":"3.19.0"},"offscreen":false,"perfadd":false,"tensorflow":{"version":"2.7.3-dev20220521","gpu":true},"wasm":{"supported":true,"backend":false},"webgl":{"supported":false,"backend":false},"webgpu":{"supported":false,"backend":false},"cpu":{"flags":[]},"kernels":169} +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: set backend: tensorflow +2022-08-21 15:22:10 STATE: test-node-gpu.js tensors 1921 +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: load models +2022-08-21 15:22:10 STATE: test-node-gpu.js result: defined models: 23 loaded models: 12 +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: warmup: none default +2022-08-21 15:22:10 DATA:  test-node-gpu.js result: face: 0 body: 0 hand: 0 gesture: 0 object: 0 person: 0 {} {} {} +2022-08-21 15:22:10 DATA:  test-node-gpu.js result: performance: load: null total: null +2022-08-21 15:22:10 STATE: test-node-gpu.js passed: warmup none result match +2022-08-21 15:22:11 STATE: test-node-gpu.js event: image +2022-08-21 15:22:15 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:15 STATE: test-node-gpu.js event: warmup +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: warmup: face default +2022-08-21 15:22:15 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.42,"keypoints":4} +2022-08-21 15:22:15 DATA:  test-node-gpu.js result: performance: load: null total: 4062 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: warmup face result match +2022-08-21 15:22:15 STATE: test-node-gpu.js event: image +2022-08-21 15:22:15 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:15 STATE: test-node-gpu.js event: warmup +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: warmup: body default +2022-08-21 15:22:15 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:15 DATA:  test-node-gpu.js result: performance: load: null total: 155 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: warmup body result match +2022-08-21 15:22:15 STATE: test-node-gpu.js details: {"face":{"boxScore":0.92,"faceScore":1,"age":23.7,"gender":"female","genderScore":0.97},"emotion":[{"score":0.63,"emotion":"angry"},{"score":0.22,"emotion":"fear"}],"body":{"score":0.92,"keypoints":17},"hand":{"boxScore":0.52,"fingerScore":0.73,"keypoints":21},"gestures":[{"face":0,"gesture":"facing right"},{"face":0,"gesture":"mouth 10% open"},{"hand":0,"gesture":"pinky forward"},{"hand":0,"gesture":"palm up"},{"hand":0,"gesture":"open palm"},{"iris":0,"gesture":"looking left"},{"iris":0,"gesture":"looking up"}]} +2022-08-21 15:22:15 INFO:  test-node-gpu.js test: details verification +2022-08-21 15:22:15 STATE: test-node-gpu.js start default +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:15 STATE: test-node-gpu.js event: image +2022-08-21 15:22:15 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg default +2022-08-21 15:22:15 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:15 DATA:  test-node-gpu.js result: performance: load: null total: 164 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face length 1 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face score 1 0.93 1 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face age/gender 23.7 female 0.97 85.47 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face arrays 4 478 1024 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face emotion 2 {"score":0.59,"emotion":"angry"} +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face anti-spoofing 0.79 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details face liveness 0.83 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details body length 1 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details body 0.92 17 6 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details hand length 1 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details hand 0.51 0.73 point +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details hand arrays 21 5 7 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details gesture length 7 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details gesture first {"face":0,"gesture":"facing right"} +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details object length 1 +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: details object 0.72 person +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996928} +2022-08-21 15:22:15 STATE: test-node-gpu.js event: image +2022-08-21 15:22:15 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:15 STATE: test-node-gpu.js passed: tensor shape: [1,1200,1200,4] dtype: float32 +2022-08-21 15:22:16 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1200,1200,4] {"checksum":1371996928} +2022-08-21 15:22:16 STATE: test-node-gpu.js event: image +2022-08-21 15:22:16 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:16 STATE: test-node-gpu.js passed: tensor shape: [1200,1200,4] dtype: float32 +2022-08-21 15:22:16 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:16 STATE: test-node-gpu.js event: image +2022-08-21 15:22:16 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:16 STATE: test-node-gpu.js passed: tensor shape: [1,1200,1200,3] dtype: float32 +2022-08-21 15:22:16 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:16 STATE: test-node-gpu.js event: image +2022-08-21 15:22:16 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:16 STATE: test-node-gpu.js passed: tensor shape: [1200,1200,3] dtype: float32 +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996871} +2022-08-21 15:22:17 STATE: test-node-gpu.js event: image +2022-08-21 15:22:17 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: tensor shape: [1,1200,1200,4] dtype: int32 +2022-08-21 15:22:17 INFO:  test-node-gpu.js test default +2022-08-21 15:22:17 STATE: test-node-gpu.js start async +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:17 STATE: test-node-gpu.js event: image +2022-08-21 15:22:17 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg async +2022-08-21 15:22:17 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:17 DATA:  test-node-gpu.js result: performance: load: null total: 143 +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: default result face match 1 female 0.97 +2022-08-21 15:22:17 INFO:  test-node-gpu.js test sync +2022-08-21 15:22:17 STATE: test-node-gpu.js start sync +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:17 STATE: test-node-gpu.js event: image +2022-08-21 15:22:17 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg sync +2022-08-21 15:22:17 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:17 DATA:  test-node-gpu.js result: performance: load: null total: 138 +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: default sync 1 female 0.97 +2022-08-21 15:22:17 INFO:  test-node-gpu.js test: image process +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: image input null [1,256,256,3] +2022-08-21 15:22:17 INFO:  test-node-gpu.js test: image null +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: invalid input could not convert input to tensor +2022-08-21 15:22:17 INFO:  test-node-gpu.js test face similarity +2022-08-21 15:22:17 STATE: test-node-gpu.js start face similarity +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:17 STATE: test-node-gpu.js event: image +2022-08-21 15:22:17 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:17 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face similarity +2022-08-21 15:22:17 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} +2022-08-21 15:22:17 DATA:  test-node-gpu.js result: performance: load: null total: 142 +2022-08-21 15:22:17 STATE: test-node-gpu.js start face similarity +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:18 STATE: test-node-gpu.js event: image +2022-08-21 15:22:18 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg face similarity +2022-08-21 15:22:18 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:18 DATA:  test-node-gpu.js result: performance: load: null total: 143 +2022-08-21 15:22:18 STATE: test-node-gpu.js start face similarity +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} +2022-08-21 15:22:18 STATE: test-node-gpu.js event: image +2022-08-21 15:22:18 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg face similarity +2022-08-21 15:22:18 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 4 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.71,"class":"person"} {"score":0.75,"keypoints":7} +2022-08-21 15:22:18 DATA:  test-node-gpu.js result: performance: load: null total: 127 +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: face descriptor +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: face similarity {"similarity":[1,0.447238756461232,0.556914029877052],"descriptors":[1024,1024,1024]} +2022-08-21 15:22:18 INFO:  test-node-gpu.js test object +2022-08-21 15:22:18 STATE: test-node-gpu.js start object +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:18 STATE: test-node-gpu.js event: image +2022-08-21 15:22:18 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg object +2022-08-21 15:22:18 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:18 DATA:  test-node-gpu.js result: performance: load: null total: 134 +2022-08-21 15:22:18 STATE: test-node-gpu.js passed: centernet +2022-08-21 15:22:18 STATE: test-node-gpu.js start object +2022-08-21 15:22:19 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:19 STATE: test-node-gpu.js event: image +2022-08-21 15:22:20 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg object +2022-08-21 15:22:20 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 3 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:20 DATA:  test-node-gpu.js result: performance: load: null total: 660 +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: nanodet +2022-08-21 15:22:20 INFO:  test-node-gpu.js test sensitive +2022-08-21 15:22:20 STATE: test-node-gpu.js start sensitive +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:20 STATE: test-node-gpu.js event: image +2022-08-21 15:22:20 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg sensitive +2022-08-21 15:22:20 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:20 DATA:  test-node-gpu.js result: performance: load: null total: 95 +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: sensitive result match +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: sensitive face result match +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: sensitive face emotion result [{"score":0.59,"emotion":"angry"},{"score":0.29,"emotion":"fear"}] +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: sensitive body result match +2022-08-21 15:22:20 STATE: test-node-gpu.js passed: sensitive hand result match +2022-08-21 15:22:20 INFO:  test-node-gpu.js test body +2022-08-21 15:22:20 STATE: test-node-gpu.js start blazepose +2022-08-21 15:22:22 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:22 STATE: test-node-gpu.js event: image +2022-08-21 15:22:22 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:22 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg blazepose +2022-08-21 15:22:22 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.99,"keypoints":39} +2022-08-21 15:22:22 DATA:  test-node-gpu.js result: performance: load: null total: 221 +2022-08-21 15:22:22 STATE: test-node-gpu.js passed: blazepose +2022-08-21 15:22:22 STATE: test-node-gpu.js start efficientpose +2022-08-21 15:22:22 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:22 STATE: test-node-gpu.js event: image +2022-08-21 15:22:23 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:23 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg efficientpose +2022-08-21 15:22:23 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.75,"keypoints":13} +2022-08-21 15:22:23 DATA:  test-node-gpu.js result: performance: load: null total: 739 +2022-08-21 15:22:23 STATE: test-node-gpu.js passed: efficientpose +2022-08-21 15:22:23 STATE: test-node-gpu.js start posenet +2022-08-21 15:22:23 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:23 STATE: test-node-gpu.js event: image +2022-08-21 15:22:23 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:23 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg posenet +2022-08-21 15:22:23 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.96,"keypoints":16} +2022-08-21 15:22:23 DATA:  test-node-gpu.js result: performance: load: null total: 137 +2022-08-21 15:22:23 STATE: test-node-gpu.js passed: posenet +2022-08-21 15:22:23 STATE: test-node-gpu.js start movenet +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:24 STATE: test-node-gpu.js event: image +2022-08-21 15:22:24 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg movenet +2022-08-21 15:22:24 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 9 object: 0 person: 1 {"score":1,"age":23.7,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:24 DATA:  test-node-gpu.js result: performance: load: null total: 108 +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: movenet +2022-08-21 15:22:24 INFO:  test-node-gpu.js test face matching +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: face database 40 +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: face match {"first":{"index":4,"similarity":0.7828184453007331}} {"second":{"index":4,"similarity":0.5001334216773398}} {"third":{"index":4,"similarity":0.5403054967489764}} +2022-08-21 15:22:24 INFO:  test-node-gpu.js test face similarity alternative +2022-08-21 15:22:24 STATE: test-node-gpu.js start face embeddings +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:24 STATE: test-node-gpu.js event: image +2022-08-21 15:22:24 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face embeddings +2022-08-21 15:22:24 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:24 DATA:  test-node-gpu.js result: performance: load: null total: 137 +2022-08-21 15:22:24 STATE: test-node-gpu.js passed: mobilefacenet {"embedding":192} +2022-08-21 15:22:24 STATE: test-node-gpu.js start face embeddings +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:25 STATE: test-node-gpu.js event: image +2022-08-21 15:22:25 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face embeddings +2022-08-21 15:22:25 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:25 DATA:  test-node-gpu.js result: performance: load: null total: 163 +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: insightface {"embedding":512} +2022-08-21 15:22:25 INFO:  test-node-gpu.js test face attention +2022-08-21 15:22:25 STATE: test-node-gpu.js start face attention +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:25 STATE: test-node-gpu.js event: image +2022-08-21 15:22:25 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg face attention +2022-08-21 15:22:25 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:25 DATA:  test-node-gpu.js result: performance: load: null total: 224 +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: face attention +2022-08-21 15:22:25 INFO:  test-node-gpu.js test detectors +2022-08-21 15:22:25 STATE: test-node-gpu.js start detectors +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:25 STATE: test-node-gpu.js event: image +2022-08-21 15:22:25 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg detectors +2022-08-21 15:22:25 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:25 DATA:  test-node-gpu.js result: performance: load: null total: 53 +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: detector result face match +2022-08-21 15:22:25 STATE: test-node-gpu.js passed: detector result hand match +2022-08-21 15:22:25 INFO:  test-node-gpu.js test: multi-instance +2022-08-21 15:22:25 STATE: test-node-gpu.js start multi instance +2022-08-21 15:22:25 STATE: test-node-gpu.js event: image +2022-08-21 15:22:26 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: detect: random multi instance +2022-08-21 15:22:26 DATA:  test-node-gpu.js result: face: 0 body: 1 hand: 0 gesture: 0 object: 0 person: 0 {} {} {"score":0,"keypoints":0} +2022-08-21 15:22:26 DATA:  test-node-gpu.js result: performance: load: null total: 50 +2022-08-21 15:22:26 INFO:  test-node-gpu.js test: first instance +2022-08-21 15:22:26 STATE: test-node-gpu.js start multi instance +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg multi instance +2022-08-21 15:22:26 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:26 DATA:  test-node-gpu.js result: performance: load: null total: 48 +2022-08-21 15:22:26 INFO:  test-node-gpu.js test: second instance +2022-08-21 15:22:26 STATE: test-node-gpu.js start multi instance +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg multi instance +2022-08-21 15:22:26 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:26 DATA:  test-node-gpu.js result: performance: load: null total: 47 +2022-08-21 15:22:26 INFO:  test-node-gpu.js test: concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js start concurrent +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:26 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151289056} +2022-08-21 15:22:27 STATE: test-node-gpu.js event: image +2022-08-21 15:22:27 STATE: test-node-gpu.js event: image +2022-08-21 15:22:27 STATE: test-node-gpu.js event: image +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 689 +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 689 +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 689 +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 689 +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 689 +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 689 +2022-08-21 15:22:27 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 420 +2022-08-21 15:22:27 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:27 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 420 +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:27 DATA:  test-node-gpu.js result: performance: load: null total: 420 +2022-08-21 15:22:27 INFO:  test-node-gpu.js test: monkey-patch +2022-08-21 15:22:27 STATE: test-node-gpu.js event: image +2022-08-21 15:22:27 STATE: test-node-gpu.js event: detect +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: monkey patch +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: segmentation [65536] +2022-08-21 15:22:27 STATE: test-node-gpu.js passeed: equal usage +2022-08-21 15:22:27 INFO:  test-node-gpu.js test: input compare +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34696120} +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1004796928} +2022-08-21 15:22:27 STATE: test-node-gpu.js passed: image compare 0 23.275441687091504 +2022-08-21 15:22:27 INFO:  test-node-gpu.js events: {"image":29,"detect":29,"warmup":2} +2022-08-21 15:22:27 INFO:  test-node-gpu.js tensors 4105 +2022-08-21 15:22:27 INFO:  test-node-gpu.js test complete: 17207 ms +2022-08-21 15:22:28 INFO:  +2022-08-21 15:22:28 INFO:  test-node-wasm.js start +2022-08-21 15:22:30 DATA:  test-node-wasm.js stdout: 2022-08-21 15:22:30 INFO:  { supported: true, backend: true, simd: true, multithread: false } +2022-08-21 15:22:30 STATE: test-node-wasm.js passed: model server: https://vladmandic.github.io/human/models/ +2022-08-21 15:22:30 INFO:  test-node-wasm.js test: configuration validation +2022-08-21 15:22:30 STATE: test-node-wasm.js passed: configuration default validation [] +2022-08-21 15:22:30 STATE: test-node-wasm.js passed: configuration invalid validation [{"reason":"unknown property","where":"config.invalid = true"}] +2022-08-21 15:22:30 INFO:  test-node-wasm.js test: model load +2022-08-21 15:22:32 STATE: test-node-wasm.js passed: models loaded 23 12 [{"name":"ssrnetage","loaded":false,"url":null},{"name":"gear","loaded":false,"url":null},{"name":"blazeposedetect","loaded":false,"url":null},{"name":"blazepose","loaded":false,"url":null},{"name":"centernet","loaded":true,"url":"https://vladmandic.github.io/human/models/mb3-centernet.json"},{"name":"efficientpose","loaded":false,"url":null},{"name":"mobilefacenet","loaded":false,"url":null},{"name":"insightface","loaded":false,"url":null},{"name":"emotion","loaded":true,"url":"https://vladmandic.github.io/human/models/emotion.json"},{"name":"facedetect","loaded":true,"url":"https://vladmandic.github.io/human/models/blazeface.json"},{"name":"faceiris","loaded":true,"url":"https://vladmandic.github.io/human/models/iris.json"},{"name":"facemesh","loaded":true,"url":"https://vladmandic.github.io/human/models/facemesh.json"},{"name":"faceres","loaded":true,"url":"https://vladmandic.github.io/human/models/faceres.json"},{"name":"ssrnetgender","loaded":false,"url":null},{"name":"handpose","loaded":false,"url":null},{"name":"handskeleton","loaded":true,"url":"https://vladmandic.github.io/human/models/handlandmark-full.json"},{"name":"handtrack","loaded":true,"url":"https://vladmandic.github.io/human/models/handtrack.json"},{"name":"liveness","loaded":true,"url":"https://vladmandic.github.io/human/models/liveness.json"},{"name":"movenet","loaded":true,"url":"https://vladmandic.github.io/human/models/movenet-lightning.json"},{"name":"nanodet","loaded":false,"url":null},{"name":"posenet","loaded":false,"url":null},{"name":"segmentation","loaded":true,"url":"https://vladmandic.github.io/human/models/selfie.json"},{"name":"antispoof","loaded":true,"url":"https://vladmandic.github.io/human/models/antispoof.json"}] +2022-08-21 15:22:32 INFO:  test-node-wasm.js test: warmup +2022-08-21 15:22:32 STATE: test-node-wasm.js passed: create human +2022-08-21 15:22:32 INFO:  test-node-wasm.js human version: 2.9.4 +2022-08-21 15:22:32 INFO:  test-node-wasm.js platform: linux x64 agent: NodeJS v18.1.0 +2022-08-21 15:22:32 INFO:  test-node-wasm.js tfjs version: 3.19.0 +2022-08-21 15:22:32 INFO:  test-node-wasm.js env: {"browser":false,"node":true,"platform":"linux x64","agent":"NodeJS v18.1.0","backends":["cpu","wasm"],"initial":false,"tfjs":{"version":"3.19.0"},"offscreen":false,"perfadd":false,"tensorflow":{},"wasm":{"supported":true,"backend":true,"simd":true,"multithread":false},"webgl":{"supported":false,"backend":false},"webgpu":{"supported":false,"backend":false},"cpu":{"flags":[]},"kernels":126} +2022-08-21 15:22:32 STATE: test-node-wasm.js passed: set backend: wasm +2022-08-21 15:22:32 STATE: test-node-wasm.js tensors 1921 +2022-08-21 15:22:32 STATE: test-node-wasm.js passed: load models +2022-08-21 15:22:32 STATE: test-node-wasm.js result: defined models: 23 loaded models: 12 +2022-08-21 15:22:32 STATE: test-node-wasm.js passed: warmup: none default +2022-08-21 15:22:32 DATA:  test-node-wasm.js result: face: 0 body: 0 hand: 0 gesture: 0 object: 0 person: 0 {} {} {} +2022-08-21 15:22:32 DATA:  test-node-wasm.js result: performance: load: null total: null +2022-08-21 15:22:32 STATE: test-node-wasm.js passed: warmup none result match +2022-08-21 15:22:32 STATE: test-node-wasm.js event: image +2022-08-21 15:22:33 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:33 STATE: test-node-wasm.js event: warmup +2022-08-21 15:22:33 STATE: test-node-wasm.js passed: warmup: face default +2022-08-21 15:22:33 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} +2022-08-21 15:22:33 DATA:  test-node-wasm.js result: performance: load: null total: 500 +2022-08-21 15:22:33 STATE: test-node-wasm.js passed: warmup face result match +2022-08-21 15:22:33 STATE: test-node-wasm.js event: image +2022-08-21 15:22:33 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:33 STATE: test-node-wasm.js event: warmup +2022-08-21 15:22:33 STATE: test-node-wasm.js passed: warmup: body default +2022-08-21 15:22:33 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:33 DATA:  test-node-wasm.js result: performance: load: null total: 352 +2022-08-21 15:22:33 STATE: test-node-wasm.js passed: warmup body result match +2022-08-21 15:22:33 STATE: test-node-wasm.js details: {"face":{"boxScore":0.93,"faceScore":1,"age":23.7,"gender":"female","genderScore":0.97},"emotion":[{"score":0.59,"emotion":"angry"},{"score":0.29,"emotion":"fear"}],"body":{"score":0.92,"keypoints":17},"hand":{"boxScore":0.51,"fingerScore":0.73,"keypoints":21},"gestures":[{"face":0,"gesture":"facing right"},{"face":0,"gesture":"mouth 21% open"},{"hand":0,"gesture":"pinky forward"},{"hand":0,"gesture":"palm up"},{"hand":0,"gesture":"open palm"},{"iris":0,"gesture":"looking left"},{"iris":0,"gesture":"looking up"}]} +2022-08-21 15:22:33 INFO:  test-node-wasm.js test: details verification +2022-08-21 15:22:33 STATE: test-node-wasm.js start default +2022-08-21 15:22:33 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:33 STATE: test-node-wasm.js event: image +2022-08-21 15:22:34 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg default +2022-08-21 15:22:34 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 7 object: 1 person: 1 {"score":1,"age":23.7,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:34 DATA:  test-node-wasm.js result: performance: load: null total: 332 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face length 1 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face score 1 0.93 1 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face age/gender 23.7 female 0.97 85.47 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face arrays 4 478 1024 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face emotion 2 {"score":0.59,"emotion":"angry"} +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face anti-spoofing 0.79 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details face liveness 0.83 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details body length 1 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details body 0.92 17 6 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details hand length 1 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details hand 0.51 0.73 point +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details hand arrays 21 5 7 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details gesture length 7 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details gesture first {"face":0,"gesture":"facing right"} +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details object length 1 +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: details object 0.72 person +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1413675264} +2022-08-21 15:22:34 STATE: test-node-wasm.js event: image +2022-08-21 15:22:34 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:34 STATE: test-node-wasm.js passed: tensor shape: [1,1200,1200,4] dtype: float32 +2022-08-21 15:22:35 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1200,1200,4] {"checksum":1413675264} +2022-08-21 15:22:35 STATE: test-node-wasm.js event: image +2022-08-21 15:22:35 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:35 STATE: test-node-wasm.js passed: tensor shape: [1200,1200,4] dtype: float32 +2022-08-21 15:22:35 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:35 STATE: test-node-wasm.js event: image +2022-08-21 15:22:35 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:35 STATE: test-node-wasm.js passed: tensor shape: [1,1200,1200,3] dtype: float32 +2022-08-21 15:22:36 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:36 STATE: test-node-wasm.js event: image +2022-08-21 15:22:36 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:36 STATE: test-node-wasm.js passed: tensor shape: [1200,1200,3] dtype: float32 +2022-08-21 15:22:36 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,4] {"checksum":1371996871} +2022-08-21 15:22:36 STATE: test-node-wasm.js event: image +2022-08-21 15:22:37 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:37 STATE: test-node-wasm.js passed: tensor shape: [1,1200,1200,4] dtype: int32 +2022-08-21 15:22:37 INFO:  test-node-wasm.js test default +2022-08-21 15:22:37 STATE: test-node-wasm.js start async +2022-08-21 15:22:37 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:37 STATE: test-node-wasm.js event: image +2022-08-21 15:22:37 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:37 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg async +2022-08-21 15:22:37 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:37 DATA:  test-node-wasm.js result: performance: load: null total: 307 +2022-08-21 15:22:37 STATE: test-node-wasm.js passed: default result face match 1 female 0.97 +2022-08-21 15:22:37 INFO:  test-node-wasm.js test sync +2022-08-21 15:22:37 STATE: test-node-wasm.js start sync +2022-08-21 15:22:37 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:37 STATE: test-node-wasm.js event: image +2022-08-21 15:22:38 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg sync +2022-08-21 15:22:38 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:38 DATA:  test-node-wasm.js result: performance: load: null total: 308 +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: default sync 1 female 0.97 +2022-08-21 15:22:38 INFO:  test-node-wasm.js test: image process +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: image input null [1,256,256,3] +2022-08-21 15:22:38 INFO:  test-node-wasm.js test: image null +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: invalid input could not convert input to tensor +2022-08-21 15:22:38 INFO:  test-node-wasm.js test face similarity +2022-08-21 15:22:38 STATE: test-node-wasm.js start face similarity +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:38 STATE: test-node-wasm.js event: image +2022-08-21 15:22:38 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face similarity +2022-08-21 15:22:38 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 6 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.82,"class":"person"} {"score":0.47,"keypoints":3} +2022-08-21 15:22:38 DATA:  test-node-wasm.js result: performance: load: null total: 288 +2022-08-21 15:22:38 STATE: test-node-wasm.js start face similarity +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:38 STATE: test-node-wasm.js event: image +2022-08-21 15:22:38 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:38 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg face similarity +2022-08-21 15:22:38 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:38 DATA:  test-node-wasm.js result: performance: load: null total: 312 +2022-08-21 15:22:38 STATE: test-node-wasm.js start face similarity +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} +2022-08-21 15:22:39 STATE: test-node-wasm.js event: image +2022-08-21 15:22:39 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg face similarity +2022-08-21 15:22:39 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 4 object: 1 person: 1 {"score":1,"age":23.5,"gender":"female"} {"score":0.71,"class":"person"} {"score":0.75,"keypoints":7} +2022-08-21 15:22:39 DATA:  test-node-wasm.js result: performance: load: null total: 281 +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: face descriptor +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: face similarity {"similarity":[1,0.5266119940661309,0.4858842904087851],"descriptors":[1024,1024,1024]} +2022-08-21 15:22:39 INFO:  test-node-wasm.js test object +2022-08-21 15:22:39 STATE: test-node-wasm.js start object +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:39 STATE: test-node-wasm.js event: image +2022-08-21 15:22:39 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg object +2022-08-21 15:22:39 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 1 person: 1 {"score":1,"age":29.6,"gender":"female"} {"score":0.72,"class":"person"} {"score":0.92,"keypoints":17} +2022-08-21 15:22:39 DATA:  test-node-wasm.js result: performance: load: null total: 301 +2022-08-21 15:22:39 STATE: test-node-wasm.js passed: centernet +2022-08-21 15:22:39 STATE: test-node-wasm.js start object +2022-08-21 15:22:40 WARN:  test-node-wasm.js missing kernel ops {"title":"object","model":"nanodet","url":"https://vladmandic.github.io/human-models/models/nanodet.json","missing":["sparsetodense"],"backkend":"wasm"} +2022-08-21 15:22:40 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:40 STATE: test-node-wasm.js event: image +2022-08-21 15:22:41 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg object +2022-08-21 15:22:41 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 8 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:41 DATA:  test-node-wasm.js result: performance: load: null total: 205 +2022-08-21 15:22:41 ERROR: test-node-wasm.js failed: nanodet [] +2022-08-21 15:22:41 INFO:  test-node-wasm.js test sensitive +2022-08-21 15:22:41 STATE: test-node-wasm.js start sensitive +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:41 STATE: test-node-wasm.js event: image +2022-08-21 15:22:41 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg sensitive +2022-08-21 15:22:41 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:41 DATA:  test-node-wasm.js result: performance: load: null total: 230 +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: sensitive result match +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: sensitive face result match +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: sensitive face emotion result [{"score":0.46,"emotion":"neutral"},{"score":0.24,"emotion":"fear"},{"score":0.17,"emotion":"sad"}] +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: sensitive body result match +2022-08-21 15:22:41 STATE: test-node-wasm.js passed: sensitive hand result match +2022-08-21 15:22:41 INFO:  test-node-wasm.js test body +2022-08-21 15:22:41 STATE: test-node-wasm.js start blazepose +2022-08-21 15:22:43 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:43 STATE: test-node-wasm.js event: image +2022-08-21 15:22:43 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:43 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg blazepose +2022-08-21 15:22:43 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.99,"keypoints":39} +2022-08-21 15:22:43 DATA:  test-node-wasm.js result: performance: load: null total: 400 +2022-08-21 15:22:43 STATE: test-node-wasm.js passed: blazepose +2022-08-21 15:22:43 STATE: test-node-wasm.js start efficientpose +2022-08-21 15:22:44 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:44 STATE: test-node-wasm.js event: image +2022-08-21 15:22:44 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:44 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg efficientpose +2022-08-21 15:22:44 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.75,"keypoints":13} +2022-08-21 15:22:44 DATA:  test-node-wasm.js result: performance: load: null total: 620 +2022-08-21 15:22:44 STATE: test-node-wasm.js passed: efficientpose +2022-08-21 15:22:44 STATE: test-node-wasm.js start posenet +2022-08-21 15:22:45 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:45 STATE: test-node-wasm.js event: image +2022-08-21 15:22:45 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:45 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg posenet +2022-08-21 15:22:45 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.96,"keypoints":16} +2022-08-21 15:22:45 DATA:  test-node-wasm.js result: performance: load: null total: 278 +2022-08-21 15:22:45 STATE: test-node-wasm.js passed: posenet +2022-08-21 15:22:45 STATE: test-node-wasm.js start movenet +2022-08-21 15:22:45 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:45 STATE: test-node-wasm.js event: image +2022-08-21 15:22:46 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg movenet +2022-08-21 15:22:46 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 10 object: 0 person: 1 {"score":1,"age":29.6,"gender":"female"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:46 DATA:  test-node-wasm.js result: performance: load: null total: 239 +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: movenet +2022-08-21 15:22:46 INFO:  test-node-wasm.js test face matching +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: face database 40 +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: face match {"first":{"index":4,"similarity":0.7827852754786533}} {"second":{"index":4,"similarity":0.5660821189104794}} {"third":{"index":4,"similarity":0.45074189882665594}} +2022-08-21 15:22:46 INFO:  test-node-wasm.js test face similarity alternative +2022-08-21 15:22:46 STATE: test-node-wasm.js start face embeddings +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:46 STATE: test-node-wasm.js event: image +2022-08-21 15:22:46 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face embeddings +2022-08-21 15:22:46 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:46 DATA:  test-node-wasm.js result: performance: load: null total: 229 +2022-08-21 15:22:46 STATE: test-node-wasm.js passed: mobilefacenet {"embedding":192} +2022-08-21 15:22:46 STATE: test-node-wasm.js start face embeddings +2022-08-21 15:22:47 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:47 STATE: test-node-wasm.js event: image +2022-08-21 15:22:47 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:47 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face embeddings +2022-08-21 15:22:47 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 2 gesture: 8 object: 0 person: 1 {"score":1,"age":23.5,"gender":"female"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:47 DATA:  test-node-wasm.js result: performance: load: null total: 279 +2022-08-21 15:22:47 STATE: test-node-wasm.js passed: insightface {"embedding":512} +2022-08-21 15:22:47 INFO:  test-node-wasm.js test face attention +2022-08-21 15:22:47 STATE: test-node-wasm.js start face attention +2022-08-21 15:22:47 WARN:  test-node-wasm.js missing kernel ops {"title":"face attention","model":"facemesh","url":"https://vladmandic.github.io/human-models/models/facemesh-attention.json","missing":["atan2"],"backkend":"wasm"} +2022-08-21 15:22:47 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:47 STATE: test-node-wasm.js event: image +2022-08-21 15:22:47 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:47 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg face attention +2022-08-21 15:22:47 DATA:  test-node-wasm.js result: face: 0 body: 1 hand: 1 gesture: 2 object: 0 person: 0 {} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:47 DATA:  test-node-wasm.js result: performance: load: null total: 115 +2022-08-21 15:22:47 ERROR: test-node-wasm.js failed: face attention {"annotations":0} +2022-08-21 15:22:47 INFO:  test-node-wasm.js test detectors +2022-08-21 15:22:47 STATE: test-node-wasm.js start detectors +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:48 STATE: test-node-wasm.js event: image +2022-08-21 15:22:48 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg detectors +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: performance: load: null total: 116 +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: detector result face match +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: detector result hand match +2022-08-21 15:22:48 INFO:  test-node-wasm.js test: multi-instance +2022-08-21 15:22:48 STATE: test-node-wasm.js start multi instance +2022-08-21 15:22:48 STATE: test-node-wasm.js event: image +2022-08-21 15:22:48 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: detect: random multi instance +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: face: 0 body: 1 hand: 0 gesture: 0 object: 0 person: 0 {} {} {"score":0,"keypoints":0} +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: performance: load: null total: 102 +2022-08-21 15:22:48 INFO:  test-node-wasm.js test: first instance +2022-08-21 15:22:48 STATE: test-node-wasm.js start multi instance +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg multi instance +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: performance: load: null total: 107 +2022-08-21 15:22:48 INFO:  test-node-wasm.js test: second instance +2022-08-21 15:22:48 STATE: test-node-wasm.js start multi instance +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg multi instance +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:48 DATA:  test-node-wasm.js result: performance: load: null total: 107 +2022-08-21 15:22:48 INFO:  test-node-wasm.js test: concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js start concurrent +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:48 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:49 STATE: test-node-wasm.js passed: load image: samples/in/ai-upper.jpg [1,720,688,3] {"checksum":151155104} +2022-08-21 15:22:49 STATE: test-node-wasm.js event: image +2022-08-21 15:22:49 STATE: test-node-wasm.js event: image +2022-08-21 15:22:49 STATE: test-node-wasm.js event: image +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 1243 +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 1243 +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 1244 +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 1244 +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 1244 +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 1244 +2022-08-21 15:22:50 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-upper.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 0 object: 0 person: 1 {"score":0.96,"gender":"unknown"} {} {"score":0.75,"keypoints":7} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 940 +2022-08-21 15:22:50 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:50 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-face.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.91,"gender":"unknown"} {} {"score":0.47,"keypoints":3} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 940 +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: detect: samples/in/ai-body.jpg concurrent +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 1 gesture: 0 object: 0 person: 1 {"score":0.93,"gender":"unknown"} {} {"score":0.92,"keypoints":17} +2022-08-21 15:22:50 DATA:  test-node-wasm.js result: performance: load: null total: 940 +2022-08-21 15:22:50 INFO:  test-node-wasm.js test: monkey-patch +2022-08-21 15:22:50 STATE: test-node-wasm.js event: image +2022-08-21 15:22:50 STATE: test-node-wasm.js event: detect +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: monkey patch +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: segmentation [65536] +2022-08-21 15:22:50 STATE: test-node-wasm.js passeed: equal usage +2022-08-21 15:22:50 INFO:  test-node-wasm.js test: input compare +2022-08-21 15:22:50 STATE: test-node-wasm.js passed: load image: samples/in/ai-face.jpg [1,256,256,3] {"checksum":34697856} +2022-08-21 15:22:51 STATE: test-node-wasm.js passed: load image: samples/in/ai-body.jpg [1,1200,1200,3] {"checksum":1038921856} +2022-08-21 15:22:51 STATE: test-node-wasm.js passed: image compare 0 23.280073018790848 +2022-08-21 15:22:51 INFO:  test-node-wasm.js events: {"image":29,"detect":29,"warmup":2} +2022-08-21 15:22:51 INFO:  test-node-wasm.js tensors 4107 +2022-08-21 15:22:51 INFO:  test-node-wasm.js test complete: 20492 ms +2022-08-21 15:22:51 STATE: all tests complete +2022-08-21 15:22:51 INFO:  status {"test":"../demo/nodejs/node.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/nodejs/node-simple.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/nodejs/node-fetch.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/nodejs/node-event.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/nodejs/node-similarity.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/nodejs/node-canvas.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/multithread/node-multiprocess.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"../demo/facematch/node-match.js","passed":1,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"test-node.js","passed":125,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"test-node-gpu.js","passed":125,"failed":0} +2022-08-21 15:22:51 INFO:  status {"test":"test-node-wasm.js","passed":124,"failed":2} +2022-08-21 15:22:51 INFO:  failures {"count":2} +2022-08-21 15:22:51 WARN:  failed {"test":"test-node-wasm.js","message":["error",["failed: nanodet",[]]]} +2022-08-21 15:22:51 WARN:  failed {"test":"test-node-wasm.js","message":["error",["failed: face attention",{"annotations":0}]]}