diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b417b0..239f96fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # @vladmandic/human -Version: **1.5.1** +Version: **1.5.2** Description: **Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gesture Recognition** Author: **Vladimir Mandic ** @@ -9,8 +9,9 @@ Repository: **** ## Changelog -### **HEAD -> main** 2021/04/13 mandic00@live.com +### **1.5.2** 2021/04/14 mandic00@live.com +- experimental node-wasm support ### **1.5.1** 2021/04/13 mandic00@live.com diff --git a/TODO.md b/TODO.md index e6c18058..caaf2161 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,7 @@ ## Big Ticket Items -- Improve automated testing framework +- N/A ## Explore Models diff --git a/dist/human.esm-nobundle.js b/dist/human.esm-nobundle.js index 01d4827c..aff9e4e8 100644 --- a/dist/human.esm-nobundle.js +++ b/dist/human.esm-nobundle.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var u0="1.5.1";var fe,Pe,Me,he,rt,ve,ct,At,_t,dn=class{constructor(t={}){fe.set(this,void 0);Pe.set(this,void 0);Me.set(this,void 0);he.set(this,void 0);this.analyze=(...t)=>{if(!C(this,Pe))return;let n=this.tf.engine().state.numTensors,A=C(this,fe);Ae(this,fe,n);let _=n-A;_!==0&&f(...t,_)};rt.set(this,t=>{if(!C(this,Me))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof o.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});ve.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=z();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&f("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&f("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&f(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&f("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&T1();try{await this.tf.setBackend(this.config.backend)}catch(_){f("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(f("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&f(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(z()-A)}});ct.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(tt);break;case"full":n=await t(nt);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});At.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+tt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+nt;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let s=await this.detect(c,this.config);t(s)},n?_.src=n:t(null)}));_t.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(tt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(nt)),!n)return null;let A;if(typeof o.node!="undefined"){let _=o.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&f("Warmup tfjs-node not loaded");return A});this.tf=o,this.draw=a1,this.version=u0,this.config=U(j,t),this.state="idle",Ae(this,fe,0),Ae(this,Pe,!1),Ae(this,Me,!1),Ae(this,he,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>i1(n,this.config),this.classes={facemesh:St,age:st,gender:it,emotion:lt,faceres:bt,body:this.config.body.modelPath.includes("posenet")?qt:e1,hand:Dt,nanodet:A1},this.faceTriangulation=O1,this.faceUVMap=I1,this.sysinfo=f1()}profileData(){return this.config.profile?Ee:{}}similarity(t,n){return this.config.face.description.enabled?Tt(t,n):this.config.face.embedding.enabled?P1(t,n):0}enhance(t){return Pt(t)}match(t,n,A=0){return M1(t,n,A)}async load(t={}){this.state="load";let n=z();t&&(this.config=U(this.config,t)),C(this,he)&&(this.config.debug&&f(`version: ${this.version}`),this.config.debug&&f(`tfjs version: ${this.tf.version_core}`),this.config.debug&&f("platform:",this.sysinfo.platform),this.config.debug&&f("agent:",this.sysinfo.agent),await C(this,ve).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&f("configuration:",this.config),this.config.debug&&f("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?kt(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?ht(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?wt(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?mt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?pt(this.config):null),this.models.handpose||(this.config.hand.enabled?$t(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?Ut(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?t1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?r1(this.config):null),this.models.nanodet||(this.config.object.enabled?o1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?gt(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await kt(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await ht(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await wt(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await mt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await pt(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await $t(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await Ut(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await t1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await r1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await o1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await gt(this.config))),C(this,he)&&(this.config.debug&&f("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),Ae(this,he,!1));let A=Math.trunc(z()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var p,u,M,E;this.state="config";let _;this.config=U(this.config,n),this.state="check";let c=C(this,rt).call(this,t);c&&(f(c,t),A({error:c}));let r=z();await C(this,ve).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let s;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&h1 instanceof ImageBitmap||t instanceof o.Tensor)&&(f("disabling video optimization"),s=this.config.videoOptimized,this.config.videoOptimized=!1),_=z();let h=i1(t,this.config);if(!h||!h.tensor){f("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(z()-_),this.analyze("Get Image:");let a,x,i,w,m;this.config.async?(i=this.config.face.enabled?Mt(this,h.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=z(),i=this.config.face.enabled?await Mt(this,h.tensor):[],m=Math.trunc(z()-_),m>0&&(this.perf.face=m)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?a=this.config.body.enabled?(p=this.models.posenet)==null?void 0:p.estimatePoses(h.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?a=this.config.body.enabled?n1(h.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(a=this.config.body.enabled?c1(h.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=z(),this.config.body.modelPath.includes("posenet")?a=this.config.body.enabled?await((u=this.models.posenet)==null?void 0:u.estimatePoses(h.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?a=this.config.body.enabled?await n1(h.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(a=this.config.body.enabled?await c1(h.tensor,this.config):[]),m=Math.trunc(z()-_),m>0&&(this.perf.body=m)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(x=this.config.hand.enabled?(M=this.models.handpose)==null?void 0:M.estimateHands(h.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=z(),x=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(h.tensor,this.config)):[],m=Math.trunc(z()-_),m>0&&(this.perf.hand=m)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(w=this.config.object.enabled?s1(h.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=z(),w=this.config.object.enabled?await s1(h.tensor,this.config):[],m=Math.trunc(z()-_),m>0&&(this.perf.object=m)),this.analyze("End Object:"),this.config.async&&([i,a,x,w]=await Promise.all([i,a,x,w])),o.dispose(h.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let b=[];this.config.gesture.enabled&&(_=z(),b=[...a0(i),...i0(a),...y0(x),...x0(i)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(z()-_)),s&&(this.config.videoOptimized=s),this.perf.total=Math.trunc(z()-r),this.state="idle";let y={face:i,body:a,hand:x,gesture:b,object:w,performance:this.perf,canvas:h.canvas};A(y)})}async warmup(t={}){let n=z();if(t&&(this.config=U(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await C(this,ct).call(this):typeof Image!="undefined"?_=await C(this,At).call(this):_=await C(this,_t).call(this),this.config.videoOptimized=A;let c=z();return this.config.debug&&f("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};fe=new WeakMap,Pe=new WeakMap,Me=new WeakMap,he=new WeakMap,rt=new WeakMap,ve=new WeakMap,ct=new WeakMap,At=new WeakMap,_t=new WeakMap;export{dn as Human,dn as default}; +2Q==`;var u0="1.5.2";var fe,Pe,Me,he,rt,ve,ct,At,_t,dn=class{constructor(t={}){fe.set(this,void 0);Pe.set(this,void 0);Me.set(this,void 0);he.set(this,void 0);this.analyze=(...t)=>{if(!C(this,Pe))return;let n=this.tf.engine().state.numTensors,A=C(this,fe);Ae(this,fe,n);let _=n-A;_!==0&&f(...t,_)};rt.set(this,t=>{if(!C(this,Me))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof o.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});ve.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=z();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&f("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&f("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&f(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&f("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&T1();try{await this.tf.setBackend(this.config.backend)}catch(_){f("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(f("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&f(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(z()-A)}});ct.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(tt);break;case"full":n=await t(nt);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});At.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+tt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+nt;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let s=await this.detect(c,this.config);t(s)},n?_.src=n:t(null)}));_t.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(tt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(nt)),!n)return null;let A;if(typeof o.node!="undefined"){let _=o.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&f("Warmup tfjs-node not loaded");return A});this.tf=o,this.draw=a1,this.version=u0,this.config=U(j,t),this.state="idle",Ae(this,fe,0),Ae(this,Pe,!1),Ae(this,Me,!1),Ae(this,he,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>i1(n,this.config),this.classes={facemesh:St,age:st,gender:it,emotion:lt,faceres:bt,body:this.config.body.modelPath.includes("posenet")?qt:e1,hand:Dt,nanodet:A1},this.faceTriangulation=O1,this.faceUVMap=I1,this.sysinfo=f1()}profileData(){return this.config.profile?Ee:{}}similarity(t,n){return this.config.face.description.enabled?Tt(t,n):this.config.face.embedding.enabled?P1(t,n):0}enhance(t){return Pt(t)}match(t,n,A=0){return M1(t,n,A)}async load(t={}){this.state="load";let n=z();t&&(this.config=U(this.config,t)),C(this,he)&&(this.config.debug&&f(`version: ${this.version}`),this.config.debug&&f(`tfjs version: ${this.tf.version_core}`),this.config.debug&&f("platform:",this.sysinfo.platform),this.config.debug&&f("agent:",this.sysinfo.agent),await C(this,ve).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&f("configuration:",this.config),this.config.debug&&f("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?kt(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?ht(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?wt(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?mt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?pt(this.config):null),this.models.handpose||(this.config.hand.enabled?$t(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?Ut(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?t1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?r1(this.config):null),this.models.nanodet||(this.config.object.enabled?o1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?gt(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await kt(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await ht(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await wt(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await mt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await pt(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await $t(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await Ut(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await t1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await r1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await o1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await gt(this.config))),C(this,he)&&(this.config.debug&&f("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),Ae(this,he,!1));let A=Math.trunc(z()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var p,u,M,E;this.state="config";let _;this.config=U(this.config,n),this.state="check";let c=C(this,rt).call(this,t);c&&(f(c,t),A({error:c}));let r=z();await C(this,ve).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let s;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&h1 instanceof ImageBitmap||t instanceof o.Tensor)&&(f("disabling video optimization"),s=this.config.videoOptimized,this.config.videoOptimized=!1),_=z();let h=i1(t,this.config);if(!h||!h.tensor){f("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(z()-_),this.analyze("Get Image:");let a,x,i,w,m;this.config.async?(i=this.config.face.enabled?Mt(this,h.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=z(),i=this.config.face.enabled?await Mt(this,h.tensor):[],m=Math.trunc(z()-_),m>0&&(this.perf.face=m)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?a=this.config.body.enabled?(p=this.models.posenet)==null?void 0:p.estimatePoses(h.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?a=this.config.body.enabled?n1(h.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(a=this.config.body.enabled?c1(h.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=z(),this.config.body.modelPath.includes("posenet")?a=this.config.body.enabled?await((u=this.models.posenet)==null?void 0:u.estimatePoses(h.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?a=this.config.body.enabled?await n1(h.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(a=this.config.body.enabled?await c1(h.tensor,this.config):[]),m=Math.trunc(z()-_),m>0&&(this.perf.body=m)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(x=this.config.hand.enabled?(M=this.models.handpose)==null?void 0:M.estimateHands(h.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=z(),x=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(h.tensor,this.config)):[],m=Math.trunc(z()-_),m>0&&(this.perf.hand=m)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(w=this.config.object.enabled?s1(h.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=z(),w=this.config.object.enabled?await s1(h.tensor,this.config):[],m=Math.trunc(z()-_),m>0&&(this.perf.object=m)),this.analyze("End Object:"),this.config.async&&([i,a,x,w]=await Promise.all([i,a,x,w])),o.dispose(h.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let b=[];this.config.gesture.enabled&&(_=z(),b=[...a0(i),...i0(a),...y0(x),...x0(i)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(z()-_)),s&&(this.config.videoOptimized=s),this.perf.total=Math.trunc(z()-r),this.state="idle";let y={face:i,body:a,hand:x,gesture:b,object:w,performance:this.perf,canvas:h.canvas};A(y)})}async warmup(t={}){let n=z();if(t&&(this.config=U(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await C(this,ct).call(this):typeof Image!="undefined"?_=await C(this,At).call(this):_=await C(this,_t).call(this),this.config.videoOptimized=A;let c=z();return this.config.debug&&f("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};fe=new WeakMap,Pe=new WeakMap,Me=new WeakMap,he=new WeakMap,rt=new WeakMap,ve=new WeakMap,ct=new WeakMap,At=new WeakMap,_t=new WeakMap;export{dn as Human,dn as default}; //# sourceMappingURL=human.esm-nobundle.js.map diff --git a/dist/human.esm.js b/dist/human.esm.js index ca70e4d1..5ab25698 100644 --- a/dist/human.esm.js +++ b/dist/human.esm.js @@ -4908,7 +4908,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var wk="1.5.1";var iu,sh,ih,Ui,q0,oh,X0,K0,Z0,aoe=class{constructor(t={}){iu.set(this,void 0);sh.set(this,void 0);ih.set(this,void 0);Ui.set(this,void 0);this.analyze=(...t)=>{if(!ur(this,sh))return;let n=this.tf.engine().state.numTensors,r=ur(this,iu);us(this,iu,n);let a=n-r;a!==0&&le(...t,a)};q0.set(this,t=>{if(!ur(this,ih))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof ze))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});oh.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let r=Ye();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&le("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&le("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let a=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&le(`wasm execution: ${a?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!a&&le("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&v8();try{await this.tf.setBackend(this.config.backend)}catch(a){le("error: cannot set backend:",this.config.backend,a)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(le("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let a=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&le(`gl version:${a.getParameter(a.VERSION)} renderer:${a.getParameter(a.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(Ye()-r)}});X0.set(this,async()=>{let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(H0);break;case"full":n=await t(G0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r});K0.set(this,async()=>new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+H0;break;case"full":case"body":r=1200,n="data:image/jpeg;base64,"+G0;break;default:n=null}let a=new Image;a.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=a.naturalWidth,s.height=a.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=await this.detect(s,this.config);t(o)},n?a.src=n:t(null)}));Z0.set(this,async()=>{let t=a=>Buffer.from(a,"base64"),n;if(this.config.warmup==="face"&&(n=t(H0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(G0)),!n)return null;let r;if(typeof void 0!="undefined"){let a=(void 0).decodeJpeg(n),s=a.expandDims(0);this.tf.dispose(a),r=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&le("Warmup tfjs-node not loaded");return r});this.tf=gu,this.draw=Xg,this.version=wk,this.config=Jn(ht,t),this.state="idle",us(this,iu,0),us(this,sh,!1),us(this,ih,!1),us(this,Ui,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>qg(n,this.config),this.classes={facemesh:fg,age:H2,gender:q2,emotion:J2,faceres:ag,body:this.config.body.modelPath.includes("posenet")?Sg:zg,hand:Fg,nanodet:Vg},this.faceTriangulation=D8,this.faceUVMap=O8,this.sysinfo=u5()}profileData(){return this.config.profile?g0:{}}similarity(t,n){return this.config.face.description.enabled?ig(t,n):this.config.face.embedding.enabled?k8(t,n):0}enhance(t){return og(t)}match(t,n,r=0){return I8(t,n,r)}async load(t={}){this.state="load";let n=Ye();t&&(this.config=Jn(this.config,t)),ur(this,Ui)&&(this.config.debug&&le(`version: ${this.version}`),this.config.debug&&le(`tfjs version: ${this.tf.version_core}`),this.config.debug&&le("platform:",this.sysinfo.platform),this.config.debug&&le("agent:",this.sysinfo.agent),await ur(this,oh).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&le("configuration:",this.config),this.config.debug&&le("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?yg(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?G2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Y2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?tg(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?ng(this.config):null),this.models.handpose||(this.config.hand.enabled?Og(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?Tg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?Pg(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?Wg(this.config):null),this.models.nanodet||(this.config.object.enabled?Ug(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?sg(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await yg(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await G2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Y2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await tg(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await ng(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await Og(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await Tg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await Pg(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await Wg(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await Ug(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await sg(this.config))),ur(this,Ui)&&(this.config.debug&&le("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),us(this,Ui,!1));let r=Math.trunc(Ye()-n);r>(this.perf.load||0)&&(this.perf.load=r)}async detect(t,n={}){return new Promise(async r=>{var y,A,g,x;this.state="config";let a;this.config=Jn(this.config,n),this.state="check";let s=ur(this,q0).call(this,t);s&&(le(s,t),r({error:s}));let i=Ye();await ur(this,oh).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&Gg instanceof ImageBitmap||t instanceof ze)&&(le("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),a=Ye();let l=qg(t,this.config);if(!l||!l.tensor){le("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(Ye()-a),this.analyze("Get Image:");let c,u,h,d,p;this.config.async?(h=this.config.face.enabled?lg(this,l.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=Ye(),h=this.config.face.enabled?await lg(this,l.tensor):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.face=p)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?(y=this.models.posenet)==null?void 0:y.estimatePoses(l.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?Bg(l.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",a=Ye(),this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?await((A=this.models.posenet)==null?void 0:A.estimatePoses(l.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?await Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?await Bg(l.tensor,this.config):[]),p=Math.trunc(Ye()-a),p>0&&(this.perf.body=p)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(u=this.config.hand.enabled?(g=this.models.handpose)==null?void 0:g.estimateHands(l.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=Ye(),u=this.config.hand.enabled?await((x=this.models.handpose)==null?void 0:x.estimateHands(l.tensor,this.config)):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.hand=p)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(d=this.config.object.enabled?Hg(l.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",a=Ye(),d=this.config.object.enabled?await Hg(l.tensor,this.config):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.object=p)),this.analyze("End Object:"),this.config.async&&([h,c,u,d]=await Promise.all([h,c,u,d])),_e(l.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let f=[];this.config.gesture.enabled&&(a=Ye(),f=[...hk(h),...ck(c),...pk(u),...dk(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(Ye()-a)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(Ye()-i),this.state="idle";let m={face:h,body:c,hand:u,gesture:f,object:d,performance:this.perf,canvas:l.canvas};r(m)})}async warmup(t={}){let n=Ye();if(t&&(this.config=Jn(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await ur(this,X0).call(this):typeof Image!="undefined"?a=await ur(this,K0).call(this):a=await ur(this,Z0).call(this),this.config.videoOptimized=r;let s=Ye();return this.config.debug&&le("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};iu=new WeakMap,sh=new WeakMap,ih=new WeakMap,Ui=new WeakMap,q0=new WeakMap,oh=new WeakMap,X0=new WeakMap,K0=new WeakMap,Z0=new WeakMap;export{aoe as Human,aoe as default}; +2Q==`;var wk="1.5.2";var iu,sh,ih,Ui,q0,oh,X0,K0,Z0,aoe=class{constructor(t={}){iu.set(this,void 0);sh.set(this,void 0);ih.set(this,void 0);Ui.set(this,void 0);this.analyze=(...t)=>{if(!ur(this,sh))return;let n=this.tf.engine().state.numTensors,r=ur(this,iu);us(this,iu,n);let a=n-r;a!==0&&le(...t,a)};q0.set(this,t=>{if(!ur(this,ih))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof ze))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});oh.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let r=Ye();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&le("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&le("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let a=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&le(`wasm execution: ${a?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!a&&le("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&v8();try{await this.tf.setBackend(this.config.backend)}catch(a){le("error: cannot set backend:",this.config.backend,a)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(le("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let a=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&le(`gl version:${a.getParameter(a.VERSION)} renderer:${a.getParameter(a.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(Ye()-r)}});X0.set(this,async()=>{let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(H0);break;case"full":n=await t(G0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r});K0.set(this,async()=>new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+H0;break;case"full":case"body":r=1200,n="data:image/jpeg;base64,"+G0;break;default:n=null}let a=new Image;a.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=a.naturalWidth,s.height=a.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=await this.detect(s,this.config);t(o)},n?a.src=n:t(null)}));Z0.set(this,async()=>{let t=a=>Buffer.from(a,"base64"),n;if(this.config.warmup==="face"&&(n=t(H0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(G0)),!n)return null;let r;if(typeof void 0!="undefined"){let a=(void 0).decodeJpeg(n),s=a.expandDims(0);this.tf.dispose(a),r=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&le("Warmup tfjs-node not loaded");return r});this.tf=gu,this.draw=Xg,this.version=wk,this.config=Jn(ht,t),this.state="idle",us(this,iu,0),us(this,sh,!1),us(this,ih,!1),us(this,Ui,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>qg(n,this.config),this.classes={facemesh:fg,age:H2,gender:q2,emotion:J2,faceres:ag,body:this.config.body.modelPath.includes("posenet")?Sg:zg,hand:Fg,nanodet:Vg},this.faceTriangulation=D8,this.faceUVMap=O8,this.sysinfo=u5()}profileData(){return this.config.profile?g0:{}}similarity(t,n){return this.config.face.description.enabled?ig(t,n):this.config.face.embedding.enabled?k8(t,n):0}enhance(t){return og(t)}match(t,n,r=0){return I8(t,n,r)}async load(t={}){this.state="load";let n=Ye();t&&(this.config=Jn(this.config,t)),ur(this,Ui)&&(this.config.debug&&le(`version: ${this.version}`),this.config.debug&&le(`tfjs version: ${this.tf.version_core}`),this.config.debug&&le("platform:",this.sysinfo.platform),this.config.debug&&le("agent:",this.sysinfo.agent),await ur(this,oh).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&le("configuration:",this.config),this.config.debug&&le("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?yg(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?G2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Y2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?tg(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?ng(this.config):null),this.models.handpose||(this.config.hand.enabled?Og(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?Tg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?Pg(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?Wg(this.config):null),this.models.nanodet||(this.config.object.enabled?Ug(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?sg(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await yg(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await G2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Y2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await tg(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await ng(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await Og(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await Tg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await Pg(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await Wg(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await Ug(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await sg(this.config))),ur(this,Ui)&&(this.config.debug&&le("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),us(this,Ui,!1));let r=Math.trunc(Ye()-n);r>(this.perf.load||0)&&(this.perf.load=r)}async detect(t,n={}){return new Promise(async r=>{var y,A,g,x;this.state="config";let a;this.config=Jn(this.config,n),this.state="check";let s=ur(this,q0).call(this,t);s&&(le(s,t),r({error:s}));let i=Ye();await ur(this,oh).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&Gg instanceof ImageBitmap||t instanceof ze)&&(le("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),a=Ye();let l=qg(t,this.config);if(!l||!l.tensor){le("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(Ye()-a),this.analyze("Get Image:");let c,u,h,d,p;this.config.async?(h=this.config.face.enabled?lg(this,l.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=Ye(),h=this.config.face.enabled?await lg(this,l.tensor):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.face=p)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?(y=this.models.posenet)==null?void 0:y.estimatePoses(l.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?Bg(l.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",a=Ye(),this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?await((A=this.models.posenet)==null?void 0:A.estimatePoses(l.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?await Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?await Bg(l.tensor,this.config):[]),p=Math.trunc(Ye()-a),p>0&&(this.perf.body=p)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(u=this.config.hand.enabled?(g=this.models.handpose)==null?void 0:g.estimateHands(l.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=Ye(),u=this.config.hand.enabled?await((x=this.models.handpose)==null?void 0:x.estimateHands(l.tensor,this.config)):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.hand=p)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(d=this.config.object.enabled?Hg(l.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",a=Ye(),d=this.config.object.enabled?await Hg(l.tensor,this.config):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.object=p)),this.analyze("End Object:"),this.config.async&&([h,c,u,d]=await Promise.all([h,c,u,d])),_e(l.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let f=[];this.config.gesture.enabled&&(a=Ye(),f=[...hk(h),...ck(c),...pk(u),...dk(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(Ye()-a)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(Ye()-i),this.state="idle";let m={face:h,body:c,hand:u,gesture:f,object:d,performance:this.perf,canvas:l.canvas};r(m)})}async warmup(t={}){let n=Ye();if(t&&(this.config=Jn(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await ur(this,X0).call(this):typeof Image!="undefined"?a=await ur(this,K0).call(this):a=await ur(this,Z0).call(this),this.config.videoOptimized=r;let s=Ye();return this.config.debug&&le("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};iu=new WeakMap,sh=new WeakMap,ih=new WeakMap,Ui=new WeakMap,q0=new WeakMap,oh=new WeakMap,X0=new WeakMap,K0=new WeakMap,Z0=new WeakMap;export{aoe as Human,aoe as default}; /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/dist/human.js b/dist/human.js index 33d3e454..b19f5e00 100644 --- a/dist/human.js +++ b/dist/human.js @@ -4908,7 +4908,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var wk="1.5.1";var iu,sh,ih,Ui,q0,oh,X0,K0,Z0,bk=class{constructor(t={}){iu.set(this,void 0);sh.set(this,void 0);ih.set(this,void 0);Ui.set(this,void 0);this.analyze=(...t)=>{if(!ur(this,sh))return;let n=this.tf.engine().state.numTensors,r=ur(this,iu);us(this,iu,n);let a=n-r;a!==0&&le(...t,a)};q0.set(this,t=>{if(!ur(this,ih))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof ze))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});oh.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let r=Ye();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&le("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&le("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let a=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&le(`wasm execution: ${a?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!a&&le("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&v8();try{await this.tf.setBackend(this.config.backend)}catch(a){le("error: cannot set backend:",this.config.backend,a)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(le("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let a=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&le(`gl version:${a.getParameter(a.VERSION)} renderer:${a.getParameter(a.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(Ye()-r)}});X0.set(this,async()=>{let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(H0);break;case"full":n=await t(G0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r});K0.set(this,async()=>new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+H0;break;case"full":case"body":r=1200,n="data:image/jpeg;base64,"+G0;break;default:n=null}let a=new Image;a.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=a.naturalWidth,s.height=a.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=await this.detect(s,this.config);t(o)},n?a.src=n:t(null)}));Z0.set(this,async()=>{let t=a=>Buffer.from(a,"base64"),n;if(this.config.warmup==="face"&&(n=t(H0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(G0)),!n)return null;let r;if(typeof void 0!="undefined"){let a=(void 0).decodeJpeg(n),s=a.expandDims(0);this.tf.dispose(a),r=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&le("Warmup tfjs-node not loaded");return r});this.tf=gu,this.draw=Xg,this.version=wk,this.config=Qn(ht,t),this.state="idle",us(this,iu,0),us(this,sh,!1),us(this,ih,!1),us(this,Ui,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>qg(n,this.config),this.classes={facemesh:fg,age:H2,gender:q2,emotion:J2,faceres:ag,body:this.config.body.modelPath.includes("posenet")?Sg:zg,hand:Fg,nanodet:Vg},this.faceTriangulation=D8,this.faceUVMap=O8,this.sysinfo=u5()}profileData(){return this.config.profile?g0:{}}similarity(t,n){return this.config.face.description.enabled?ig(t,n):this.config.face.embedding.enabled?k8(t,n):0}enhance(t){return og(t)}match(t,n,r=0){return I8(t,n,r)}async load(t={}){this.state="load";let n=Ye();t&&(this.config=Qn(this.config,t)),ur(this,Ui)&&(this.config.debug&&le(`version: ${this.version}`),this.config.debug&&le(`tfjs version: ${this.tf.version_core}`),this.config.debug&&le("platform:",this.sysinfo.platform),this.config.debug&&le("agent:",this.sysinfo.agent),await ur(this,oh).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&le("configuration:",this.config),this.config.debug&&le("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?yg(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?G2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Y2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?tg(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?ng(this.config):null),this.models.handpose||(this.config.hand.enabled?Og(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?Tg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?Pg(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?Wg(this.config):null),this.models.nanodet||(this.config.object.enabled?Ug(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?sg(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await yg(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await G2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Y2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await tg(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await ng(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await Og(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await Tg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await Pg(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await Wg(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await Ug(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await sg(this.config))),ur(this,Ui)&&(this.config.debug&&le("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),us(this,Ui,!1));let r=Math.trunc(Ye()-n);r>(this.perf.load||0)&&(this.perf.load=r)}async detect(t,n={}){return new Promise(async r=>{var y,A,g,x;this.state="config";let a;this.config=Qn(this.config,n),this.state="check";let s=ur(this,q0).call(this,t);s&&(le(s,t),r({error:s}));let i=Ye();await ur(this,oh).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&Gg instanceof ImageBitmap||t instanceof ze)&&(le("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),a=Ye();let l=qg(t,this.config);if(!l||!l.tensor){le("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(Ye()-a),this.analyze("Get Image:");let c,u,h,d,p;this.config.async?(h=this.config.face.enabled?lg(this,l.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=Ye(),h=this.config.face.enabled?await lg(this,l.tensor):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.face=p)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?(y=this.models.posenet)==null?void 0:y.estimatePoses(l.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?Bg(l.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",a=Ye(),this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?await((A=this.models.posenet)==null?void 0:A.estimatePoses(l.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?await Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?await Bg(l.tensor,this.config):[]),p=Math.trunc(Ye()-a),p>0&&(this.perf.body=p)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(u=this.config.hand.enabled?(g=this.models.handpose)==null?void 0:g.estimateHands(l.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=Ye(),u=this.config.hand.enabled?await((x=this.models.handpose)==null?void 0:x.estimateHands(l.tensor,this.config)):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.hand=p)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(d=this.config.object.enabled?Hg(l.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",a=Ye(),d=this.config.object.enabled?await Hg(l.tensor,this.config):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.object=p)),this.analyze("End Object:"),this.config.async&&([h,c,u,d]=await Promise.all([h,c,u,d])),_e(l.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let f=[];this.config.gesture.enabled&&(a=Ye(),f=[...hk(h),...ck(c),...pk(u),...dk(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(Ye()-a)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(Ye()-i),this.state="idle";let m={face:h,body:c,hand:u,gesture:f,object:d,performance:this.perf,canvas:l.canvas};r(m)})}async warmup(t={}){let n=Ye();if(t&&(this.config=Qn(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await ur(this,X0).call(this):typeof Image!="undefined"?a=await ur(this,K0).call(this):a=await ur(this,Z0).call(this),this.config.videoOptimized=r;let s=Ye();return this.config.debug&&le("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};iu=new WeakMap,sh=new WeakMap,ih=new WeakMap,Ui=new WeakMap,q0=new WeakMap,oh=new WeakMap,X0=new WeakMap,K0=new WeakMap,Z0=new WeakMap;return soe;})(); +2Q==`;var wk="1.5.2";var iu,sh,ih,Ui,q0,oh,X0,K0,Z0,bk=class{constructor(t={}){iu.set(this,void 0);sh.set(this,void 0);ih.set(this,void 0);Ui.set(this,void 0);this.analyze=(...t)=>{if(!ur(this,sh))return;let n=this.tf.engine().state.numTensors,r=ur(this,iu);us(this,iu,n);let a=n-r;a!==0&&le(...t,a)};q0.set(this,t=>{if(!ur(this,ih))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof ze))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});oh.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let r=Ye();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&le("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&le("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let a=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&le(`wasm execution: ${a?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!a&&le("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&v8();try{await this.tf.setBackend(this.config.backend)}catch(a){le("error: cannot set backend:",this.config.backend,a)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(le("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let a=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&le(`gl version:${a.getParameter(a.VERSION)} renderer:${a.getParameter(a.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(Ye()-r)}});X0.set(this,async()=>{let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(H0);break;case"full":n=await t(G0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r});K0.set(this,async()=>new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+H0;break;case"full":case"body":r=1200,n="data:image/jpeg;base64,"+G0;break;default:n=null}let a=new Image;a.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=a.naturalWidth,s.height=a.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=await this.detect(s,this.config);t(o)},n?a.src=n:t(null)}));Z0.set(this,async()=>{let t=a=>Buffer.from(a,"base64"),n;if(this.config.warmup==="face"&&(n=t(H0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(G0)),!n)return null;let r;if(typeof void 0!="undefined"){let a=(void 0).decodeJpeg(n),s=a.expandDims(0);this.tf.dispose(a),r=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&le("Warmup tfjs-node not loaded");return r});this.tf=gu,this.draw=Xg,this.version=wk,this.config=Qn(ht,t),this.state="idle",us(this,iu,0),us(this,sh,!1),us(this,ih,!1),us(this,Ui,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>qg(n,this.config),this.classes={facemesh:fg,age:H2,gender:q2,emotion:J2,faceres:ag,body:this.config.body.modelPath.includes("posenet")?Sg:zg,hand:Fg,nanodet:Vg},this.faceTriangulation=D8,this.faceUVMap=O8,this.sysinfo=u5()}profileData(){return this.config.profile?g0:{}}similarity(t,n){return this.config.face.description.enabled?ig(t,n):this.config.face.embedding.enabled?k8(t,n):0}enhance(t){return og(t)}match(t,n,r=0){return I8(t,n,r)}async load(t={}){this.state="load";let n=Ye();t&&(this.config=Qn(this.config,t)),ur(this,Ui)&&(this.config.debug&&le(`version: ${this.version}`),this.config.debug&&le(`tfjs version: ${this.tf.version_core}`),this.config.debug&&le("platform:",this.sysinfo.platform),this.config.debug&&le("agent:",this.sysinfo.agent),await ur(this,oh).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&le("configuration:",this.config),this.config.debug&&le("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?yg(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?G2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Y2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?tg(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?ng(this.config):null),this.models.handpose||(this.config.hand.enabled?Og(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?Tg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?Pg(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?Wg(this.config):null),this.models.nanodet||(this.config.object.enabled?Ug(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?sg(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await yg(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await G2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Y2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await tg(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await ng(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await Og(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await Tg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await Pg(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await Wg(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await Ug(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await sg(this.config))),ur(this,Ui)&&(this.config.debug&&le("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),us(this,Ui,!1));let r=Math.trunc(Ye()-n);r>(this.perf.load||0)&&(this.perf.load=r)}async detect(t,n={}){return new Promise(async r=>{var y,A,g,x;this.state="config";let a;this.config=Qn(this.config,n),this.state="check";let s=ur(this,q0).call(this,t);s&&(le(s,t),r({error:s}));let i=Ye();await ur(this,oh).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&Gg instanceof ImageBitmap||t instanceof ze)&&(le("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),a=Ye();let l=qg(t,this.config);if(!l||!l.tensor){le("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(Ye()-a),this.analyze("Get Image:");let c,u,h,d,p;this.config.async?(h=this.config.face.enabled?lg(this,l.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=Ye(),h=this.config.face.enabled?await lg(this,l.tensor):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.face=p)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?(y=this.models.posenet)==null?void 0:y.estimatePoses(l.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?Bg(l.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",a=Ye(),this.config.body.modelPath.includes("posenet")?c=this.config.body.enabled?await((A=this.models.posenet)==null?void 0:A.estimatePoses(l.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?c=this.config.body.enabled?await Lg(l.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(c=this.config.body.enabled?await Bg(l.tensor,this.config):[]),p=Math.trunc(Ye()-a),p>0&&(this.perf.body=p)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(u=this.config.hand.enabled?(g=this.models.handpose)==null?void 0:g.estimateHands(l.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=Ye(),u=this.config.hand.enabled?await((x=this.models.handpose)==null?void 0:x.estimateHands(l.tensor,this.config)):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.hand=p)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(d=this.config.object.enabled?Hg(l.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",a=Ye(),d=this.config.object.enabled?await Hg(l.tensor,this.config):[],p=Math.trunc(Ye()-a),p>0&&(this.perf.object=p)),this.analyze("End Object:"),this.config.async&&([h,c,u,d]=await Promise.all([h,c,u,d])),_e(l.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let f=[];this.config.gesture.enabled&&(a=Ye(),f=[...hk(h),...ck(c),...pk(u),...dk(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(Ye()-a)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(Ye()-i),this.state="idle";let m={face:h,body:c,hand:u,gesture:f,object:d,performance:this.perf,canvas:l.canvas};r(m)})}async warmup(t={}){let n=Ye();if(t&&(this.config=Qn(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await ur(this,X0).call(this):typeof Image!="undefined"?a=await ur(this,K0).call(this):a=await ur(this,Z0).call(this),this.config.videoOptimized=r;let s=Ye();return this.config.debug&&le("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};iu=new WeakMap,sh=new WeakMap,ih=new WeakMap,Ui=new WeakMap,q0=new WeakMap,oh=new WeakMap,X0=new WeakMap,K0=new WeakMap,Z0=new WeakMap;return soe;})(); /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/dist/human.node-gpu.js b/dist/human.node-gpu.js index a97f632a..1a9c9a57 100644 --- a/dist/human.node-gpu.js +++ b/dist/human.node-gpu.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var F0="1.5.1";var We,He,Ve,Te,ut,Xe,bt,gt,Tt,q0=class{constructor(t={}){We.set(this,void 0);He.set(this,void 0);Ve.set(this,void 0);Te.set(this,void 0);this.analyze=(...t)=>{if(!Ae(this,He))return;let n=this.tf.engine().state.numTensors,A=Ae(this,We);pe(this,We,n);let _=n-A;_!==0&&l(...t,_)};ut.set(this,t=>{if(!Ae(this,Ve))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof je.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Xe.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=v();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&l("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&l("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&l(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&l("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&X1();try{await this.tf.setBackend(this.config.backend)}catch(_){l("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(l("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&l(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(v()-A)}});bt.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(mt);break;case"full":n=await t(pt);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});gt.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+mt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+pt;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let o=await this.detect(c,this.config);t(o)},n?_.src=n:t(null)}));Tt.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(mt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(pt)),!n)return null;let A;if(typeof je.node!="undefined"){let _=je.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&l("Warmup tfjs-node not loaded");return A});this.tf=je,this.draw=W1,this.version=F0,this.config=ee(j,t),this.state="idle",pe(this,We,0),pe(this,He,!1),pe(this,Ve,!1),pe(this,Te,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>j1(n,this.config),this.classes={facemesh:Dt,age:vt,gender:Rt,emotion:Ot,faceres:Vt,body:this.config.body.modelPath.includes("posenet")?h1:b1,hand:d1,nanodet:z1},this.faceTriangulation=e0,this.faceUVMap=t0,this.sysinfo=Z1()}profileData(){return this.config.profile?Be:{}}similarity(t,n){return this.config.face.description.enabled?Ft(t,n):this.config.face.embedding.enabled?F1(t,n):0}enhance(t){return qt(t)}match(t,n,A=0){return q1(t,n,A)}async load(t={}){this.state="load";let n=v();t&&(this.config=ee(this.config,t)),Ae(this,Te)&&(this.config.debug&&l(`version: ${this.version}`),this.config.debug&&l(`tfjs version: ${this.tf.version_core}`),this.config.debug&&l("platform:",this.sysinfo.platform),this.config.debug&&l("agent:",this.sysinfo.agent),await Ae(this,Xe).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&l("configuration:",this.config),this.config.debug&&l("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?$t(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Et(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Nt(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Lt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?Zt(this.config):null),this.models.handpose||(this.config.hand.enabled?u1(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?a1(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?g1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?P1(this.config):null),this.models.nanodet||(this.config.object.enabled?E1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Xt(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await $t(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Et(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Nt(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Lt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await Zt(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await u1(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await a1(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await g1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await P1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await E1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Xt(this.config))),Ae(this,Te)&&(this.config.debug&&l("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),pe(this,Te,!1));let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var f,m,T,E;this.state="config";let _;this.config=ee(this.config,n),this.state="check";let c=Ae(this,ut).call(this,t);c&&(l(c,t),A({error:c}));let r=v();await Ae(this,Xe).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&S1 instanceof ImageBitmap||t instanceof je.Tensor)&&(l("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),_=v();let s=j1(t,this.config);if(!s||!s.tensor){l("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-_),this.analyze("Get Image:");let i,a,h,y,d;this.config.async?(h=this.config.face.enabled?Bt(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=v(),h=this.config.face.enabled?await Bt(this,s.tensor):[],d=Math.trunc(v()-_),d>0&&(this.perf.face=d)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?(f=this.models.posenet)==null?void 0:f.estimatePoses(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?M1(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=v(),this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?await((m=this.models.posenet)==null?void 0:m.estimatePoses(s.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?await T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?await M1(s.tensor,this.config):[]),d=Math.trunc(v()-_),d>0&&(this.perf.body=d)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(a=this.config.hand.enabled?(T=this.models.handpose)==null?void 0:T.estimateHands(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=v(),a=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(s.tensor,this.config)):[],d=Math.trunc(v()-_),d>0&&(this.perf.hand=d)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(y=this.config.object.enabled?R1(s.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=v(),y=this.config.object.enabled?await R1(s.tensor,this.config):[],d=Math.trunc(v()-_),d>0&&(this.perf.object=d)),this.analyze("End Object:"),this.config.async&&([h,i,a,y]=await Promise.all([h,i,a,y])),je.dispose(s.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let p=[];this.config.gesture.enabled&&(_=v(),p=[...N0(h),...W0(i),...k0(a),...O0(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-_)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(v()-r),this.state="idle";let x={face:h,body:i,hand:a,gesture:p,object:y,performance:this.perf,canvas:s.canvas};A(x)})}async warmup(t={}){let n=v();if(t&&(this.config=ee(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await Ae(this,bt).call(this):typeof Image!="undefined"?_=await Ae(this,gt).call(this):_=await Ae(this,Tt).call(this),this.config.videoOptimized=A;let c=v();return this.config.debug&&l("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};We=new WeakMap,He=new WeakMap,Ve=new WeakMap,Te=new WeakMap,ut=new WeakMap,Xe=new WeakMap,bt=new WeakMap,gt=new WeakMap,Tt=new WeakMap;0&&(module.exports={Human}); +2Q==`;var F0="1.5.2";var We,He,Ve,Te,ut,Xe,bt,gt,Tt,q0=class{constructor(t={}){We.set(this,void 0);He.set(this,void 0);Ve.set(this,void 0);Te.set(this,void 0);this.analyze=(...t)=>{if(!Ae(this,He))return;let n=this.tf.engine().state.numTensors,A=Ae(this,We);pe(this,We,n);let _=n-A;_!==0&&l(...t,_)};ut.set(this,t=>{if(!Ae(this,Ve))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof je.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Xe.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=v();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&l("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&l("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&l(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&l("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&X1();try{await this.tf.setBackend(this.config.backend)}catch(_){l("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(l("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&l(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(v()-A)}});bt.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(mt);break;case"full":n=await t(pt);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});gt.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+mt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+pt;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let o=await this.detect(c,this.config);t(o)},n?_.src=n:t(null)}));Tt.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(mt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(pt)),!n)return null;let A;if(typeof je.node!="undefined"){let _=je.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&l("Warmup tfjs-node not loaded");return A});this.tf=je,this.draw=W1,this.version=F0,this.config=ee(j,t),this.state="idle",pe(this,We,0),pe(this,He,!1),pe(this,Ve,!1),pe(this,Te,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>j1(n,this.config),this.classes={facemesh:Dt,age:vt,gender:Rt,emotion:Ot,faceres:Vt,body:this.config.body.modelPath.includes("posenet")?h1:b1,hand:d1,nanodet:z1},this.faceTriangulation=e0,this.faceUVMap=t0,this.sysinfo=Z1()}profileData(){return this.config.profile?Be:{}}similarity(t,n){return this.config.face.description.enabled?Ft(t,n):this.config.face.embedding.enabled?F1(t,n):0}enhance(t){return qt(t)}match(t,n,A=0){return q1(t,n,A)}async load(t={}){this.state="load";let n=v();t&&(this.config=ee(this.config,t)),Ae(this,Te)&&(this.config.debug&&l(`version: ${this.version}`),this.config.debug&&l(`tfjs version: ${this.tf.version_core}`),this.config.debug&&l("platform:",this.sysinfo.platform),this.config.debug&&l("agent:",this.sysinfo.agent),await Ae(this,Xe).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&l("configuration:",this.config),this.config.debug&&l("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?$t(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Et(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Nt(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Lt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?Zt(this.config):null),this.models.handpose||(this.config.hand.enabled?u1(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?a1(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?g1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?P1(this.config):null),this.models.nanodet||(this.config.object.enabled?E1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Xt(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await $t(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Et(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Nt(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Lt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await Zt(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await u1(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await a1(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await g1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await P1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await E1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Xt(this.config))),Ae(this,Te)&&(this.config.debug&&l("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),pe(this,Te,!1));let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var f,m,T,E;this.state="config";let _;this.config=ee(this.config,n),this.state="check";let c=Ae(this,ut).call(this,t);c&&(l(c,t),A({error:c}));let r=v();await Ae(this,Xe).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&S1 instanceof ImageBitmap||t instanceof je.Tensor)&&(l("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),_=v();let s=j1(t,this.config);if(!s||!s.tensor){l("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-_),this.analyze("Get Image:");let i,a,h,y,d;this.config.async?(h=this.config.face.enabled?Bt(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=v(),h=this.config.face.enabled?await Bt(this,s.tensor):[],d=Math.trunc(v()-_),d>0&&(this.perf.face=d)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?(f=this.models.posenet)==null?void 0:f.estimatePoses(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?M1(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=v(),this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?await((m=this.models.posenet)==null?void 0:m.estimatePoses(s.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?await T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?await M1(s.tensor,this.config):[]),d=Math.trunc(v()-_),d>0&&(this.perf.body=d)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(a=this.config.hand.enabled?(T=this.models.handpose)==null?void 0:T.estimateHands(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=v(),a=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(s.tensor,this.config)):[],d=Math.trunc(v()-_),d>0&&(this.perf.hand=d)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(y=this.config.object.enabled?R1(s.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=v(),y=this.config.object.enabled?await R1(s.tensor,this.config):[],d=Math.trunc(v()-_),d>0&&(this.perf.object=d)),this.analyze("End Object:"),this.config.async&&([h,i,a,y]=await Promise.all([h,i,a,y])),je.dispose(s.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let p=[];this.config.gesture.enabled&&(_=v(),p=[...N0(h),...W0(i),...k0(a),...O0(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-_)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(v()-r),this.state="idle";let x={face:h,body:i,hand:a,gesture:p,object:y,performance:this.perf,canvas:s.canvas};A(x)})}async warmup(t={}){let n=v();if(t&&(this.config=ee(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await Ae(this,bt).call(this):typeof Image!="undefined"?_=await Ae(this,gt).call(this):_=await Ae(this,Tt).call(this),this.config.videoOptimized=A;let c=v();return this.config.debug&&l("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};We=new WeakMap,He=new WeakMap,Ve=new WeakMap,Te=new WeakMap,ut=new WeakMap,Xe=new WeakMap,bt=new WeakMap,gt=new WeakMap,Tt=new WeakMap;0&&(module.exports={Human}); //# sourceMappingURL=human.node-gpu.js.map diff --git a/dist/human.node-wasm.js b/dist/human.node-wasm.js index e8b4db77..578a2e5d 100644 --- a/dist/human.node-wasm.js +++ b/dist/human.node-wasm.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var q0="1.5.1";var We,He,Ve,Te,bt,Xe,gt,Tt,Pt,B0=class{constructor(t={}){We.set(this,void 0);He.set(this,void 0);Ve.set(this,void 0);Te.set(this,void 0);this.analyze=(...t)=>{if(!Ae(this,He))return;let n=this.tf.engine().state.numTensors,A=Ae(this,We);pe(this,We,n);let _=n-A;_!==0&&l(...t,_)};bt.set(this,t=>{if(!Ae(this,Ve))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof je.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Xe.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=v();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&l("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&l("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&l(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&l("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&F1();try{await this.tf.setBackend(this.config.backend)}catch(_){l("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(l("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&l(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(v()-A)}});gt.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(pt);break;case"full":n=await t(ut);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});Tt.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+pt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+ut;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let o=await this.detect(c,this.config);t(o)},n?_.src=n:t(null)}));Pt.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(pt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(ut)),!n)return null;let A;if(typeof je.node!="undefined"){let _=je.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&l("Warmup tfjs-node not loaded");return A});this.tf=je,this.draw=N1,this.version=q0,this.config=ee(j,t),this.state="idle",pe(this,We,0),pe(this,He,!1),pe(this,Ve,!1),pe(this,Te,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>W1(n,this.config),this.classes={facemesh:Gt,age:Et,gender:St,emotion:kt,faceres:Xt,body:this.config.body.modelPath.includes("posenet")?i1:g1,hand:f1,nanodet:v1},this.faceTriangulation=t0,this.faceUVMap=n0,this.sysinfo=H1()}profileData(){return this.config.profile?Ue:{}}similarity(t,n){return this.config.face.description.enabled?qt(t,n):this.config.face.embedding.enabled?q1(t,n):0}enhance(t){return Bt(t)}match(t,n,A=0){return B1(t,n,A)}async load(t={}){this.state="load";let n=v();t&&(this.config=ee(this.config,t)),Ae(this,Te)&&(this.config.debug&&l(`version: ${this.version}`),this.config.debug&&l(`tfjs version: ${this.tf.version_core}`),this.config.debug&&l("platform:",this.sysinfo.platform),this.config.debug&&l("agent:",this.sysinfo.agent),await Ae(this,Xe).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&l("configuration:",this.config),this.config.debug&&l("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?e1(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Rt(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Ot(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Zt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?Ht(this.config):null),this.models.handpose||(this.config.hand.enabled?b1(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?x1(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?T1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?M1(this.config):null),this.models.nanodet||(this.config.object.enabled?R1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Ft(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await e1(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Rt(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Ot(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Zt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await Ht(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await b1(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await x1(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await T1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await M1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await R1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Ft(this.config))),Ae(this,Te)&&(this.config.debug&&l("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),pe(this,Te,!1));let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var f,m,T,E;this.state="config";let _;this.config=ee(this.config,n),this.state="check";let c=Ae(this,bt).call(this,t);c&&(l(c,t),A({error:c}));let r=v();await Ae(this,Xe).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&j1 instanceof ImageBitmap||t instanceof je.Tensor)&&(l("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),_=v();let s=W1(t,this.config);if(!s||!s.tensor){l("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-_),this.analyze("Get Image:");let i,a,h,y,d;this.config.async?(h=this.config.face.enabled?Ut(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=v(),h=this.config.face.enabled?await Ut(this,s.tensor):[],d=Math.trunc(v()-_),d>0&&(this.perf.face=d)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?(f=this.models.posenet)==null?void 0:f.estimatePoses(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?P1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?z1(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=v(),this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?await((m=this.models.posenet)==null?void 0:m.estimatePoses(s.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?await P1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?await z1(s.tensor,this.config):[]),d=Math.trunc(v()-_),d>0&&(this.perf.body=d)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(a=this.config.hand.enabled?(T=this.models.handpose)==null?void 0:T.estimateHands(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=v(),a=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(s.tensor,this.config)):[],d=Math.trunc(v()-_),d>0&&(this.perf.hand=d)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(y=this.config.object.enabled?S1(s.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=v(),y=this.config.object.enabled?await S1(s.tensor,this.config):[],d=Math.trunc(v()-_),d>0&&(this.perf.object=d)),this.analyze("End Object:"),this.config.async&&([h,i,a,y]=await Promise.all([h,i,a,y])),je.dispose(s.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let p=[];this.config.gesture.enabled&&(_=v(),p=[...O0(h),...N0(i),...I0(a),...k0(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-_)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(v()-r),this.state="idle";let x={face:h,body:i,hand:a,gesture:p,object:y,performance:this.perf,canvas:s.canvas};A(x)})}async warmup(t={}){let n=v();if(t&&(this.config=ee(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await Ae(this,gt).call(this):typeof Image!="undefined"?_=await Ae(this,Tt).call(this):_=await Ae(this,Pt).call(this),this.config.videoOptimized=A;let c=v();return this.config.debug&&l("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};We=new WeakMap,He=new WeakMap,Ve=new WeakMap,Te=new WeakMap,bt=new WeakMap,Xe=new WeakMap,gt=new WeakMap,Tt=new WeakMap,Pt=new WeakMap;0&&(module.exports={Human}); +2Q==`;var q0="1.5.2";var We,He,Ve,Te,bt,Xe,gt,Tt,Pt,B0=class{constructor(t={}){We.set(this,void 0);He.set(this,void 0);Ve.set(this,void 0);Te.set(this,void 0);this.analyze=(...t)=>{if(!Ae(this,He))return;let n=this.tf.engine().state.numTensors,A=Ae(this,We);pe(this,We,n);let _=n-A;_!==0&&l(...t,_)};bt.set(this,t=>{if(!Ae(this,Ve))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof je.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Xe.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=v();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&l("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&l("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&l(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&l("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&F1();try{await this.tf.setBackend(this.config.backend)}catch(_){l("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(l("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&l(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(v()-A)}});gt.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(pt);break;case"full":n=await t(ut);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});Tt.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+pt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+ut;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let o=await this.detect(c,this.config);t(o)},n?_.src=n:t(null)}));Pt.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(pt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(ut)),!n)return null;let A;if(typeof je.node!="undefined"){let _=je.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&l("Warmup tfjs-node not loaded");return A});this.tf=je,this.draw=N1,this.version=q0,this.config=ee(j,t),this.state="idle",pe(this,We,0),pe(this,He,!1),pe(this,Ve,!1),pe(this,Te,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>W1(n,this.config),this.classes={facemesh:Gt,age:Et,gender:St,emotion:kt,faceres:Xt,body:this.config.body.modelPath.includes("posenet")?i1:g1,hand:f1,nanodet:v1},this.faceTriangulation=t0,this.faceUVMap=n0,this.sysinfo=H1()}profileData(){return this.config.profile?Ue:{}}similarity(t,n){return this.config.face.description.enabled?qt(t,n):this.config.face.embedding.enabled?q1(t,n):0}enhance(t){return Bt(t)}match(t,n,A=0){return B1(t,n,A)}async load(t={}){this.state="load";let n=v();t&&(this.config=ee(this.config,t)),Ae(this,Te)&&(this.config.debug&&l(`version: ${this.version}`),this.config.debug&&l(`tfjs version: ${this.tf.version_core}`),this.config.debug&&l("platform:",this.sysinfo.platform),this.config.debug&&l("agent:",this.sysinfo.agent),await Ae(this,Xe).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&l("configuration:",this.config),this.config.debug&&l("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?e1(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Rt(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Ot(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Zt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?Ht(this.config):null),this.models.handpose||(this.config.hand.enabled?b1(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?x1(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?T1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?M1(this.config):null),this.models.nanodet||(this.config.object.enabled?R1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Ft(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await e1(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Rt(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Ot(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Zt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await Ht(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await b1(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await x1(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await T1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await M1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await R1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Ft(this.config))),Ae(this,Te)&&(this.config.debug&&l("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),pe(this,Te,!1));let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var f,m,T,E;this.state="config";let _;this.config=ee(this.config,n),this.state="check";let c=Ae(this,bt).call(this,t);c&&(l(c,t),A({error:c}));let r=v();await Ae(this,Xe).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&j1 instanceof ImageBitmap||t instanceof je.Tensor)&&(l("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),_=v();let s=W1(t,this.config);if(!s||!s.tensor){l("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-_),this.analyze("Get Image:");let i,a,h,y,d;this.config.async?(h=this.config.face.enabled?Ut(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=v(),h=this.config.face.enabled?await Ut(this,s.tensor):[],d=Math.trunc(v()-_),d>0&&(this.perf.face=d)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?(f=this.models.posenet)==null?void 0:f.estimatePoses(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?P1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?z1(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=v(),this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?await((m=this.models.posenet)==null?void 0:m.estimatePoses(s.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?await P1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?await z1(s.tensor,this.config):[]),d=Math.trunc(v()-_),d>0&&(this.perf.body=d)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(a=this.config.hand.enabled?(T=this.models.handpose)==null?void 0:T.estimateHands(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=v(),a=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(s.tensor,this.config)):[],d=Math.trunc(v()-_),d>0&&(this.perf.hand=d)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(y=this.config.object.enabled?S1(s.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=v(),y=this.config.object.enabled?await S1(s.tensor,this.config):[],d=Math.trunc(v()-_),d>0&&(this.perf.object=d)),this.analyze("End Object:"),this.config.async&&([h,i,a,y]=await Promise.all([h,i,a,y])),je.dispose(s.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let p=[];this.config.gesture.enabled&&(_=v(),p=[...O0(h),...N0(i),...I0(a),...k0(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-_)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(v()-r),this.state="idle";let x={face:h,body:i,hand:a,gesture:p,object:y,performance:this.perf,canvas:s.canvas};A(x)})}async warmup(t={}){let n=v();if(t&&(this.config=ee(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await Ae(this,gt).call(this):typeof Image!="undefined"?_=await Ae(this,Tt).call(this):_=await Ae(this,Pt).call(this),this.config.videoOptimized=A;let c=v();return this.config.debug&&l("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};We=new WeakMap,He=new WeakMap,Ve=new WeakMap,Te=new WeakMap,bt=new WeakMap,Xe=new WeakMap,gt=new WeakMap,Tt=new WeakMap,Pt=new WeakMap;0&&(module.exports={Human}); //# sourceMappingURL=human.node-wasm.js.map diff --git a/dist/human.node.js b/dist/human.node.js index 182228e9..89e87245 100644 --- a/dist/human.node.js +++ b/dist/human.node.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var F0="1.5.1";var We,He,Ve,Te,ut,Xe,bt,gt,Tt,q0=class{constructor(t={}){We.set(this,void 0);He.set(this,void 0);Ve.set(this,void 0);Te.set(this,void 0);this.analyze=(...t)=>{if(!Ae(this,He))return;let n=this.tf.engine().state.numTensors,A=Ae(this,We);pe(this,We,n);let _=n-A;_!==0&&l(...t,_)};ut.set(this,t=>{if(!Ae(this,Ve))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof je.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Xe.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=v();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&l("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&l("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&l(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&l("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&X1();try{await this.tf.setBackend(this.config.backend)}catch(_){l("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(l("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&l(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(v()-A)}});bt.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(mt);break;case"full":n=await t(pt);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});gt.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+mt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+pt;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let o=await this.detect(c,this.config);t(o)},n?_.src=n:t(null)}));Tt.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(mt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(pt)),!n)return null;let A;if(typeof je.node!="undefined"){let _=je.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&l("Warmup tfjs-node not loaded");return A});this.tf=je,this.draw=W1,this.version=F0,this.config=ee(j,t),this.state="idle",pe(this,We,0),pe(this,He,!1),pe(this,Ve,!1),pe(this,Te,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>j1(n,this.config),this.classes={facemesh:Dt,age:vt,gender:Rt,emotion:Ot,faceres:Vt,body:this.config.body.modelPath.includes("posenet")?h1:b1,hand:d1,nanodet:z1},this.faceTriangulation=e0,this.faceUVMap=t0,this.sysinfo=Z1()}profileData(){return this.config.profile?Be:{}}similarity(t,n){return this.config.face.description.enabled?Ft(t,n):this.config.face.embedding.enabled?F1(t,n):0}enhance(t){return qt(t)}match(t,n,A=0){return q1(t,n,A)}async load(t={}){this.state="load";let n=v();t&&(this.config=ee(this.config,t)),Ae(this,Te)&&(this.config.debug&&l(`version: ${this.version}`),this.config.debug&&l(`tfjs version: ${this.tf.version_core}`),this.config.debug&&l("platform:",this.sysinfo.platform),this.config.debug&&l("agent:",this.sysinfo.agent),await Ae(this,Xe).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&l("configuration:",this.config),this.config.debug&&l("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?$t(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Et(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Nt(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Lt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?Zt(this.config):null),this.models.handpose||(this.config.hand.enabled?u1(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?a1(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?g1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?P1(this.config):null),this.models.nanodet||(this.config.object.enabled?E1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Xt(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await $t(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Et(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Nt(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Lt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await Zt(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await u1(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await a1(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await g1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await P1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await E1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Xt(this.config))),Ae(this,Te)&&(this.config.debug&&l("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),pe(this,Te,!1));let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var f,m,T,E;this.state="config";let _;this.config=ee(this.config,n),this.state="check";let c=Ae(this,ut).call(this,t);c&&(l(c,t),A({error:c}));let r=v();await Ae(this,Xe).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&S1 instanceof ImageBitmap||t instanceof je.Tensor)&&(l("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),_=v();let s=j1(t,this.config);if(!s||!s.tensor){l("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-_),this.analyze("Get Image:");let i,a,h,y,d;this.config.async?(h=this.config.face.enabled?Bt(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=v(),h=this.config.face.enabled?await Bt(this,s.tensor):[],d=Math.trunc(v()-_),d>0&&(this.perf.face=d)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?(f=this.models.posenet)==null?void 0:f.estimatePoses(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?M1(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=v(),this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?await((m=this.models.posenet)==null?void 0:m.estimatePoses(s.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?await T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?await M1(s.tensor,this.config):[]),d=Math.trunc(v()-_),d>0&&(this.perf.body=d)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(a=this.config.hand.enabled?(T=this.models.handpose)==null?void 0:T.estimateHands(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=v(),a=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(s.tensor,this.config)):[],d=Math.trunc(v()-_),d>0&&(this.perf.hand=d)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(y=this.config.object.enabled?R1(s.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=v(),y=this.config.object.enabled?await R1(s.tensor,this.config):[],d=Math.trunc(v()-_),d>0&&(this.perf.object=d)),this.analyze("End Object:"),this.config.async&&([h,i,a,y]=await Promise.all([h,i,a,y])),je.dispose(s.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let p=[];this.config.gesture.enabled&&(_=v(),p=[...N0(h),...W0(i),...k0(a),...O0(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-_)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(v()-r),this.state="idle";let x={face:h,body:i,hand:a,gesture:p,object:y,performance:this.perf,canvas:s.canvas};A(x)})}async warmup(t={}){let n=v();if(t&&(this.config=ee(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await Ae(this,bt).call(this):typeof Image!="undefined"?_=await Ae(this,gt).call(this):_=await Ae(this,Tt).call(this),this.config.videoOptimized=A;let c=v();return this.config.debug&&l("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};We=new WeakMap,He=new WeakMap,Ve=new WeakMap,Te=new WeakMap,ut=new WeakMap,Xe=new WeakMap,bt=new WeakMap,gt=new WeakMap,Tt=new WeakMap;0&&(module.exports={Human}); +2Q==`;var F0="1.5.2";var We,He,Ve,Te,ut,Xe,bt,gt,Tt,q0=class{constructor(t={}){We.set(this,void 0);He.set(this,void 0);Ve.set(this,void 0);Te.set(this,void 0);this.analyze=(...t)=>{if(!Ae(this,He))return;let n=this.tf.engine().state.numTensors,A=Ae(this,We);pe(this,We,n);let _=n-A;_!==0&&l(...t,_)};ut.set(this,t=>{if(!Ae(this,Ve))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof je.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Xe.set(this,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let A=v();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(this.tf.ENV.flags.IS_BROWSER&&this.config.backend==="tensorflow"&&(this.config.backend="webgl"),this.tf.ENV.flags.IS_NODE&&(this.config.backend==="webgl"||this.config.backend==="humangl")&&(this.config.backend="tensorflow"),this.config.debug&&l("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&l("wasm path:",this.config.wasmPath),typeof((n=this.tf)==null?void 0:n.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let _=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),c=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&l(`wasm execution: ${_?"SIMD":"no SIMD"} ${c?"multithreaded":"singlethreaded"}`),this.config.debug&&!_&&l("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&X1();try{await this.tf.setBackend(this.config.backend)}catch(_){l("error: cannot set backend:",this.config.backend,_)}}if(this.tf.enableProdMode(),this.tf.getBackend()==="webgl"||this.tf.getBackend()==="humangl"){this.tf.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),this.config.deallocate&&(l("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1));let _=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&l(`gl version:${_.getParameter(_.VERSION)} renderer:${_.getParameter(_.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(v()-A)}});bt.set(this,async()=>{let t=(_,c="application/octet-stream")=>fetch(`data:${c};base64,${_}`).then(r=>r.blob()),n,A;switch(this.config.warmup){case"face":n=await t(mt);break;case"full":n=await t(pt);break;default:n=null}if(n){let _=await createImageBitmap(n);A=await this.detect(_,this.config),_.close()}return A});gt.set(this,async()=>new Promise(t=>{let n,A=0;switch(this.config.warmup){case"face":A=256,n="data:image/jpeg;base64,"+mt;break;case"full":case"body":A=1200,n="data:image/jpeg;base64,"+pt;break;default:n=null}let _=new Image;_.onload=async()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(A,A):document.createElement("canvas");c.width=_.naturalWidth,c.height=_.naturalHeight;let r=c.getContext("2d");r==null||r.drawImage(_,0,0);let o=await this.detect(c,this.config);t(o)},n?_.src=n:t(null)}));Tt.set(this,async()=>{let t=_=>Buffer.from(_,"base64"),n;if(this.config.warmup==="face"&&(n=t(mt)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(pt)),!n)return null;let A;if(typeof je.node!="undefined"){let _=je.node.decodeJpeg(n),c=_.expandDims(0);this.tf.dispose(_),A=await this.detect(c,this.config),this.tf.dispose(c)}else this.config.debug&&l("Warmup tfjs-node not loaded");return A});this.tf=je,this.draw=W1,this.version=F0,this.config=ee(j,t),this.state="idle",pe(this,We,0),pe(this,He,!1),pe(this,Ve,!1),pe(this,Te,!0),this.perf={},this.models={face:null,posenet:null,blazepose:null,efficientpose:null,handpose:null,iris:null,age:null,gender:null,emotion:null,embedding:null,nanodet:null,faceres:null},this.image=n=>j1(n,this.config),this.classes={facemesh:Dt,age:vt,gender:Rt,emotion:Ot,faceres:Vt,body:this.config.body.modelPath.includes("posenet")?h1:b1,hand:d1,nanodet:z1},this.faceTriangulation=e0,this.faceUVMap=t0,this.sysinfo=Z1()}profileData(){return this.config.profile?Be:{}}similarity(t,n){return this.config.face.description.enabled?Ft(t,n):this.config.face.embedding.enabled?F1(t,n):0}enhance(t){return qt(t)}match(t,n,A=0){return q1(t,n,A)}async load(t={}){this.state="load";let n=v();t&&(this.config=ee(this.config,t)),Ae(this,Te)&&(this.config.debug&&l(`version: ${this.version}`),this.config.debug&&l(`tfjs version: ${this.tf.version_core}`),this.config.debug&&l("platform:",this.sysinfo.platform),this.config.debug&&l("agent:",this.sysinfo.agent),await Ae(this,Xe).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&l("configuration:",this.config),this.config.debug&&l("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.efficientpose,this.models.nanodet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?$t(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Et(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Nt(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Lt(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?Zt(this.config):null),this.models.handpose||(this.config.hand.enabled?u1(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?a1(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?g1(this.config):null),this.models.efficientpose||(this.config.body.enabled&&this.config.body.modelPath.includes("efficientpose")?P1(this.config):null),this.models.nanodet||(this.config.object.enabled?E1(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Xt(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await $t(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Et(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Nt(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Lt(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await Zt(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await u1(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await a1(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await g1(this.config)),this.config.body.enabled&&!this.models.efficientpose&&this.config.body.modelPath.includes("efficientpose")&&(this.models.efficientpose=await P1(this.config)),this.config.object.enabled&&!this.models.nanodet&&(this.models.nanodet=await E1(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Xt(this.config))),Ae(this,Te)&&(this.config.debug&&l("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),pe(this,Te,!1));let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async detect(t,n={}){return new Promise(async A=>{var f,m,T,E;this.state="config";let _;this.config=ee(this.config,n),this.state="check";let c=Ae(this,ut).call(this,t);c&&(l(c,t),A({error:c}));let r=v();await Ae(this,Xe).call(this),await this.load(),this.config.scoped&&this.tf.engine().startScope(),this.analyze("Start Scope:");let o;t&&this.config.videoOptimized&&(t instanceof HTMLImageElement||t instanceof Image||t instanceof ImageData||typeof ImageBitmap!="undefined"&&S1 instanceof ImageBitmap||t instanceof je.Tensor)&&(l("disabling video optimization"),o=this.config.videoOptimized,this.config.videoOptimized=!1),_=v();let s=j1(t,this.config);if(!s||!s.tensor){l("could not convert input to tensor"),A({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-_),this.analyze("Get Image:");let i,a,h,y,d;this.config.async?(h=this.config.face.enabled?Bt(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",_=v(),h=this.config.face.enabled?await Bt(this,s.tensor):[],d=Math.trunc(v()-_),d>0&&(this.perf.face=d)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?(f=this.models.posenet)==null?void 0:f.estimatePoses(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?M1(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",_=v(),this.config.body.modelPath.includes("posenet")?i=this.config.body.enabled?await((m=this.models.posenet)==null?void 0:m.estimatePoses(s.tensor,this.config)):[]:this.config.body.modelPath.includes("blazepose")?i=this.config.body.enabled?await T1(s.tensor,this.config):[]:this.config.body.modelPath.includes("efficientpose")&&(i=this.config.body.enabled?await M1(s.tensor,this.config):[]),d=Math.trunc(v()-_),d>0&&(this.perf.body=d)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(a=this.config.hand.enabled?(T=this.models.handpose)==null?void 0:T.estimateHands(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",_=v(),a=this.config.hand.enabled?await((E=this.models.handpose)==null?void 0:E.estimateHands(s.tensor,this.config)):[],d=Math.trunc(v()-_),d>0&&(this.perf.hand=d)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(y=this.config.object.enabled?R1(s.tensor,this.config):[],this.perf.object&&delete this.perf.object):(this.state="run:object",_=v(),y=this.config.object.enabled?await R1(s.tensor,this.config):[],d=Math.trunc(v()-_),d>0&&(this.perf.object=d)),this.analyze("End Object:"),this.config.async&&([h,i,a,y]=await Promise.all([h,i,a,y])),je.dispose(s.tensor),this.config.scoped&&this.tf.engine().endScope(),this.analyze("End Scope:");let p=[];this.config.gesture.enabled&&(_=v(),p=[...N0(h),...W0(i),...k0(a),...O0(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-_)),o&&(this.config.videoOptimized=o),this.perf.total=Math.trunc(v()-r),this.state="idle";let x={face:h,body:i,hand:a,gesture:p,object:y,performance:this.perf,canvas:s.canvas};A(x)})}async warmup(t={}){let n=v();if(t&&(this.config=ee(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let A=this.config.videoOptimized;this.config.videoOptimized=!1;let _;typeof createImageBitmap=="function"?_=await Ae(this,bt).call(this):typeof Image!="undefined"?_=await Ae(this,gt).call(this):_=await Ae(this,Tt).call(this),this.config.videoOptimized=A;let c=v();return this.config.debug&&l("Warmup",this.config.warmup,Math.round(c-n),"ms",_),_}};We=new WeakMap,He=new WeakMap,Ve=new WeakMap,Te=new WeakMap,ut=new WeakMap,Xe=new WeakMap,bt=new WeakMap,gt=new WeakMap,Tt=new WeakMap;0&&(module.exports={Human}); //# sourceMappingURL=human.node.js.map diff --git a/package.json b/package.json index a7a2e108..9c3254bd 100644 --- a/package.json +++ b/package.json @@ -21,11 +21,11 @@ "url": "git+https://github.com/vladmandic/human.git" }, "scripts": { - "start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation demo/node.js", + "start": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught demo/node.js", "dev": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/serve.js", "build": "rimraf dist/* typedoc/* types/* && node --trace-warnings --unhandled-rejections=strict --trace-uncaught server/build.js", "lint": "eslint src server demo test", - "test": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation test/test-node.js" + "test": "node --trace-warnings --unhandled-rejections=strict --trace-uncaught test/test.js" }, "keywords": [ "human", @@ -61,14 +61,14 @@ "@tensorflow/tfjs-layers": "^3.4.0", "@tensorflow/tfjs-node": "^3.4.0", "@tensorflow/tfjs-node-gpu": "^3.4.0", - "@types/node": "^14.14.37", + "@types/node": "^14.14.39", "@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/parser": "^4.22.0", - "@vladmandic/pilogger": "^0.2.16", + "@vladmandic/pilogger": "^0.2.17", "canvas": "^2.7.0", "chokidar": "^3.5.1", "dayjs": "^1.10.4", - "esbuild": "^0.11.10", + "esbuild": "^0.11.11", "eslint": "^7.24.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.22.1", diff --git a/server/build.js b/server/build.js old mode 100755 new mode 100644 index 88d4d25e..c8d84eff --- a/server/build.js +++ b/server/build.js @@ -1,6 +1,5 @@ -#!/usr/bin/env -S node --trace-warnings - const ts = require('typescript'); +const path = require('path'); const log = require('@vladmandic/pilogger'); const esbuild = require('esbuild'); const TypeDoc = require('typedoc'); @@ -265,6 +264,7 @@ async function build(f, msg, dev = false) { } if (require.main === module) { + log.logFile(path.join(__dirname, 'build.log')); log.header(); build('all', 'startup'); } else { diff --git a/server/build.log b/server/build.log new file mode 100644 index 00000000..f862d010 --- /dev/null +++ b/server/build.log @@ -0,0 +1,34 @@ +2021-04-15 09:36:00 INFO:  @vladmandic/human version 1.5.2 +2021-04-15 09:36:00 INFO:  User: vlado Platform: linux Arch: x64 Node: v15.7.0 +2021-04-15 09:36:00 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true,"sourcemap":true,"bundle":true,"metafile":true,"target":"es2018"} +2021-04-15 09:36:00 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":733,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:36:00 STATE: Build for: node type: node: {"imports":46,"importBytes":545147,"outputBytes":304326,"outputFiles":"dist/human.node.js"} +2021-04-15 09:36:00 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":737,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:36:00 STATE: Build for: nodeGPU type: node: {"imports":46,"importBytes":545151,"outputBytes":304334,"outputFiles":"dist/human.node-gpu.js"} +2021-04-15 09:36:00 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":783,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:36:00 STATE: Build for: nodeWASM type: node: {"imports":46,"importBytes":545197,"outputBytes":304378,"outputFiles":"dist/human.node-wasm.js"} +2021-04-15 09:36:00 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:36:00 STATE: Build for: browserNoBundle type: esm: {"imports":46,"importBytes":545808,"outputBytes":304324,"outputFiles":"dist/human.esm-nobundle.js"} +2021-04-15 09:36:01 STATE: Build for: browserBundle type: tfjs: {"modules":1262,"moduleBytes":4068263,"imports":7,"importBytes":2488,"outputBytes":1097287,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:36:01 STATE: Build for: browserBundle type: iife: {"imports":46,"importBytes":1641701,"outputBytes":1397747,"outputFiles":"dist/human.js"} +2021-04-15 09:36:02 STATE: Build for: browserBundle type: esm: {"imports":46,"importBytes":1641701,"outputBytes":1397705,"outputFiles":"dist/human.esm.js"} +2021-04-15 09:36:02 INFO:  Generate types: ["src/human.ts"] +2021-04-15 09:36:07 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"] +2021-04-15 09:36:07 INFO:  Generate TypeDocs: ["src/human.ts"] +2021-04-15 09:40:34 INFO:  @vladmandic/human version 1.5.2 +2021-04-15 09:40:34 INFO:  User: vlado Platform: linux Arch: x64 Node: v15.7.0 +2021-04-15 09:40:34 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true,"sourcemap":true,"bundle":true,"metafile":true,"target":"es2018"} +2021-04-15 09:40:34 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":39,"outputBytes":733,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:40:34 STATE: Build for: node type: node: {"imports":46,"importBytes":545147,"outputBytes":304326,"outputFiles":"dist/human.node.js"} +2021-04-15 09:40:34 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":43,"outputBytes":737,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:40:35 STATE: Build for: nodeGPU type: node: {"imports":46,"importBytes":545151,"outputBytes":304334,"outputFiles":"dist/human.node-gpu.js"} +2021-04-15 09:40:35 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":81,"outputBytes":783,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:40:35 STATE: Build for: nodeWASM type: node: {"imports":46,"importBytes":545197,"outputBytes":304378,"outputFiles":"dist/human.node-wasm.js"} +2021-04-15 09:40:35 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2488,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:40:35 STATE: Build for: browserNoBundle type: esm: {"imports":46,"importBytes":545808,"outputBytes":304324,"outputFiles":"dist/human.esm-nobundle.js"} +2021-04-15 09:40:35 STATE: Build for: browserBundle type: tfjs: {"modules":1262,"moduleBytes":4068263,"imports":7,"importBytes":2488,"outputBytes":1097287,"outputFiles":"dist/tfjs.esm.js"} +2021-04-15 09:40:36 STATE: Build for: browserBundle type: iife: {"imports":46,"importBytes":1641701,"outputBytes":1397747,"outputFiles":"dist/human.js"} +2021-04-15 09:40:36 STATE: Build for: browserBundle type: esm: {"imports":46,"importBytes":1641701,"outputBytes":1397705,"outputFiles":"dist/human.esm.js"} +2021-04-15 09:40:36 INFO:  Generate types: ["src/human.ts"] +2021-04-15 09:40:41 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"] +2021-04-15 09:40:41 INFO:  Generate TypeDocs: ["src/human.ts"] diff --git a/server/serve.js b/server/serve.js old mode 100755 new mode 100644 index 4eae4266..7723d015 --- a/server/serve.js +++ b/server/serve.js @@ -1,5 +1,3 @@ -#!/usr/bin/env -S node --trace-warnings - /* micro http2 server with file monitoring and automatic app rebuild - can process concurrent http requests diff --git a/test/README.md b/test/README.md index 74922714..3baf1784 100644 --- a/test/README.md +++ b/test/README.md @@ -4,22 +4,23 @@ ### NodeJS using TensorFlow library +- Image filters are disabled due to lack of Canvas and WeBGL access - Face rotation is disabled for `NodeJS` platform: `Kernel 'RotateWithOffset' not registered for backend 'tensorflow'` -- Image filters are disabled due to lack of Canvas and WeBGL access ### NodeJS with GPU acceleation using CUDA +- Image filters are disabled due to lack of Canvas and WeBGL access - Face rotation is disabled for `NodeJS` platform: `Kernel 'RotateWithOffset' not registered for backend 'tensorflow'` -- Image filters are disabled due to lack of Canvas and WeBGL access ### NodeJS using WASM - Requires dev http server See +- Image filters are disabled due to lack of Canvas and WeBGL access - Only supported input is Tensor due to missing image decoders - Warmup returns null and is marked as failed Missing native Image implementation in NodeJS diff --git a/test/test-main.js b/test/test-main.js index c447695a..165a4c7c 100644 --- a/test/test-main.js +++ b/test/test-main.js @@ -1,23 +1,25 @@ const process = require('process'); -const path = require('path'); -const log = require('@vladmandic/pilogger'); const canvasJS = require('canvas'); const fetch = require('node-fetch').default; let config; -log.info('test:', path.basename(process.argv[1])); + +const log = (status, ...data) => { + if (typeof process.send !== 'undefined') process.send([status, data]); + else process.stdout.write(JSON.stringify(data)); +}; async function testHTTP() { if (config.modelBasePath.startsWith('file:')) return true; return new Promise((resolve) => { fetch(config.modelBasePath) .then((res) => { - if (res && res.ok) log.state('passed: model server:', config.modelBasePath); - else log.error('failed: model server:', config.modelBasePath); + if (res && res.ok) log('state', 'passed: model server:', config.modelBasePath); + else log('error', 'failed: model server:', config.modelBasePath); resolve(res && res.ok); }) .catch((err) => { - log.error('failed: model server:', err.message); + log('error', 'failed: model server:', err.message); resolve(false); }); }); @@ -28,7 +30,7 @@ async function getImage(human, input) { try { img = await canvasJS.loadImage(input); } catch (err) { - log.error('failed: load image', input, err.message); + log('error', 'failed: load image', input, err.message); return img; } const canvas = canvasJS.createCanvas(img.width, img.height); @@ -42,8 +44,8 @@ async function getImage(human, input) { const reshape = human.tf.reshape(rgb, [1, canvas.width, canvas.height, 3]); // move extra dim from the end of tensor and use it as batch number instead return reshape; }); - if (res && res.shape[0] === 1 && res.shape[3] === 3) log.state('passed: load image:', input, res.shape); - else log.error('failed: load image:', input, res); + if (res && res.shape[0] === 1 && res.shape[3] === 3) log('state', 'passed: load image:', input, res.shape); + else log('error', 'failed: load image:', input, res); return res; } @@ -51,31 +53,31 @@ function printResults(detect) { const person = (detect.face && detect.face[0]) ? { confidence: detect.face[0].confidence, age: detect.face[0].age, gender: detect.face[0].gender } : {}; const object = (detect.object && detect.object[0]) ? { score: detect.object[0].score, class: detect.object[0].label } : {}; const body = (detect.body && detect.body[0]) ? { score: detect.body[0].score, keypoints: detect.body[0].keypoints.length } : {}; - if (detect.face) log.data(' result: face:', detect.face?.length, 'body:', detect.body?.length, 'hand:', detect.hand?.length, 'gesture:', detect.gesture?.length, 'object:', detect.object?.length, person, object, body); - if (detect.performance) log.data(' result: performance:', 'load:', detect?.performance.load, 'total:', detect.performance?.total); + if (detect.face) log('data', ' result: face:', detect.face?.length, 'body:', detect.body?.length, 'hand:', detect.hand?.length, 'gesture:', detect.gesture?.length, 'object:', detect.object?.length, person, object, body); + if (detect.performance) log('data', ' result: performance:', 'load:', detect?.performance.load, 'total:', detect.performance?.total); } async function testInstance(human) { - if (human) log.state('passed: create human'); - else log.error('failed: create human'); + if (human) log('state', 'passed: create human'); + else log('error', 'failed: create human'); // if (!human.tf) human.tf = tf; - log.info('human version:', human.version); - log.info('platform:', human.sysinfo.platform, 'agent:', human.sysinfo.agent); - log.info('tfjs version:', human.tf.version.tfjs); + log('info', 'human version:', human.version); + log('info', 'platform:', human.sysinfo.platform, 'agent:', human.sysinfo.agent); + log('info', 'tfjs version:', human.tf.version.tfjs); await human.load(); - if (config.backend === human.tf.getBackend()) log.state('passed: set backend:', config.backend); - else log.error('failed: set backend:', config.backend); + if (config.backend === human.tf.getBackend()) log('state', 'passed: set backend:', config.backend); + else log('error', 'failed: set backend:', config.backend); if (human.models) { - log.state('passed: load models'); + log('state', 'passed: load models'); const keys = Object.keys(human.models); const loaded = keys.filter((model) => human.models[model]); - log.data(' result: defined models:', keys.length, 'loaded models:', loaded.length); + log('state', ' result: defined models:', keys.length, 'loaded models:', loaded.length); return true; } - log.error('failed: load models'); + log('error', 'failed: load models'); return false; } @@ -84,36 +86,36 @@ async function testWarmup(human, title) { try { warmup = await human.warmup(config); } catch (err) { - log.error('error warmup'); + log('error', 'error warmup'); } if (warmup) { - log.state('passed: warmup:', config.warmup, title); + log('state', 'passed: warmup:', config.warmup, title); printResults(warmup); return true; } - log.error('failed: warmup:', config.warmup, title); + log('error', 'failed: warmup:', config.warmup, title); return false; } async function testDetect(human, input, title) { const image = input ? await getImage(human, input) : human.tf.randomNormal([1, 1024, 1024, 3]); if (!image) { - log.error('failed: detect: input is null'); + log('error', 'failed: detect: input is null'); return false; } let detect; try { detect = await human.detect(image, config); } catch (err) { - log.error('error: detect', err); + log('error', 'error: detect', err); } if (image instanceof human.tf.Tensor) human.tf.dispose(image); if (detect) { - log.state('passed: detect:', input || 'random', title); + log('state', 'passed: detect:', input || 'random', title); printResults(detect); return true; } - log.error('failed: detect', input || 'random', title); + log('error', 'failed: detect', input || 'random', title); return false; } @@ -121,7 +123,7 @@ async function test(Human, inputConfig) { config = inputConfig; const ok = await testHTTP(); if (!ok) { - log.warn('aborting test'); + log('error', 'aborting test'); return; } const t0 = process.hrtime.bigint(); @@ -134,7 +136,7 @@ async function test(Human, inputConfig) { config.warmup = 'body'; await testWarmup(human, 'default'); - log.info('test body variants'); + log('info', 'test body variants'); config.body = { modelPath: 'posenet.json', enabled: true }; await testDetect(human, 'assets/human-sample-body.jpg', 'posenet'); config.body = { modelPath: 'efficientpose.json', enabled: true }; @@ -143,12 +145,12 @@ async function test(Human, inputConfig) { await testDetect(human, 'assets/human-sample-body.jpg', 'blazepose'); await testDetect(human, null, 'default'); - log.info('test: first instance'); + log('info', 'test: first instance'); await testDetect(human, 'assets/sample-me.jpg', 'default'); - log.info('test: second instance'); + log('info', 'test: second instance'); const second = new Human(config); await testDetect(second, 'assets/sample-me.jpg', 'default'); - log.info('test: concurrent'); + log('info', 'test: concurrent'); await Promise.all([ testDetect(human, 'assets/human-sample-face.jpg', 'default'), testDetect(second, 'assets/human-sample-face.jpg', 'default'), @@ -156,7 +158,7 @@ async function test(Human, inputConfig) { testDetect(second, 'assets/human-sample-body.jpg', 'default'), ]); const t1 = process.hrtime.bigint(); - log.info('test complete:', Math.trunc(parseInt((t1 - t0).toString()) / 1000 / 1000), 'ms'); + log('info', 'test complete:', Math.trunc(parseInt((t1 - t0).toString()) / 1000 / 1000), 'ms'); } exports.test = test; diff --git a/test/test.js b/test/test.js new file mode 100644 index 00000000..78da5574 --- /dev/null +++ b/test/test.js @@ -0,0 +1,69 @@ +const path = require('path'); +const process = require('process'); +const { fork } = require('child_process'); +const log = require('@vladmandic/pilogger'); + +const tests = [ + 'test-node.js', + 'test-node-gpu.js', + 'test-node-wasm.js', +]; + +const ignore = [ + 'cpu_feature_guard.cc', + 'rebuild TensorFlow', + 'xla_gpu_device.cc', + 'cudart_stub.cc', + 'cuda_driver.cc:326', + 'cpu_allocator_impl.cc', +]; + +const status = { + passed: 0, + failed: 0, +}; + +function logMessage(test, data) { + log[data[0]](test, ...data[1]); + if (data[1][0].startsWith('passed')) status.passed++; + if (data[1][0].startsWith('failed')) status.failed++; +} + +function logStdIO(ok, test, buffer) { + const lines = buffer.toString().split(/\r\n|\n\r|\n|\r/); + const filtered = lines.filter((line) => { + for (const ignoreString of ignore) { + if (line.includes(ignoreString)) return false; + } + return true; + }); + for (const line of filtered) { + if (line.length < 2) continue; + if (ok) log.data(test, 'stdout:', line); + else log.warn(test, 'stderr:', line); + } +} + +async function runTest(test) { + return new Promise((resolve) => { + log.info(test, 'start'); + const child = fork(path.join(__dirname, test), [], { silent: true }); + child.on('message', (data) => logMessage(test, data)); + child.on('error', (data) => log.error(test, ':', data.message || data)); + child.on('close', (code) => resolve(code)); + child.stdout?.on('data', (data) => logStdIO(true, test, data)); + child.stderr?.on('data', (data) => logStdIO(false, test, data)); + }); +} + +async function testAll() { + log.logFile(path.join(__dirname, 'test.log')); + log.header(); + process.on('unhandledRejection', (data) => log.error('nodejs unhandled rejection', data)); + process.on('uncaughtException', (data) => log.error('nodejs unhandled exception', data)); + log.info('tests:', tests); + for (const test of tests) await runTest(test); + log.info('status:', status); +} + +testAll(); diff --git a/test/test.log b/test/test.log new file mode 100644 index 00000000..26c5e233 --- /dev/null +++ b/test/test.log @@ -0,0 +1,181 @@ +2021-04-15 09:33:11 INFO:  @vladmandic/human version 1.5.2 +2021-04-15 09:33:11 INFO:  User: vlado Platform: linux Arch: x64 Node: v15.7.0 +2021-04-15 09:33:11 INFO:  tests: ["test-node.js","test-node-gpu.js","test-node-wasm.js"] +2021-04-15 09:33:11 INFO:  test-node.js start +2021-04-15 09:33:12 STATE: test-node.js passed: create human +2021-04-15 09:33:12 INFO:  test-node.js human version: 1.5.2 +2021-04-15 09:33:12 INFO:  test-node.js platform: linux x64 agent: NodeJS v15.7.0 +2021-04-15 09:33:12 INFO:  test-node.js tfjs version: 3.4.0 +2021-04-15 09:33:12 STATE: test-node.js passed: set backend: tensorflow +2021-04-15 09:33:12 STATE: test-node.js passed: load models +2021-04-15 09:33:12 STATE: test-node.js result: defined models: 12 loaded models: 6 +2021-04-15 09:33:12 STATE: test-node.js passed: warmup: none default +2021-04-15 09:33:13 STATE: test-node.js passed: warmup: face default +2021-04-15 09:33:13 DATA:  test-node.js result: face: 1 body: 0 hand: 0 gesture: 2 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.52,"class":"person"} {} +2021-04-15 09:33:13 DATA:  test-node.js result: performance: load: 485 total: 1252 +2021-04-15 09:33:15 STATE: test-node.js passed: warmup: body default +2021-04-15 09:33:15 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17} +2021-04-15 09:33:15 DATA:  test-node.js result: performance: load: 485 total: 1305 +2021-04-15 09:33:15 INFO:  test-node.js test body variants +2021-04-15 09:33:16 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:17 STATE: test-node.js passed: detect: assets/human-sample-body.jpg posenet +2021-04-15 09:33:17 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17} +2021-04-15 09:33:17 DATA:  test-node.js result: performance: load: 485 total: 1246 +2021-04-15 09:33:18 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:20 STATE: test-node.js passed: detect: assets/human-sample-body.jpg efficientpose +2021-04-15 09:33:20 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.75,"keypoints":13} +2021-04-15 09:33:20 DATA:  test-node.js result: performance: load: 485 total: 1851 +2021-04-15 09:33:21 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:22 STATE: test-node.js passed: detect: assets/human-sample-body.jpg blazepose +2021-04-15 09:33:22 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:22 DATA:  test-node.js result: performance: load: 485 total: 1320 +2021-04-15 09:33:23 STATE: test-node.js passed: detect: random default +2021-04-15 09:33:23 DATA:  test-node.js result: face: 0 body: 1 hand: 0 gesture: 1 object: 0 {} {} {"score":1,"keypoints":39} +2021-04-15 09:33:23 DATA:  test-node.js result: performance: load: 485 total: 692 +2021-04-15 09:33:23 INFO:  test-node.js test: first instance +2021-04-15 09:33:24 STATE: test-node.js passed: load image: assets/sample-me.jpg [1,700,700,3] +2021-04-15 09:33:25 STATE: test-node.js passed: detect: assets/sample-me.jpg default +2021-04-15 09:33:25 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:25 DATA:  test-node.js result: performance: load: 485 total: 1038 +2021-04-15 09:33:25 INFO:  test-node.js test: second instance +2021-04-15 09:33:25 STATE: test-node.js passed: load image: assets/sample-me.jpg [1,700,700,3] +2021-04-15 09:33:26 STATE: test-node.js passed: detect: assets/sample-me.jpg default +2021-04-15 09:33:26 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:26 DATA:  test-node.js result: performance: load: 6 total: 1200 +2021-04-15 09:33:26 INFO:  test-node.js test: concurrent +2021-04-15 09:33:26 STATE: test-node.js passed: load image: assets/human-sample-face.jpg [1,256,256,3] +2021-04-15 09:33:26 STATE: test-node.js passed: load image: assets/human-sample-face.jpg [1,256,256,3] +2021-04-15 09:33:27 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:28 STATE: test-node.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-face.jpg default +2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 485 total: 4406 +2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-face.jpg default +2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 6 total: 4407 +2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-body.jpg default +2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 485 total: 4406 +2021-04-15 09:33:33 STATE: test-node.js passed: detect: assets/human-sample-body.jpg default +2021-04-15 09:33:33 DATA:  test-node.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:33 DATA:  test-node.js result: performance: load: 6 total: 4407 +2021-04-15 09:33:33 INFO:  test-node.js test complete: 21236 ms +2021-04-15 09:33:33 INFO:  test-node-gpu.js start +2021-04-15 09:33:33 WARN:  test-node-gpu.js stderr: 2021-04-15 09:33:33.862585: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory +2021-04-15 09:33:33 WARN:  test-node-gpu.js stderr: 2021-04-15 09:33:33.916618: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory +2021-04-15 09:33:33 WARN:  test-node-gpu.js stderr: 2021-04-15 09:33:33.916711: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (wyse): /proc/driver/nvidia/version does not exist +2021-04-15 09:33:34 STATE: test-node-gpu.js passed: create human +2021-04-15 09:33:34 INFO:  test-node-gpu.js human version: 1.5.2 +2021-04-15 09:33:34 INFO:  test-node-gpu.js platform: linux x64 agent: NodeJS v15.7.0 +2021-04-15 09:33:34 INFO:  test-node-gpu.js tfjs version: 3.4.0 +2021-04-15 09:33:34 STATE: test-node-gpu.js passed: set backend: tensorflow +2021-04-15 09:33:34 STATE: test-node-gpu.js passed: load models +2021-04-15 09:33:34 STATE: test-node-gpu.js result: defined models: 12 loaded models: 6 +2021-04-15 09:33:34 STATE: test-node-gpu.js passed: warmup: none default +2021-04-15 09:33:35 STATE: test-node-gpu.js passed: warmup: face default +2021-04-15 09:33:35 DATA:  test-node-gpu.js result: face: 1 body: 0 hand: 0 gesture: 2 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.52,"class":"person"} {} +2021-04-15 09:33:35 DATA:  test-node-gpu.js result: performance: load: 464 total: 1274 +2021-04-15 09:33:37 STATE: test-node-gpu.js passed: warmup: body default +2021-04-15 09:33:37 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17} +2021-04-15 09:33:37 DATA:  test-node-gpu.js result: performance: load: 464 total: 1295 +2021-04-15 09:33:37 INFO:  test-node-gpu.js test body variants +2021-04-15 09:33:38 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:39 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg posenet +2021-04-15 09:33:39 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.95,"keypoints":17} +2021-04-15 09:33:39 DATA:  test-node-gpu.js result: performance: load: 464 total: 1285 +2021-04-15 09:33:40 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:42 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg efficientpose +2021-04-15 09:33:42 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":0.75,"keypoints":13} +2021-04-15 09:33:42 DATA:  test-node-gpu.js result: performance: load: 464 total: 2037 +2021-04-15 09:33:43 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:44 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg blazepose +2021-04-15 09:33:44 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:44 DATA:  test-node-gpu.js result: performance: load: 464 total: 1433 +2021-04-15 09:33:45 STATE: test-node-gpu.js passed: detect: random default +2021-04-15 09:33:45 DATA:  test-node-gpu.js result: face: 0 body: 1 hand: 0 gesture: 1 object: 0 {} {} {"score":1,"keypoints":39} +2021-04-15 09:33:45 DATA:  test-node-gpu.js result: performance: load: 464 total: 714 +2021-04-15 09:33:45 INFO:  test-node-gpu.js test: first instance +2021-04-15 09:33:46 STATE: test-node-gpu.js passed: load image: assets/sample-me.jpg [1,700,700,3] +2021-04-15 09:33:47 STATE: test-node-gpu.js passed: detect: assets/sample-me.jpg default +2021-04-15 09:33:47 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:47 DATA:  test-node-gpu.js result: performance: load: 464 total: 1050 +2021-04-15 09:33:47 INFO:  test-node-gpu.js test: second instance +2021-04-15 09:33:47 STATE: test-node-gpu.js passed: load image: assets/sample-me.jpg [1,700,700,3] +2021-04-15 09:33:48 STATE: test-node-gpu.js passed: detect: assets/sample-me.jpg default +2021-04-15 09:33:48 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 2 {"confidence":1,"age":39.2,"gender":"male"} {"score":0.7,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:48 DATA:  test-node-gpu.js result: performance: load: 4 total: 1028 +2021-04-15 09:33:48 INFO:  test-node-gpu.js test: concurrent +2021-04-15 09:33:48 STATE: test-node-gpu.js passed: load image: assets/human-sample-face.jpg [1,256,256,3] +2021-04-15 09:33:48 STATE: test-node-gpu.js passed: load image: assets/human-sample-face.jpg [1,256,256,3] +2021-04-15 09:33:49 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:50 STATE: test-node-gpu.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-face.jpg default +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 464 total: 4261 +2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-face.jpg default +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 1 {"confidence":1,"age":23.6,"gender":"female"} {"score":0.53,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 4 total: 4261 +2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg default +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 464 total: 4261 +2021-04-15 09:33:55 STATE: test-node-gpu.js passed: detect: assets/human-sample-body.jpg default +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 3 {"confidence":1,"age":28.5,"gender":"female"} {"score":0.86,"class":"person"} {"score":1,"keypoints":39} +2021-04-15 09:33:55 DATA:  test-node-gpu.js result: performance: load: 4 total: 4261 +2021-04-15 09:33:55 INFO:  test-node-gpu.js test complete: 21151 ms +2021-04-15 09:33:55 INFO:  test-node-wasm.js start +2021-04-15 09:33:55 STATE: test-node-wasm.js passed: model server: http://localhost:10030/models/ +2021-04-15 09:33:55 STATE: test-node-wasm.js passed: create human +2021-04-15 09:33:55 INFO:  test-node-wasm.js human version: 1.5.2 +2021-04-15 09:33:55 INFO:  test-node-wasm.js platform: linux x64 agent: NodeJS v15.7.0 +2021-04-15 09:33:55 INFO:  test-node-wasm.js tfjs version: 3.4.0 +2021-04-15 09:33:56 STATE: test-node-wasm.js passed: set backend: wasm +2021-04-15 09:33:56 STATE: test-node-wasm.js passed: load models +2021-04-15 09:33:56 STATE: test-node-wasm.js result: defined models: 12 loaded models: 5 +2021-04-15 09:33:56 STATE: test-node-wasm.js passed: warmup: none default +2021-04-15 09:33:56 ERROR: test-node-wasm.js failed: warmup: face default +2021-04-15 09:33:56 ERROR: test-node-wasm.js failed: warmup: body default +2021-04-15 09:33:56 INFO:  test-node-wasm.js test body variants +2021-04-15 09:33:58 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:34:01 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg posenet +2021-04-15 09:34:01 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":0.93,"keypoints":17} +2021-04-15 09:34:01 DATA:  test-node-wasm.js result: performance: load: 827 total: 2835 +2021-04-15 09:34:02 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:34:08 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg efficientpose +2021-04-15 09:34:08 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":0.5,"keypoints":16} +2021-04-15 09:34:08 DATA:  test-node-wasm.js result: performance: load: 827 total: 5024 +2021-04-15 09:34:09 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:34:12 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg blazepose +2021-04-15 09:34:12 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:12 DATA:  test-node-wasm.js result: performance: load: 827 total: 2437 +2021-04-15 09:34:13 STATE: test-node-wasm.js passed: detect: random default +2021-04-15 09:34:13 DATA:  test-node-wasm.js result: face: 0 body: 1 hand: 0 gesture: 1 object: 0 {} {} {"score":1,"keypoints":39} +2021-04-15 09:34:13 DATA:  test-node-wasm.js result: performance: load: 827 total: 1384 +2021-04-15 09:34:13 INFO:  test-node-wasm.js test: first instance +2021-04-15 09:34:14 STATE: test-node-wasm.js passed: load image: assets/sample-me.jpg [1,700,700,3] +2021-04-15 09:34:16 STATE: test-node-wasm.js passed: detect: assets/sample-me.jpg default +2021-04-15 09:34:16 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":39.2,"gender":"male"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:16 DATA:  test-node-wasm.js result: performance: load: 827 total: 2091 +2021-04-15 09:34:16 INFO:  test-node-wasm.js test: second instance +2021-04-15 09:34:17 STATE: test-node-wasm.js passed: load image: assets/sample-me.jpg [1,700,700,3] +2021-04-15 09:34:19 STATE: test-node-wasm.js passed: detect: assets/sample-me.jpg default +2021-04-15 09:34:19 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":39.2,"gender":"male"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:19 DATA:  test-node-wasm.js result: performance: load: 3 total: 2065 +2021-04-15 09:34:19 INFO:  test-node-wasm.js test: concurrent +2021-04-15 09:34:19 STATE: test-node-wasm.js passed: load image: assets/human-sample-face.jpg [1,256,256,3] +2021-04-15 09:34:19 STATE: test-node-wasm.js passed: load image: assets/human-sample-face.jpg [1,256,256,3] +2021-04-15 09:34:21 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:34:23 STATE: test-node-wasm.js passed: load image: assets/human-sample-body.jpg [1,1200,1200,3] +2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-face.jpg default +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":23.6,"gender":"female"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 827 total: 7839 +2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-face.jpg default +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 3 object: 0 {"confidence":1,"age":23.6,"gender":"female"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 3 total: 7839 +2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg default +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 827 total: 7839 +2021-04-15 09:34:31 STATE: test-node-wasm.js passed: detect: assets/human-sample-body.jpg default +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: face: 1 body: 1 hand: 0 gesture: 2 object: 0 {"confidence":1,"age":28.5,"gender":"female"} {} {"score":1,"keypoints":39} +2021-04-15 09:34:31 DATA:  test-node-wasm.js result: performance: load: 3 total: 7839 +2021-04-15 09:34:31 INFO:  test-node-wasm.js test complete: 35570 ms +2021-04-15 09:34:31 INFO:  status: {"passed":74,"failed":2}