diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a9ce4d7..da3b380b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # @vladmandic/human -Version: **1.9.3** +Version: **1.9.4** 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,12 @@ Repository: **** ## Changelog -### **HEAD -> main** 2021/05/26 mandic00@live.com +### **1.9.4** 2021/05/27 mandic00@live.com + +### **origin/main** 2021/05/26 mandic00@live.com + +- webhint and lighthouse optimizations - add camera startup diag messages - implemented unified result.persons that combines face, body and hands for each person - added experimental results interpolation for smooth draw operations diff --git a/dist/human.esm-nobundle.js b/dist/human.esm-nobundle.js index b51a2e8f..523bfaa5 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 $A="1.9.3";var m0,z0,v0,r0,i0,h0,Y0,E0,J0,U0,K0,G0,X2=class{constructor(e={}){U(this,m0,void 0);U(this,z0,void 0);U(this,v0,void 0);U(this,r0,void 0);U(this,i0,void 0);U(this,h0,void 0);this.analyze=(...e)=>{if(!H(this,z0))return;let t=this.tf.engine().state.numTensors,n=H(this,m0);K(this,m0,t);let o=t-n;o!==0&&b(...e,o)};U(this,Y0,e=>{if(!H(this,v0))return null;if(!e)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(e instanceof a.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(t){return"backend not loaded"}return null});U(this,E0,async(e=!1)=>{var t;if(this.config.backend&&this.config.backend.length>0&&e||this.tf.getBackend()!==this.config.backend){let n=W();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&this.config.debug&&b("running inside web worker"),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&&b("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&b("wasm path:",this.config.wasmPath),typeof((t=this.tf)==null?void 0:t.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let o=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),i=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&b(`wasm execution: ${o?"SIMD":"no SIMD"} ${i?"multithreaded":"singlethreaded"}`),this.config.debug&&!o&&b("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&oA();try{await this.tf.setBackend(this.config.backend)}catch(o){b("error: cannot set backend:",this.config.backend,o)}}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_CPU_FORWARD",!0),a.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),typeof this.config.deallocate!="undefined"&&(b("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0));let o=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&b(`gl version:${o.getParameter(o.VERSION)} renderer:${o.getParameter(o.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(W()-n)}});U(this,J0,async e=>{if(this.config.cacheSensitivity===0)return!1;let t=32,n=e.resizeBilinear([Math.trunc(e.shape[1]/t),Math.trunc(e.shape[2]/t)]),o=n.dataSync(),i=0;for(let y=0;y10*this.config.cacheSensitivity?0:r),s});U(this,U0,async()=>{let e=(o,i="application/octet-stream")=>fetch(`data:${i};base64,${o}`).then(r=>r.blob()),t,n;switch(this.config.warmup){case"face":t=await e(C0);break;case"full":t=await e(B0);break;default:t=null}if(t){let o=await createImageBitmap(t);n=await this.detect(o,this.config),o.close()}return n});U(this,K0,async()=>new Promise(e=>{let t,n=0;switch(this.config.warmup){case"face":n=256,t="data:image/jpeg;base64,"+C0;break;case"full":case"body":n=1200,t="data:image/jpeg;base64,"+B0;break;default:t=null}let o=new Image;o.onload=async()=>{let i=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(n,n):document.createElement("canvas");i.width=o.naturalWidth,i.height=o.naturalHeight;let r=i.getContext("2d");r==null||r.drawImage(o,0,0);let s=await this.detect(i,this.config);e(s)},t?o.src=t:e(null)}));U(this,G0,async()=>{let e=o=>Buffer.from(o,"base64"),t;if(this.config.warmup==="face"&&(t=e(C0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(t=e(B0)),!t)return null;let n;if(typeof a.node!="undefined"){let o=a.node.decodeJpeg(t),i=o.expandDims(0);this.tf.dispose(o),n=await this.detect(i,this.config),this.tf.dispose(i)}else this.config.debug&&b("Warmup tfjs-node not loaded");return n});this.tf=a,this.draw=U5,this.version=$A,this.config=F(Q5,e),this.state="idle",K(this,m0,0),K(this,z0,!1),K(this,v0,!1),K(this,r0,!0),K(this,h0,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,centernet:null,faceres:null},this.image=t=>B5(t,this.config),this.classes={facemesh:s5,emotion:x5,faceres:f5,body:this.config.body.modelPath.includes("posenet")?M5:N5,hand:w5,nanodet:V5,centernet:C5},this.faceTriangulation=hA,this.faceUVMap=uA,this.sysinfo=_5(),K(this,i0,1)}similarity(e,t){return c5(e,t)}enhance(e){return d5(e)}match(e,t,n=0){return gA(e,t,n)}async load(e={}){this.state="load";let t=W();e&&(this.config=F(this.config,e)),H(this,r0)&&(this.config.debug&&b(`version: ${this.version}`),this.config.debug&&b(`tfjs version: ${this.tf.version_core}`),this.config.debug&&b("platform:",this.sysinfo.platform),this.config.debug&&b("agent:",this.sysinfo.agent),await H(this,E0).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&b("configuration:",this.config),this.config.debug&&b("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.emotion,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.nanodet,this.models.centernet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?o5(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?a5(this.config):null),this.models.handpose||(this.config.hand.enabled?S5(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?P5(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?W5(this.config):null),this.models.nanodet||(this.config.object.enabled&&this.config.object.modelPath.includes("nanodet")?L5(this.config):null),this.models.centernet||(this.config.object.enabled&&this.config.object.modelPath.includes("centernet")?F5(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?l5(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await o5(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await a5(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await S5(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await P5(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await W5(this.config)),this.config.object.enabled&&!this.models.nanodet&&this.config.object.modelPath.includes("nanodet")&&(this.models.nanodet=await L5(this.config)),this.config.object.enabled&&!this.models.centernet&&this.config.object.modelPath.includes("centernet")&&(this.models.centernet=await F5(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await l5(this.config))),H(this,r0)&&(this.config.debug&&b("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),K(this,r0,!1));let n=Math.trunc(W()-t);n>(this.perf.load||0)&&(this.perf.load=n)}async detect(e,t={}){return new Promise(async n=>{this.state="config";let o;this.config=F(this.config,t),this.state="check";let i=H(this,Y0).call(this,e);i&&(b(i,e),n({error:i}));let r=W();await H(this,E0).call(this),await this.load(),o=W();let s=B5(e,this.config);if(!s||!s.tensor){b("could not convert input to tensor"),n({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(W()-o),this.analyze("Get Image:"),o=W(),this.config.skipFrame=await H(this,J0).call(this,s.tensor),this.perf.frames||(this.perf.frames=0),this.perf.cached||(this.perf.cached=0),this.perf.frames++,this.config.skipFrame&&this.perf.cached++,this.perf.changed=Math.trunc(W()-o),this.analyze("Check Changed:");let y,x,d,l,f;this.config.async?(y=this.config.face.enabled?m5(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",o=W(),y=this.config.face.enabled?await m5(this,s.tensor):[],f=Math.trunc(W()-o),f>0&&(this.perf.face=f)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?x=this.config.body.enabled?T5(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(x=this.config.body.enabled?k5(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",o=W(),this.config.body.modelPath.includes("posenet")?x=this.config.body.enabled?await T5(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(x=this.config.body.enabled?await k5(s.tensor,this.config):[]),f=Math.trunc(W()-o),f>0&&(this.perf.body=f)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(d=this.config.hand.enabled?j5(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",o=W(),d=this.config.hand.enabled?await j5(s.tensor,this.config):[],f=Math.trunc(W()-o),f>0&&(this.perf.hand=f)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(this.config.object.modelPath.includes("nanodet")?l=this.config.object.enabled?Z5(s.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(l=this.config.object.enabled?q5(s.tensor,this.config):[]),this.perf.object&&delete this.perf.object):(this.state="run:object",o=W(),this.config.object.modelPath.includes("nanodet")?l=this.config.object.enabled?await Z5(s.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(l=this.config.object.enabled?await q5(s.tensor,this.config):[]),f=Math.trunc(W()-o),f>0&&(this.perf.object=f)),this.analyze("End Object:"),this.config.async&&([y,x,d,l]=await Promise.all([y,x,d,l]));let p=[];this.config.gesture.enabled&&(o=W(),p=[...CA(y),...qA(x),...YA(d),...BA(y)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(W()-o)),this.perf.total=Math.trunc(W()-r),this.state="idle";let v={face:y,body:x,hand:d,gesture:p,object:l,performance:this.perf,canvas:s.canvas,timestamp:Date.now(),get persons(){var c;return _A(y,x,d,p,(c=s==null?void 0:s.tensor)==null?void 0:c.shape)}};a.dispose(s.tensor),n(v)})}async warmup(e={}){let t=W();if(e&&(this.config=F(this.config,e)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let n;typeof createImageBitmap=="function"?n=await H(this,U0).call(this):typeof Image!="undefined"?n=await H(this,K0).call(this):n=await H(this,G0).call(this);let o=W();return this.config.debug&&b("Warmup",this.config.warmup,Math.round(o-t),"ms",n),n}};m0=new WeakMap,z0=new WeakMap,v0=new WeakMap,r0=new WeakMap,i0=new WeakMap,h0=new WeakMap,Y0=new WeakMap,E0=new WeakMap,J0=new WeakMap,U0=new WeakMap,K0=new WeakMap,G0=new WeakMap;export{X2 as Human,X2 as default}; +2Q==`;var $A="1.9.4";var m0,z0,v0,r0,i0,h0,Y0,E0,J0,U0,K0,G0,X2=class{constructor(e={}){U(this,m0,void 0);U(this,z0,void 0);U(this,v0,void 0);U(this,r0,void 0);U(this,i0,void 0);U(this,h0,void 0);this.analyze=(...e)=>{if(!H(this,z0))return;let t=this.tf.engine().state.numTensors,n=H(this,m0);K(this,m0,t);let o=t-n;o!==0&&b(...e,o)};U(this,Y0,e=>{if(!H(this,v0))return null;if(!e)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(e instanceof a.Tensor))return"input must be a tensor";try{this.tf.getBackend()}catch(t){return"backend not loaded"}return null});U(this,E0,async(e=!1)=>{var t;if(this.config.backend&&this.config.backend.length>0&&e||this.tf.getBackend()!==this.config.backend){let n=W();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&this.config.debug&&b("running inside web worker"),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&&b("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&b("wasm path:",this.config.wasmPath),typeof((t=this.tf)==null?void 0:t.setWasmPaths)!="undefined")this.tf.setWasmPaths(this.config.wasmPath);else throw new Error("Human: WASM backend is not loaded");let o=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),i=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&b(`wasm execution: ${o?"SIMD":"no SIMD"} ${i?"multithreaded":"singlethreaded"}`),this.config.debug&&!o&&b("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&oA();try{await this.tf.setBackend(this.config.backend)}catch(o){b("error: cannot set backend:",this.config.backend,o)}}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_CPU_FORWARD",!0),a.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),typeof this.config.deallocate!="undefined"&&(b("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0));let o=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&b(`gl version:${o.getParameter(o.VERSION)} renderer:${o.getParameter(o.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(W()-n)}});U(this,J0,async e=>{if(this.config.cacheSensitivity===0)return!1;let t=32,n=e.resizeBilinear([Math.trunc(e.shape[1]/t),Math.trunc(e.shape[2]/t)]),o=n.dataSync(),i=0;for(let y=0;y10*this.config.cacheSensitivity?0:r),s});U(this,U0,async()=>{let e=(o,i="application/octet-stream")=>fetch(`data:${i};base64,${o}`).then(r=>r.blob()),t,n;switch(this.config.warmup){case"face":t=await e(C0);break;case"full":t=await e(B0);break;default:t=null}if(t){let o=await createImageBitmap(t);n=await this.detect(o,this.config),o.close()}return n});U(this,K0,async()=>new Promise(e=>{let t,n=0;switch(this.config.warmup){case"face":n=256,t="data:image/jpeg;base64,"+C0;break;case"full":case"body":n=1200,t="data:image/jpeg;base64,"+B0;break;default:t=null}let o=new Image;o.onload=async()=>{let i=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(n,n):document.createElement("canvas");i.width=o.naturalWidth,i.height=o.naturalHeight;let r=i.getContext("2d");r==null||r.drawImage(o,0,0);let s=await this.detect(i,this.config);e(s)},t?o.src=t:e(null)}));U(this,G0,async()=>{let e=o=>Buffer.from(o,"base64"),t;if(this.config.warmup==="face"&&(t=e(C0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(t=e(B0)),!t)return null;let n;if(typeof a.node!="undefined"){let o=a.node.decodeJpeg(t),i=o.expandDims(0);this.tf.dispose(o),n=await this.detect(i,this.config),this.tf.dispose(i)}else this.config.debug&&b("Warmup tfjs-node not loaded");return n});this.tf=a,this.draw=U5,this.version=$A,this.config=F(Q5,e),this.state="idle",K(this,m0,0),K(this,z0,!1),K(this,v0,!1),K(this,r0,!0),K(this,h0,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,centernet:null,faceres:null},this.image=t=>B5(t,this.config),this.classes={facemesh:s5,emotion:x5,faceres:f5,body:this.config.body.modelPath.includes("posenet")?M5:N5,hand:w5,nanodet:V5,centernet:C5},this.faceTriangulation=hA,this.faceUVMap=uA,this.sysinfo=_5(),K(this,i0,1)}similarity(e,t){return c5(e,t)}enhance(e){return d5(e)}match(e,t,n=0){return gA(e,t,n)}async load(e={}){this.state="load";let t=W();e&&(this.config=F(this.config,e)),H(this,r0)&&(this.config.debug&&b(`version: ${this.version}`),this.config.debug&&b(`tfjs version: ${this.tf.version_core}`),this.config.debug&&b("platform:",this.sysinfo.platform),this.config.debug&&b("agent:",this.sysinfo.agent),await H(this,E0).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&b("configuration:",this.config),this.config.debug&&b("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.emotion,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.nanodet,this.models.centernet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?o5(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?a5(this.config):null),this.models.handpose||(this.config.hand.enabled?S5(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?P5(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?W5(this.config):null),this.models.nanodet||(this.config.object.enabled&&this.config.object.modelPath.includes("nanodet")?L5(this.config):null),this.models.centernet||(this.config.object.enabled&&this.config.object.modelPath.includes("centernet")?F5(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?l5(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await o5(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await a5(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await S5(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await P5(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await W5(this.config)),this.config.object.enabled&&!this.models.nanodet&&this.config.object.modelPath.includes("nanodet")&&(this.models.nanodet=await L5(this.config)),this.config.object.enabled&&!this.models.centernet&&this.config.object.modelPath.includes("centernet")&&(this.models.centernet=await F5(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await l5(this.config))),H(this,r0)&&(this.config.debug&&b("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),K(this,r0,!1));let n=Math.trunc(W()-t);n>(this.perf.load||0)&&(this.perf.load=n)}async detect(e,t={}){return new Promise(async n=>{this.state="config";let o;this.config=F(this.config,t),this.state="check";let i=H(this,Y0).call(this,e);i&&(b(i,e),n({error:i}));let r=W();await H(this,E0).call(this),await this.load(),o=W();let s=B5(e,this.config);if(!s||!s.tensor){b("could not convert input to tensor"),n({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(W()-o),this.analyze("Get Image:"),o=W(),this.config.skipFrame=await H(this,J0).call(this,s.tensor),this.perf.frames||(this.perf.frames=0),this.perf.cached||(this.perf.cached=0),this.perf.frames++,this.config.skipFrame&&this.perf.cached++,this.perf.changed=Math.trunc(W()-o),this.analyze("Check Changed:");let y,x,d,l,f;this.config.async?(y=this.config.face.enabled?m5(this,s.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",o=W(),y=this.config.face.enabled?await m5(this,s.tensor):[],f=Math.trunc(W()-o),f>0&&(this.perf.face=f)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?x=this.config.body.enabled?T5(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(x=this.config.body.enabled?k5(s.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",o=W(),this.config.body.modelPath.includes("posenet")?x=this.config.body.enabled?await T5(s.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(x=this.config.body.enabled?await k5(s.tensor,this.config):[]),f=Math.trunc(W()-o),f>0&&(this.perf.body=f)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(d=this.config.hand.enabled?j5(s.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",o=W(),d=this.config.hand.enabled?await j5(s.tensor,this.config):[],f=Math.trunc(W()-o),f>0&&(this.perf.hand=f)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(this.config.object.modelPath.includes("nanodet")?l=this.config.object.enabled?Z5(s.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(l=this.config.object.enabled?q5(s.tensor,this.config):[]),this.perf.object&&delete this.perf.object):(this.state="run:object",o=W(),this.config.object.modelPath.includes("nanodet")?l=this.config.object.enabled?await Z5(s.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(l=this.config.object.enabled?await q5(s.tensor,this.config):[]),f=Math.trunc(W()-o),f>0&&(this.perf.object=f)),this.analyze("End Object:"),this.config.async&&([y,x,d,l]=await Promise.all([y,x,d,l]));let p=[];this.config.gesture.enabled&&(o=W(),p=[...CA(y),...qA(x),...YA(d),...BA(y)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(W()-o)),this.perf.total=Math.trunc(W()-r),this.state="idle";let v={face:y,body:x,hand:d,gesture:p,object:l,performance:this.perf,canvas:s.canvas,timestamp:Date.now(),get persons(){var c;return _A(y,x,d,p,(c=s==null?void 0:s.tensor)==null?void 0:c.shape)}};a.dispose(s.tensor),n(v)})}async warmup(e={}){let t=W();if(e&&(this.config=F(this.config,e)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let n;typeof createImageBitmap=="function"?n=await H(this,U0).call(this):typeof Image!="undefined"?n=await H(this,K0).call(this):n=await H(this,G0).call(this);let o=W();return this.config.debug&&b("Warmup",this.config.warmup,Math.round(o-t),"ms",n),n}};m0=new WeakMap,z0=new WeakMap,v0=new WeakMap,r0=new WeakMap,i0=new WeakMap,h0=new WeakMap,Y0=new WeakMap,E0=new WeakMap,J0=new WeakMap,U0=new WeakMap,K0=new WeakMap,G0=new WeakMap;export{X2 as Human,X2 as default}; //# sourceMappingURL=human.esm-nobundle.js.map diff --git a/dist/human.esm.js b/dist/human.esm.js index 4a0cdde6..a44b08c1 100644 --- a/dist/human.esm.js +++ b/dist/human.esm.js @@ -4974,7 +4974,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var u9="1.9.3";var au,rp,sp,Li,Wi,ru,_0,ip,P0,L0,W0,B0,hoe=class{constructor(t={}){Zn(this,au,void 0);Zn(this,rp,void 0);Zn(this,sp,void 0);Zn(this,Li,void 0);Zn(this,Wi,void 0);Zn(this,ru,void 0);this.analyze=(...t)=>{if(!on(this,rp))return;let n=this.tf.engine().state.numTensors,a=on(this,au);ya(this,au,n);let r=n-a;r!==0&&ce(...t,r)};Zn(this,_0,t=>{if(!on(this,sp))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof Le))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Zn(this,ip,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let a=at();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&this.config.debug&&ce("running inside web worker"),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&&ce("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&ce("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 r=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&ce(`wasm execution: ${r?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!r&&ce("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&fk();try{await this.tf.setBackend(this.config.backend)}catch(r){ce("error: cannot set backend:",this.config.backend,r)}}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_CPU_FORWARD",!0),la.set("WEBGL_FORCE_F16_TEXTURES",!0),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),typeof this.config.deallocate!="undefined"&&(ce("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0));let r=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&ce(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(at()-a)}});Zn(this,P0,async t=>{if(this.config.cacheSensitivity===0)return!1;let n=32,a=t.resizeBilinear([Math.trunc(t.shape[1]/n),Math.trunc(t.shape[2]/n)]),r=a.dataSync(),s=0;for(let l=0;l10*this.config.cacheSensitivity?0:i),o});Zn(this,L0,async()=>{let t=(r,s="application/octet-stream")=>fetch(`data:${s};base64,${r}`).then(i=>i.blob()),n,a;switch(this.config.warmup){case"face":n=await t(z0);break;case"full":n=await t(O0);break;default:n=null}if(n){let r=await createImageBitmap(n);a=await this.detect(r,this.config),r.close()}return a});Zn(this,W0,async()=>new Promise(t=>{let n,a=0;switch(this.config.warmup){case"face":a=256,n="data:image/jpeg;base64,"+z0;break;case"full":case"body":a=1200,n="data:image/jpeg;base64,"+O0;break;default:n=null}let r=new Image;r.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(a,a):document.createElement("canvas");s.width=r.naturalWidth,s.height=r.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(r,0,0);let o=await this.detect(s,this.config);t(o)},n?r.src=n:t(null)}));Zn(this,B0,async()=>{let t=r=>Buffer.from(r,"base64"),n;if(this.config.warmup==="face"&&(n=t(z0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(O0)),!n)return null;let a;if(typeof void 0!="undefined"){let r=(void 0).decodeJpeg(n),s=r.expandDims(0);this.tf.dispose(r),a=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&ce("Warmup tfjs-node not loaded");return a});this.tf=Zd,this.draw=zg,this.version=u9,this.config=$n(Kg,t),this.state="idle",ya(this,au,0),ya(this,rp,!1),ya(this,sp,!1),ya(this,Li,!0),ya(this,ru,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,centernet:null,faceres:null},this.image=n=>Fg(n,this.config),this.classes={facemesh:q2,emotion:Y2,faceres:ng,body:this.config.body.modelPath.includes("posenet")?pg:vg,hand:gg,nanodet:Ng,centernet:Mg},this.faceTriangulation=Nk,this.faceUVMap=Tk,this.sysinfo=Zg(),ya(this,Wi,1)}similarity(t,n){return eg(t,n)}enhance(t){return tg(t)}match(t,n,a=0){return Rk(t,n,a)}async load(t={}){this.state="load";let n=at();t&&(this.config=$n(this.config,t)),on(this,Li)&&(this.config.debug&&ce(`version: ${this.version}`),this.config.debug&&ce(`tfjs version: ${this.tf.version_core}`),this.config.debug&&ce("platform:",this.sysinfo.platform),this.config.debug&&ce("agent:",this.sysinfo.agent),await on(this,ip).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&ce("configuration:",this.config),this.config.debug&&ce("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.emotion,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.nanodet,this.models.centernet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?G2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Z2(this.config):null),this.models.handpose||(this.config.hand.enabled?yg(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?dg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?xg(this.config):null),this.models.nanodet||(this.config.object.enabled&&this.config.object.modelPath.includes("nanodet")?Ig(this.config):null),this.models.centernet||(this.config.object.enabled&&this.config.object.modelPath.includes("centernet")?Cg(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Q2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await G2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Z2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await yg(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await dg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await xg(this.config)),this.config.object.enabled&&!this.models.nanodet&&this.config.object.modelPath.includes("nanodet")&&(this.models.nanodet=await Ig(this.config)),this.config.object.enabled&&!this.models.centernet&&this.config.object.modelPath.includes("centernet")&&(this.models.centernet=await Cg(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Q2(this.config))),on(this,Li)&&(this.config.debug&&ce("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),ya(this,Li,!1));let a=Math.trunc(at()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async detect(t,n={}){return new Promise(async a=>{this.state="config";let r;this.config=$n(this.config,n),this.state="check";let s=on(this,_0).call(this,t);s&&(ce(s,t),a({error:s}));let i=at();await on(this,ip).call(this),await this.load(),r=at();let o=Fg(t,this.config);if(!o||!o.tensor){ce("could not convert input to tensor"),a({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(at()-r),this.analyze("Get Image:"),r=at(),this.config.skipFrame=await on(this,P0).call(this,o.tensor),this.perf.frames||(this.perf.frames=0),this.perf.cached||(this.perf.cached=0),this.perf.frames++,this.config.skipFrame&&this.perf.cached++,this.perf.changed=Math.trunc(at()-r),this.analyze("Check Changed:");let l,u,d,p,c;this.config.async?(l=this.config.face.enabled?ag(this,o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",r=at(),l=this.config.face.enabled?await ag(this,o.tensor):[],c=Math.trunc(at()-r),c>0&&(this.perf.face=c)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?bg(o.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",r=at(),this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?await ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?await bg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.body=c)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(d=this.config.hand.enabled?Ag(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",r=at(),d=this.config.hand.enabled?await Ag(o.tensor,this.config):[],c=Math.trunc(at()-r),c>0&&(this.perf.hand=c)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?Rg(o.tensor,this.config):[]),this.perf.object&&delete this.perf.object):(this.state="run:object",r=at(),this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?await Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?await Rg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.object=c)),this.analyze("End Object:"),this.config.async&&([l,u,d,p]=await Promise.all([l,u,d,p]));let h=[];this.config.gesture.enabled&&(r=at(),h=[...Qk(l),...Jk(u),...t9(d),...e9(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(at()-r)),this.perf.total=Math.trunc(at()-i),this.state="idle";let m={face:l,body:u,hand:d,gesture:h,object:p,performance:this.perf,canvas:o.canvas,timestamp:Date.now(),get persons(){var f;return l9(l,u,d,h,(f=o==null?void 0:o.tensor)==null?void 0:f.shape)}};Ee(o.tensor),a(m)})}async warmup(t={}){let n=at();if(t&&(this.config=$n(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let a;typeof createImageBitmap=="function"?a=await on(this,L0).call(this):typeof Image!="undefined"?a=await on(this,W0).call(this):a=await on(this,B0).call(this);let r=at();return this.config.debug&&ce("Warmup",this.config.warmup,Math.round(r-n),"ms",a),a}};au=new WeakMap,rp=new WeakMap,sp=new WeakMap,Li=new WeakMap,Wi=new WeakMap,ru=new WeakMap,_0=new WeakMap,ip=new WeakMap,P0=new WeakMap,L0=new WeakMap,W0=new WeakMap,B0=new WeakMap;export{hoe as Human,hoe as default}; +2Q==`;var u9="1.9.4";var au,rp,sp,Li,Wi,ru,_0,ip,P0,L0,W0,B0,hoe=class{constructor(t={}){Zn(this,au,void 0);Zn(this,rp,void 0);Zn(this,sp,void 0);Zn(this,Li,void 0);Zn(this,Wi,void 0);Zn(this,ru,void 0);this.analyze=(...t)=>{if(!on(this,rp))return;let n=this.tf.engine().state.numTensors,a=on(this,au);ya(this,au,n);let r=n-a;r!==0&&ce(...t,r)};Zn(this,_0,t=>{if(!on(this,sp))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof Le))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Zn(this,ip,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let a=at();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&this.config.debug&&ce("running inside web worker"),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&&ce("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&ce("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 r=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&ce(`wasm execution: ${r?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!r&&ce("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&fk();try{await this.tf.setBackend(this.config.backend)}catch(r){ce("error: cannot set backend:",this.config.backend,r)}}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_CPU_FORWARD",!0),la.set("WEBGL_FORCE_F16_TEXTURES",!0),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),typeof this.config.deallocate!="undefined"&&(ce("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0));let r=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&ce(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(at()-a)}});Zn(this,P0,async t=>{if(this.config.cacheSensitivity===0)return!1;let n=32,a=t.resizeBilinear([Math.trunc(t.shape[1]/n),Math.trunc(t.shape[2]/n)]),r=a.dataSync(),s=0;for(let l=0;l10*this.config.cacheSensitivity?0:i),o});Zn(this,L0,async()=>{let t=(r,s="application/octet-stream")=>fetch(`data:${s};base64,${r}`).then(i=>i.blob()),n,a;switch(this.config.warmup){case"face":n=await t(z0);break;case"full":n=await t(O0);break;default:n=null}if(n){let r=await createImageBitmap(n);a=await this.detect(r,this.config),r.close()}return a});Zn(this,W0,async()=>new Promise(t=>{let n,a=0;switch(this.config.warmup){case"face":a=256,n="data:image/jpeg;base64,"+z0;break;case"full":case"body":a=1200,n="data:image/jpeg;base64,"+O0;break;default:n=null}let r=new Image;r.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(a,a):document.createElement("canvas");s.width=r.naturalWidth,s.height=r.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(r,0,0);let o=await this.detect(s,this.config);t(o)},n?r.src=n:t(null)}));Zn(this,B0,async()=>{let t=r=>Buffer.from(r,"base64"),n;if(this.config.warmup==="face"&&(n=t(z0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(O0)),!n)return null;let a;if(typeof void 0!="undefined"){let r=(void 0).decodeJpeg(n),s=r.expandDims(0);this.tf.dispose(r),a=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&ce("Warmup tfjs-node not loaded");return a});this.tf=Zd,this.draw=zg,this.version=u9,this.config=$n(Kg,t),this.state="idle",ya(this,au,0),ya(this,rp,!1),ya(this,sp,!1),ya(this,Li,!0),ya(this,ru,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,centernet:null,faceres:null},this.image=n=>Fg(n,this.config),this.classes={facemesh:q2,emotion:Y2,faceres:ng,body:this.config.body.modelPath.includes("posenet")?pg:vg,hand:gg,nanodet:Ng,centernet:Mg},this.faceTriangulation=Nk,this.faceUVMap=Tk,this.sysinfo=Zg(),ya(this,Wi,1)}similarity(t,n){return eg(t,n)}enhance(t){return tg(t)}match(t,n,a=0){return Rk(t,n,a)}async load(t={}){this.state="load";let n=at();t&&(this.config=$n(this.config,t)),on(this,Li)&&(this.config.debug&&ce(`version: ${this.version}`),this.config.debug&&ce(`tfjs version: ${this.tf.version_core}`),this.config.debug&&ce("platform:",this.sysinfo.platform),this.config.debug&&ce("agent:",this.sysinfo.agent),await on(this,ip).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&ce("configuration:",this.config),this.config.debug&&ce("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.emotion,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.nanodet,this.models.centernet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?G2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Z2(this.config):null),this.models.handpose||(this.config.hand.enabled?yg(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?dg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?xg(this.config):null),this.models.nanodet||(this.config.object.enabled&&this.config.object.modelPath.includes("nanodet")?Ig(this.config):null),this.models.centernet||(this.config.object.enabled&&this.config.object.modelPath.includes("centernet")?Cg(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Q2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await G2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Z2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await yg(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await dg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await xg(this.config)),this.config.object.enabled&&!this.models.nanodet&&this.config.object.modelPath.includes("nanodet")&&(this.models.nanodet=await Ig(this.config)),this.config.object.enabled&&!this.models.centernet&&this.config.object.modelPath.includes("centernet")&&(this.models.centernet=await Cg(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Q2(this.config))),on(this,Li)&&(this.config.debug&&ce("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),ya(this,Li,!1));let a=Math.trunc(at()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async detect(t,n={}){return new Promise(async a=>{this.state="config";let r;this.config=$n(this.config,n),this.state="check";let s=on(this,_0).call(this,t);s&&(ce(s,t),a({error:s}));let i=at();await on(this,ip).call(this),await this.load(),r=at();let o=Fg(t,this.config);if(!o||!o.tensor){ce("could not convert input to tensor"),a({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(at()-r),this.analyze("Get Image:"),r=at(),this.config.skipFrame=await on(this,P0).call(this,o.tensor),this.perf.frames||(this.perf.frames=0),this.perf.cached||(this.perf.cached=0),this.perf.frames++,this.config.skipFrame&&this.perf.cached++,this.perf.changed=Math.trunc(at()-r),this.analyze("Check Changed:");let l,u,d,p,c;this.config.async?(l=this.config.face.enabled?ag(this,o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",r=at(),l=this.config.face.enabled?await ag(this,o.tensor):[],c=Math.trunc(at()-r),c>0&&(this.perf.face=c)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?bg(o.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",r=at(),this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?await ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?await bg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.body=c)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(d=this.config.hand.enabled?Ag(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",r=at(),d=this.config.hand.enabled?await Ag(o.tensor,this.config):[],c=Math.trunc(at()-r),c>0&&(this.perf.hand=c)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?Rg(o.tensor,this.config):[]),this.perf.object&&delete this.perf.object):(this.state="run:object",r=at(),this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?await Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?await Rg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.object=c)),this.analyze("End Object:"),this.config.async&&([l,u,d,p]=await Promise.all([l,u,d,p]));let h=[];this.config.gesture.enabled&&(r=at(),h=[...Qk(l),...Jk(u),...t9(d),...e9(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(at()-r)),this.perf.total=Math.trunc(at()-i),this.state="idle";let m={face:l,body:u,hand:d,gesture:h,object:p,performance:this.perf,canvas:o.canvas,timestamp:Date.now(),get persons(){var f;return l9(l,u,d,h,(f=o==null?void 0:o.tensor)==null?void 0:f.shape)}};Ee(o.tensor),a(m)})}async warmup(t={}){let n=at();if(t&&(this.config=$n(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let a;typeof createImageBitmap=="function"?a=await on(this,L0).call(this):typeof Image!="undefined"?a=await on(this,W0).call(this):a=await on(this,B0).call(this);let r=at();return this.config.debug&&ce("Warmup",this.config.warmup,Math.round(r-n),"ms",a),a}};au=new WeakMap,rp=new WeakMap,sp=new WeakMap,Li=new WeakMap,Wi=new WeakMap,ru=new WeakMap,_0=new WeakMap,ip=new WeakMap,P0=new WeakMap,L0=new WeakMap,W0=new WeakMap,B0=new WeakMap;export{hoe as Human,hoe as default}; /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/dist/human.js b/dist/human.js index bfebd44f..9fb22a7d 100644 --- a/dist/human.js +++ b/dist/human.js @@ -4974,7 +4974,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var u9="1.9.3";var au,rp,sp,Li,Wi,ru,_0,ip,P0,L0,W0,B0,d9=class{constructor(t={}){Zn(this,au,void 0);Zn(this,rp,void 0);Zn(this,sp,void 0);Zn(this,Li,void 0);Zn(this,Wi,void 0);Zn(this,ru,void 0);this.analyze=(...t)=>{if(!on(this,rp))return;let n=this.tf.engine().state.numTensors,a=on(this,au);ga(this,au,n);let r=n-a;r!==0&&ce(...t,r)};Zn(this,_0,t=>{if(!on(this,sp))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof Le))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Zn(this,ip,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let a=at();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&this.config.debug&&ce("running inside web worker"),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&&ce("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&ce("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 r=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&ce(`wasm execution: ${r?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!r&&ce("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&fk();try{await this.tf.setBackend(this.config.backend)}catch(r){ce("error: cannot set backend:",this.config.backend,r)}}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_CPU_FORWARD",!0),la.set("WEBGL_FORCE_F16_TEXTURES",!0),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),typeof this.config.deallocate!="undefined"&&(ce("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0));let r=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&ce(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(at()-a)}});Zn(this,P0,async t=>{if(this.config.cacheSensitivity===0)return!1;let n=32,a=t.resizeBilinear([Math.trunc(t.shape[1]/n),Math.trunc(t.shape[2]/n)]),r=a.dataSync(),s=0;for(let l=0;l10*this.config.cacheSensitivity?0:i),o});Zn(this,L0,async()=>{let t=(r,s="application/octet-stream")=>fetch(`data:${s};base64,${r}`).then(i=>i.blob()),n,a;switch(this.config.warmup){case"face":n=await t(z0);break;case"full":n=await t(O0);break;default:n=null}if(n){let r=await createImageBitmap(n);a=await this.detect(r,this.config),r.close()}return a});Zn(this,W0,async()=>new Promise(t=>{let n,a=0;switch(this.config.warmup){case"face":a=256,n="data:image/jpeg;base64,"+z0;break;case"full":case"body":a=1200,n="data:image/jpeg;base64,"+O0;break;default:n=null}let r=new Image;r.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(a,a):document.createElement("canvas");s.width=r.naturalWidth,s.height=r.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(r,0,0);let o=await this.detect(s,this.config);t(o)},n?r.src=n:t(null)}));Zn(this,B0,async()=>{let t=r=>Buffer.from(r,"base64"),n;if(this.config.warmup==="face"&&(n=t(z0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(O0)),!n)return null;let a;if(typeof void 0!="undefined"){let r=(void 0).decodeJpeg(n),s=r.expandDims(0);this.tf.dispose(r),a=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&ce("Warmup tfjs-node not loaded");return a});this.tf=Zd,this.draw=zg,this.version=u9,this.config=$n(Kg,t),this.state="idle",ga(this,au,0),ga(this,rp,!1),ga(this,sp,!1),ga(this,Li,!0),ga(this,ru,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,centernet:null,faceres:null},this.image=n=>Fg(n,this.config),this.classes={facemesh:q2,emotion:Y2,faceres:ng,body:this.config.body.modelPath.includes("posenet")?pg:vg,hand:gg,nanodet:Ng,centernet:Mg},this.faceTriangulation=Nk,this.faceUVMap=Tk,this.sysinfo=Zg(),ga(this,Wi,1)}similarity(t,n){return eg(t,n)}enhance(t){return tg(t)}match(t,n,a=0){return Rk(t,n,a)}async load(t={}){this.state="load";let n=at();t&&(this.config=$n(this.config,t)),on(this,Li)&&(this.config.debug&&ce(`version: ${this.version}`),this.config.debug&&ce(`tfjs version: ${this.tf.version_core}`),this.config.debug&&ce("platform:",this.sysinfo.platform),this.config.debug&&ce("agent:",this.sysinfo.agent),await on(this,ip).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&ce("configuration:",this.config),this.config.debug&&ce("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.emotion,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.nanodet,this.models.centernet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?G2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Z2(this.config):null),this.models.handpose||(this.config.hand.enabled?yg(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?dg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?xg(this.config):null),this.models.nanodet||(this.config.object.enabled&&this.config.object.modelPath.includes("nanodet")?Ig(this.config):null),this.models.centernet||(this.config.object.enabled&&this.config.object.modelPath.includes("centernet")?Cg(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Q2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await G2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Z2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await yg(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await dg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await xg(this.config)),this.config.object.enabled&&!this.models.nanodet&&this.config.object.modelPath.includes("nanodet")&&(this.models.nanodet=await Ig(this.config)),this.config.object.enabled&&!this.models.centernet&&this.config.object.modelPath.includes("centernet")&&(this.models.centernet=await Cg(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Q2(this.config))),on(this,Li)&&(this.config.debug&&ce("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),ga(this,Li,!1));let a=Math.trunc(at()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async detect(t,n={}){return new Promise(async a=>{this.state="config";let r;this.config=$n(this.config,n),this.state="check";let s=on(this,_0).call(this,t);s&&(ce(s,t),a({error:s}));let i=at();await on(this,ip).call(this),await this.load(),r=at();let o=Fg(t,this.config);if(!o||!o.tensor){ce("could not convert input to tensor"),a({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(at()-r),this.analyze("Get Image:"),r=at(),this.config.skipFrame=await on(this,P0).call(this,o.tensor),this.perf.frames||(this.perf.frames=0),this.perf.cached||(this.perf.cached=0),this.perf.frames++,this.config.skipFrame&&this.perf.cached++,this.perf.changed=Math.trunc(at()-r),this.analyze("Check Changed:");let l,u,d,p,c;this.config.async?(l=this.config.face.enabled?ag(this,o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",r=at(),l=this.config.face.enabled?await ag(this,o.tensor):[],c=Math.trunc(at()-r),c>0&&(this.perf.face=c)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?bg(o.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",r=at(),this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?await ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?await bg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.body=c)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(d=this.config.hand.enabled?Ag(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",r=at(),d=this.config.hand.enabled?await Ag(o.tensor,this.config):[],c=Math.trunc(at()-r),c>0&&(this.perf.hand=c)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?Rg(o.tensor,this.config):[]),this.perf.object&&delete this.perf.object):(this.state="run:object",r=at(),this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?await Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?await Rg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.object=c)),this.analyze("End Object:"),this.config.async&&([l,u,d,p]=await Promise.all([l,u,d,p]));let h=[];this.config.gesture.enabled&&(r=at(),h=[...Qk(l),...Jk(u),...t9(d),...e9(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(at()-r)),this.perf.total=Math.trunc(at()-i),this.state="idle";let m={face:l,body:u,hand:d,gesture:h,object:p,performance:this.perf,canvas:o.canvas,timestamp:Date.now(),get persons(){var f;return l9(l,u,d,h,(f=o==null?void 0:o.tensor)==null?void 0:f.shape)}};Ee(o.tensor),a(m)})}async warmup(t={}){let n=at();if(t&&(this.config=$n(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let a;typeof createImageBitmap=="function"?a=await on(this,L0).call(this):typeof Image!="undefined"?a=await on(this,W0).call(this):a=await on(this,B0).call(this);let r=at();return this.config.debug&&ce("Warmup",this.config.warmup,Math.round(r-n),"ms",a),a}};au=new WeakMap,rp=new WeakMap,sp=new WeakMap,Li=new WeakMap,Wi=new WeakMap,ru=new WeakMap,_0=new WeakMap,ip=new WeakMap,P0=new WeakMap,L0=new WeakMap,W0=new WeakMap,B0=new WeakMap;return foe;})(); +2Q==`;var u9="1.9.4";var au,rp,sp,Li,Wi,ru,_0,ip,P0,L0,W0,B0,d9=class{constructor(t={}){Zn(this,au,void 0);Zn(this,rp,void 0);Zn(this,sp,void 0);Zn(this,Li,void 0);Zn(this,Wi,void 0);Zn(this,ru,void 0);this.analyze=(...t)=>{if(!on(this,rp))return;let n=this.tf.engine().state.numTensors,a=on(this,au);ga(this,au,n);let r=n-a;r!==0&&ce(...t,r)};Zn(this,_0,t=>{if(!on(this,sp))return null;if(!t)return"input is not defined";if(this.tf.ENV.flags.IS_NODE&&!(t instanceof Le))return"input must be a tensor";try{this.tf.getBackend()}catch(n){return"backend not loaded"}return null});Zn(this,ip,async(t=!1)=>{var n;if(this.config.backend&&this.config.backend.length>0&&t||this.tf.getBackend()!==this.config.backend){let a=at();if(this.state="backend",this.config.backend&&this.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&this.config.debug&&ce("running inside web worker"),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&&ce("setting backend:",this.config.backend),this.config.backend==="wasm"){if(this.config.debug&&ce("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 r=await this.tf.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await this.tf.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");this.config.debug&&ce(`wasm execution: ${r?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),this.config.debug&&!r&&ce("warning: wasm simd support is not enabled")}this.config.backend==="humangl"&&fk();try{await this.tf.setBackend(this.config.backend)}catch(r){ce("error: cannot set backend:",this.config.backend,r)}}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_CPU_FORWARD",!0),la.set("WEBGL_FORCE_F16_TEXTURES",!0),this.tf.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0),typeof this.config.deallocate!="undefined"&&(ce("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),this.tf.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0));let r=await this.tf.backend().getGPGPUContext().gl;this.config.debug&&ce(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await this.tf.ready(),this.perf.backend=Math.trunc(at()-a)}});Zn(this,P0,async t=>{if(this.config.cacheSensitivity===0)return!1;let n=32,a=t.resizeBilinear([Math.trunc(t.shape[1]/n),Math.trunc(t.shape[2]/n)]),r=a.dataSync(),s=0;for(let l=0;l10*this.config.cacheSensitivity?0:i),o});Zn(this,L0,async()=>{let t=(r,s="application/octet-stream")=>fetch(`data:${s};base64,${r}`).then(i=>i.blob()),n,a;switch(this.config.warmup){case"face":n=await t(z0);break;case"full":n=await t(O0);break;default:n=null}if(n){let r=await createImageBitmap(n);a=await this.detect(r,this.config),r.close()}return a});Zn(this,W0,async()=>new Promise(t=>{let n,a=0;switch(this.config.warmup){case"face":a=256,n="data:image/jpeg;base64,"+z0;break;case"full":case"body":a=1200,n="data:image/jpeg;base64,"+O0;break;default:n=null}let r=new Image;r.onload=async()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(a,a):document.createElement("canvas");s.width=r.naturalWidth,s.height=r.naturalHeight;let i=s.getContext("2d");i==null||i.drawImage(r,0,0);let o=await this.detect(s,this.config);t(o)},n?r.src=n:t(null)}));Zn(this,B0,async()=>{let t=r=>Buffer.from(r,"base64"),n;if(this.config.warmup==="face"&&(n=t(z0)),(this.config.warmup==="body"||this.config.warmup==="full")&&(n=t(O0)),!n)return null;let a;if(typeof void 0!="undefined"){let r=(void 0).decodeJpeg(n),s=r.expandDims(0);this.tf.dispose(r),a=await this.detect(s,this.config),this.tf.dispose(s)}else this.config.debug&&ce("Warmup tfjs-node not loaded");return a});this.tf=Zd,this.draw=zg,this.version=u9,this.config=$n(Kg,t),this.state="idle",ga(this,au,0),ga(this,rp,!1),ga(this,sp,!1),ga(this,Li,!0),ga(this,ru,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,centernet:null,faceres:null},this.image=n=>Fg(n,this.config),this.classes={facemesh:q2,emotion:Y2,faceres:ng,body:this.config.body.modelPath.includes("posenet")?pg:vg,hand:gg,nanodet:Ng,centernet:Mg},this.faceTriangulation=Nk,this.faceUVMap=Tk,this.sysinfo=Zg(),ga(this,Wi,1)}similarity(t,n){return eg(t,n)}enhance(t){return tg(t)}match(t,n,a=0){return Rk(t,n,a)}async load(t={}){this.state="load";let n=at();t&&(this.config=$n(this.config,t)),on(this,Li)&&(this.config.debug&&ce(`version: ${this.version}`),this.config.debug&&ce(`tfjs version: ${this.tf.version_core}`),this.config.debug&&ce("platform:",this.sysinfo.platform),this.config.debug&&ce("agent:",this.sysinfo.agent),await on(this,ip).call(this,!0),this.tf.ENV.flags.IS_BROWSER&&(this.config.debug&&ce("configuration:",this.config),this.config.debug&&ce("tf flags:",this.tf.ENV.flags))),this.config.async?[this.models.face,this.models.emotion,this.models.handpose,this.models.posenet,this.models.blazepose,this.models.nanodet,this.models.centernet,this.models.faceres]=await Promise.all([this.models.face||(this.config.face.enabled?G2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?Z2(this.config):null),this.models.handpose||(this.config.hand.enabled?yg(this.config):null),this.models.posenet||(this.config.body.enabled&&this.config.body.modelPath.includes("posenet")?dg(this.config):null),this.models.blazepose||(this.config.body.enabled&&this.config.body.modelPath.includes("blazepose")?xg(this.config):null),this.models.nanodet||(this.config.object.enabled&&this.config.object.modelPath.includes("nanodet")?Ig(this.config):null),this.models.centernet||(this.config.object.enabled&&this.config.object.modelPath.includes("centernet")?Cg(this.config):null),this.models.faceres||(this.config.face.enabled&&this.config.face.description.enabled?Q2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await G2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await Z2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await yg(this.config)),this.config.body.enabled&&!this.models.posenet&&this.config.body.modelPath.includes("posenet")&&(this.models.posenet=await dg(this.config)),this.config.body.enabled&&!this.models.blazepose&&this.config.body.modelPath.includes("blazepose")&&(this.models.blazepose=await xg(this.config)),this.config.object.enabled&&!this.models.nanodet&&this.config.object.modelPath.includes("nanodet")&&(this.models.nanodet=await Ig(this.config)),this.config.object.enabled&&!this.models.centernet&&this.config.object.modelPath.includes("centernet")&&(this.models.centernet=await Cg(this.config)),this.config.face.enabled&&this.config.face.description.enabled&&!this.models.faceres&&(this.models.faceres=await Q2(this.config))),on(this,Li)&&(this.config.debug&&ce("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),ga(this,Li,!1));let a=Math.trunc(at()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async detect(t,n={}){return new Promise(async a=>{this.state="config";let r;this.config=$n(this.config,n),this.state="check";let s=on(this,_0).call(this,t);s&&(ce(s,t),a({error:s}));let i=at();await on(this,ip).call(this),await this.load(),r=at();let o=Fg(t,this.config);if(!o||!o.tensor){ce("could not convert input to tensor"),a({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(at()-r),this.analyze("Get Image:"),r=at(),this.config.skipFrame=await on(this,P0).call(this,o.tensor),this.perf.frames||(this.perf.frames=0),this.perf.cached||(this.perf.cached=0),this.perf.frames++,this.config.skipFrame&&this.perf.cached++,this.perf.changed=Math.trunc(at()-r),this.analyze("Check Changed:");let l,u,d,p,c;this.config.async?(l=this.config.face.enabled?ag(this,o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",r=at(),l=this.config.face.enabled?await ag(this,o.tensor):[],c=Math.trunc(at()-r),c>0&&(this.perf.face=c)),this.analyze("Start Body:"),this.config.async?(this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?bg(o.tensor,this.config):[]),this.perf.body&&delete this.perf.body):(this.state="run:body",r=at(),this.config.body.modelPath.includes("posenet")?u=this.config.body.enabled?await ug(o.tensor,this.config):[]:this.config.body.modelPath.includes("blazepose")&&(u=this.config.body.enabled?await bg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.body=c)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(d=this.config.hand.enabled?Ag(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",r=at(),d=this.config.hand.enabled?await Ag(o.tensor,this.config):[],c=Math.trunc(at()-r),c>0&&(this.perf.hand=c)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.config.async?(this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?Rg(o.tensor,this.config):[]),this.perf.object&&delete this.perf.object):(this.state="run:object",r=at(),this.config.object.modelPath.includes("nanodet")?p=this.config.object.enabled?await Sg(o.tensor,this.config):[]:this.config.object.modelPath.includes("centernet")&&(p=this.config.object.enabled?await Rg(o.tensor,this.config):[]),c=Math.trunc(at()-r),c>0&&(this.perf.object=c)),this.analyze("End Object:"),this.config.async&&([l,u,d,p]=await Promise.all([l,u,d,p]));let h=[];this.config.gesture.enabled&&(r=at(),h=[...Qk(l),...Jk(u),...t9(d),...e9(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(at()-r)),this.perf.total=Math.trunc(at()-i),this.state="idle";let m={face:l,body:u,hand:d,gesture:h,object:p,performance:this.perf,canvas:o.canvas,timestamp:Date.now(),get persons(){var f;return l9(l,u,d,h,(f=o==null?void 0:o.tensor)==null?void 0:f.shape)}};Ee(o.tensor),a(m)})}async warmup(t={}){let n=at();if(t&&(this.config=$n(this.config,t)),!this.config.warmup||this.config.warmup==="none")return{error:"null"};let a;typeof createImageBitmap=="function"?a=await on(this,L0).call(this):typeof Image!="undefined"?a=await on(this,W0).call(this):a=await on(this,B0).call(this);let r=at();return this.config.debug&&ce("Warmup",this.config.warmup,Math.round(r-n),"ms",a),a}};au=new WeakMap,rp=new WeakMap,sp=new WeakMap,Li=new WeakMap,Wi=new WeakMap,ru=new WeakMap,_0=new WeakMap,ip=new WeakMap,P0=new WeakMap,L0=new WeakMap,W0=new WeakMap,B0=new WeakMap;return foe;})(); /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/dist/human.node-gpu.js b/dist/human.node-gpu.js index c05f7e87..185794e0 100644 --- a/dist/human.node-gpu.js +++ b/dist/human.node-gpu.js @@ -19721,7 +19721,7 @@ lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ 2Q==`; // package.json -var version = "1.9.3"; +var version = "1.9.4"; // src/human.ts var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; diff --git a/dist/human.node-wasm.js b/dist/human.node-wasm.js index 14775802..0844344d 100644 --- a/dist/human.node-wasm.js +++ b/dist/human.node-wasm.js @@ -19722,7 +19722,7 @@ lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ 2Q==`; // package.json -var version = "1.9.3"; +var version = "1.9.4"; // src/human.ts var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; diff --git a/dist/human.node.js b/dist/human.node.js index 8efa0720..092efaf5 100644 --- a/dist/human.node.js +++ b/dist/human.node.js @@ -19721,7 +19721,7 @@ lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ 2Q==`; // package.json -var version = "1.9.3"; +var version = "1.9.4"; // src/human.ts var _numTensors, _analyzeMemoryLeaks, _checkSanity, _firstRun, _lastInputSum, _lastCacheDiff, _sanity, _checkBackend, _skipFrame, _warmupBitmap, _warmupCanvas, _warmupNode; diff --git a/server/build.log b/server/build.log index 95e62130..709404c5 100644 --- a/server/build.log +++ b/server/build.log @@ -1,17 +1,17 @@ -2021-05-26 08:51:59 INFO:  @vladmandic/human version 1.9.3 -2021-05-26 08:51:59 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0 -2021-05-26 08:51:59 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true} -2021-05-26 08:51:59 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"} -2021-05-26 08:51:59 STATE: Build for: node type: node: {"imports":37,"importBytes":431051,"outputBytes":385549,"outputFiles":"dist/human.node.js"} -2021-05-26 08:51:59 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"} -2021-05-26 08:51:59 STATE: Build for: nodeGPU type: node: {"imports":37,"importBytes":431059,"outputBytes":385553,"outputFiles":"dist/human.node-gpu.js"} -2021-05-26 08:51:59 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"} -2021-05-26 08:51:59 STATE: Build for: nodeWASM type: node: {"imports":37,"importBytes":431126,"outputBytes":385625,"outputFiles":"dist/human.node-wasm.js"} -2021-05-26 08:51:59 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2478,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"} -2021-05-26 08:51:59 STATE: Build for: browserNoBundle type: esm: {"imports":37,"importBytes":431153,"outputBytes":236268,"outputFiles":"dist/human.esm-nobundle.js"} -2021-05-26 08:52:00 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2478,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"} -2021-05-26 08:52:00 STATE: Build for: browserBundle type: iife: {"imports":37,"importBytes":1541173,"outputBytes":1344154,"outputFiles":"dist/human.js"} -2021-05-26 08:52:01 STATE: Build for: browserBundle type: esm: {"imports":37,"importBytes":1541173,"outputBytes":1344146,"outputFiles":"dist/human.esm.js"} -2021-05-26 08:52:01 INFO:  Generate types: ["src/human.ts"] -2021-05-26 08:52:06 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"] -2021-05-26 08:52:06 INFO:  Generate TypeDocs: ["src/human.ts"] +2021-05-27 16:05:26 INFO:  @vladmandic/human version 1.9.4 +2021-05-27 16:05:26 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.0.0 +2021-05-27 16:05:26 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true} +2021-05-27 16:05:26 STATE: Build for: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1292,"outputFiles":"dist/tfjs.esm.js"} +2021-05-27 16:05:26 STATE: Build for: node type: node: {"imports":37,"importBytes":431050,"outputBytes":385549,"outputFiles":"dist/human.node.js"} +2021-05-27 16:05:26 STATE: Build for: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1300,"outputFiles":"dist/tfjs.esm.js"} +2021-05-27 16:05:26 STATE: Build for: nodeGPU type: node: {"imports":37,"importBytes":431058,"outputBytes":385553,"outputFiles":"dist/human.node-gpu.js"} +2021-05-27 16:05:26 STATE: Build for: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1367,"outputFiles":"dist/tfjs.esm.js"} +2021-05-27 16:05:26 STATE: Build for: nodeWASM type: node: {"imports":37,"importBytes":431125,"outputBytes":385625,"outputFiles":"dist/human.node-wasm.js"} +2021-05-27 16:05:26 STATE: Build for: browserNoBundle type: tfjs: {"imports":1,"importBytes":2478,"outputBytes":1394,"outputFiles":"dist/tfjs.esm.js"} +2021-05-27 16:05:26 STATE: Build for: browserNoBundle type: esm: {"imports":37,"importBytes":431152,"outputBytes":236268,"outputFiles":"dist/human.esm-nobundle.js"} +2021-05-27 16:05:27 STATE: Build for: browserBundle type: tfjs: {"modules":1274,"moduleBytes":4114813,"imports":7,"importBytes":2478,"outputBytes":1111414,"outputFiles":"dist/tfjs.esm.js"} +2021-05-27 16:05:27 STATE: Build for: browserBundle type: iife: {"imports":37,"importBytes":1541172,"outputBytes":1344154,"outputFiles":"dist/human.js"} +2021-05-27 16:05:28 STATE: Build for: browserBundle type: esm: {"imports":37,"importBytes":1541172,"outputBytes":1344146,"outputFiles":"dist/human.esm.js"} +2021-05-27 16:05:28 INFO:  Generate types: ["src/human.ts"] +2021-05-27 16:05:33 INFO:  Update Change log: ["/home/vlado/dev/human/CHANGELOG.md"] +2021-05-27 16:05:33 INFO:  Generate TypeDocs: ["src/human.ts"]