seg-cam 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/public/jersey-detector-worker.js +49 -28
- package/dist/jersey-detector-worker.js +0 -6669
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Se=Object.create;var Y=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames,ye=Object.getOwnPropertySymbols,Ne=Object.getPrototypeOf,Ee=Object.prototype.hasOwnProperty,He=Object.prototype.propertyIsEnumerable;var De=(e,r,t)=>r in e?Y(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,Re=(e,r)=>{for(var t in r||(r={}))Ee.call(r,t)&&De(e,t,r[t]);if(ye)for(var t of ye(r))He.call(r,t)&&De(e,t,r[t]);return e};var Je=(e,r)=>{for(var t in r)Y(e,t,{get:r[t],enumerable:!0})},Ie=(e,r,t,y)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of Ae(r))!Ee.call(e,a)&&a!==t&&Y(e,a,{get:()=>r[a],enumerable:!(y=Oe(r,a))||y.enumerable});return e};var Pe=(e,r,t)=>(t=e!=null?Se(Ne(e)):{},Ie(r||!e||!e.__esModule?Y(t,"default",{value:e,enumerable:!0}):t,e)),je=e=>Ie(Y({},"__esModule",{value:!0}),e);var S=(e,r,t)=>new Promise((y,a)=>{var O=h=>{try{k(t.next(h))}catch(v){a(v)}},R=h=>{try{k(t.throw(h))}catch(v){a(v)}},k=h=>h.done?y(h.value):Promise.resolve(h.value).then(O,R);k((t=t.apply(e,r)).next())});var Le={};Je(Le,{DEFAULT_CONFIG:()=>m,JerseyDetector:()=>ge,useJerseyWorker:()=>se});module.exports=je(Le);var s=require("react");var p=require("react");var f=null,_=!1,q=null,de=0,ne=null,E=new Map,Ue=0,oe=new Map;function se(e,r){let t=(0,p.useRef)(!1),[y,a]=(0,p.useState)(!1),[O,R]=(0,p.useState)(null),k=(0,p.useRef)(!0),h=(0,p.useRef)(!1),v=(0,p.useRef)(`instance_${Math.random().toString(36).substr(2,9)}`),A=(0,p.useRef)(0),[U,X]=(0,p.useState)(0);(0,p.useEffect)(()=>{var M;if(!e)return;k.current=!0,A.current++;let I=A.current,b=v.current,N=(M=oe.get(b))!=null?M:0;return I>N&&(de++,oe.set(b,I)),S(null,null,function*(){var T;if(!f||!Ve(ne,e)){f&&(f.terminate(),f=null,_=!1,console.log("[v0 useJerseyWorker] Worker terminated because of change in config or watchdog"));try{h.current=(T=e.verbose)!=null?T:h.current;let d=r||"/jersey-detector-worker.js";f=new Worker(d),ne=e,_=!1,q=null,a(!1),R(null),f.onmessage=w=>{let u=w.data;switch(u.type){case"ready":_=!0,a(!0);break;case"debug":h.current&&console.log(u.debug_message);break;case"error":let l=u.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",l),_=!1,q=l,a(!1),R(l);break;case"detect_response":if(u.requestId&&E.has(u.requestId)){let W=E.get(u.requestId);W==null||W.resolve(u),E.delete(u.requestId)}break}},f.onerror=w=>{let u=w.message||"Worker initialization error";_=!1,q=u,a(!1),R(u)},f.postMessage({type:"init",config:e})}catch(d){a(!1),R((d==null?void 0:d.message)||String(d))}}else a(_),R(q)}),()=>{k.current=!1;let T=v.current,d=oe.get(T),w=A.current;d===w&&(de--,oe.delete(T),de<=0&&f&&(f.terminate(),f=null,_=!1,q=null,ne=null,E.clear()))}},[e,r,U]);let x=(0,p.useRef)(0);(0,p.useEffect)(()=>{if(!f)return;let I=setInterval(()=>{E.size>0?x.current>=3&&(console.error("[v0 useJerseyWorker] Watchdog: Worker appears hung after 3 consecutive timeouts. Restarting..."),x.current=0,f&&(f.terminate(),f=null,_=!1,ne=null,a(!1),X(b=>b+1))):x.current=0},2e3);return()=>clearInterval(I)},[y,U]);let z=(0,p.useCallback)((I,b,N=.5,H=!0,M)=>S(null,null,function*(){if(!f||!_)return null;if(t.current||E.size>0)return h.current,null;let T=`req_${++Ue}_${Date.now()}`;return new Promise((d,w)=>{let u=setTimeout(()=>{if(E.has(T)){x.current++;let g=E.get(T);g==null||g.reject(new Error("Detection timeout")),E.delete(T),t.current=!1}},5e3),l=g=>{x.current=0,clearTimeout(u),t.current=!1,d(g)},W=g=>{clearTimeout(u),t.current=!1,w(g)};E.set(T,{resolve:l,reject:W});try{t.current=!0,f.postMessage({type:"detect",requestId:T,dimensions:b,bitmap:I,threshold:N,includeSegmentedImages:H,lastJerseyCount:M},[I])}catch(g){clearTimeout(u),E.delete(T),t.current=!1,w(new Error(`Failed to send detect: ${g==null?void 0:g.message}`))}})}),[y]);return{isReady:y,workerReady:y,lastError:O,detect:z}}function Ve(e,r){return e?JSON.stringify(e)===JSON.stringify(r):!1}var m={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,IMAGES_TO_RETURN:"mask",VERBOSE:!1,MIN_DETECTION_AREA:1e4};var be=Pe(require("p-limit"));var we=require("react/jsx-runtime"),ge=(0,s.forwardRef)(({videoRef:e,onWorkerReady:r,onWorkerError:t,onStatsUpdate:y,onSegmentedImage:a,task:O=m.TASK,model:R=m.MODEL,verbose:k=m.VERBOSE,bodyPixArchitecture:h=m.BODYPIX_ARCHITECTURE,bodyPixMultiplier:v=m.BODYPIX_MULTIPLIER,bodyPixQuantBytes:A=m.BODYPIX_QUANT_BYTES,bodyPixStride:U=m.BODYPIX_STRIDE,multiSegmentation:X=m.MULTI_SEGMENTATION,segmentBodyParts:x=m.SEGMENT_BODY_PARTS,backgroundShade:z=m.BACKGROUND_SHADE,shirtShade:I=m.SHIRT_SHADE,threshold:b=m.DETECTION_THRESHOLD,targetPartId:N=m.TARGET_PART_ID,imagesToReturn:H=m.IMAGES_TO_RETURN,minDetectionArea:M=m.MIN_DETECTION_AREA,throttleMs:T=1e3,onImageSegmentedLimit:d=2,workerUrl:w,className:u,style:l},W)=>{let g=(0,s.useRef)(null),ae=(0,s.useRef)(null),V=(0,s.useRef)(null),$=(0,s.useRef)(!1),L=(0,s.useRef)(null),ie=(0,s.useRef)(!1),K=(0,s.useRef)([]),ke=(0,s.useRef)(null),Q=(0,s.useRef)(!1),Z=(0,s.useRef)(void 0);Z.current=t;let ee=(0,s.useRef)({jerseyCount:0,confidence:0,fps:0,processingTime:0}),ce=(0,s.useRef)(0),ue=(0,s.useMemo)(()=>(0,be.default)(d),[d]),re=(0,s.useMemo)(()=>({task:O,model:R,verbose:k,bodyPixArchitecture:h,bodyPixMultiplier:v,bodyPixQuantBytes:A,bodyPixStride:U,multiSegmentation:X,segmentBodyParts:x,backgroundShade:z,shirtShade:I,threshold:b,targetPartId:N,imagesToReturn:H,minDetectionArea:M,mirror:(l==null?void 0:l.transform)==="scaleX(-1)"||typeof(l==null?void 0:l.transform)=="string"&&l.transform.includes("scaleX(-1)")}),[O,R,k,h,v,A,U,X,x,z,I,b,N,H,M,l==null?void 0:l.transform]),ve=()=>{var n,i;return{width:((n=e.current)==null?void 0:n.videoWidth)||0,height:((i=e.current)==null?void 0:i.videoHeight)||0}},{isReady:J,workerReady:B,lastError:F,detect:Ce}=se(re,w);(0,s.useEffect)(()=>{B&&(console.log("[JerseyDetector] Worker Ready with config:",re),Q.current=!1),r==null||r(B)},[B,r,re]),(0,s.useEffect)(()=>{var n;F&&((n=Z.current)==null||n.call(Z,F))},[F]);let _e=(0,s.useCallback)((n,i)=>{if(ue.activeCount>=d){n.forEach(o=>{var c;return(c=o==null?void 0:o.close)==null?void 0:c.call(o)}),console.warn(`[JerseyDetector] Dropped new segmented images \u2014 max ${d} classifications running`);return}ue(()=>S(null,null,function*(){try{a==null||a(n,i)}catch(o){console.error("[JerseyDetector] Classification error:",o)}finally{n.forEach(o=>{var c;return(c=o==null?void 0:o.close)==null?void 0:c.call(o)})}}))},[a,d,ue]),xe=()=>S(null,null,function*(){var P,le,pe;let n=e.current,i=g.current;if(Q.current||!J||!B||!n||!i||ie.current||n.readyState<2||n.paused||n.ended||n.videoWidth===0||n.videoHeight===0)return;!V.current&&!ae.current&&(V.current=i.getContext("bitmaprenderer"),$.current=!!V.current,$.current||(ae.current=i.getContext("2d")));let o=ae.current;if(!$.current&&!o||i.width<=0||i.height<=0)return;let c=null,C=null;try{ie.current=!0;let G=n.videoWidth,fe=n.videoHeight;ke.current={width:G,height:fe},c=yield createImageBitmap(n);let Be=ve(),me=Date.now(),Me=me-ce.current>T,We=ee.current.jerseyCount,D=yield Ce(c,Be,b,Me,We);if((D==null?void 0:D.type)==="detect_response"){if(H!=="none"&&((i.width!==G||i.height!==fe)&&(i.width=G,i.height=fe),D.bitmap)){let j=D.bitmap;$.current&&V.current?V.current.transferFromImageBitmap(j):(o&&o.drawImage(j,0,0),j.close())}K.current.push(Date.now()),K.current=K.current.filter(j=>Date.now()-j<1e3);let te={jerseyCount:((P=D.stats)==null?void 0:P.jerseyCount)||0,confidence:((le=D.stats)==null?void 0:le.confidence)||0,fps:K.current.length,processingTime:((pe=D.stats)==null?void 0:pe.processingTime)||0},he=ee.current;ee.current=te;let Te=me-ce.current>T||te.jerseyCount!==he.jerseyCount||te.confidence!==he.confidence;Te&&y&&(y(te),ce.current=me),Te&&D.segmentedImages&&D.segmentedImages.length>0&&a&&_e(D.segmentedImages,D.bboxes)}}catch(G){console.warn("[JerseyDetector] Detection error (skipping frame):",G)}finally{c==null||c.close(),ie.current=!1}});return(0,s.useImperativeHandle)(W,()=>({get isReady(){return J},get lastError(){return F},get stats(){return ee.current},capture:(n="image/jpeg",i=.92)=>{let o=e.current,c=g.current;if(!o||o.videoWidth<=0||o.videoHeight<=0)throw new Error("Video not ready for capture");let C=document.createElement("canvas");C.width=o.videoWidth,C.height=o.videoHeight;let P=C.getContext("2d");if(!P)throw new Error("Failed to get context for capture canvas");let le=re.mirror;return P.drawImage(o,0,0,C.width,C.height),c&&c.width>0&&c.height>0&&P.drawImage(c,0,0,C.width,C.height),C.toDataURL(n,i)}}),[J,F,B]),(0,s.useEffect)(()=>{if(!B||!J||Q.current)return;let n=e.current,i=g.current;if(!n||!i||n.videoWidth===0||n.videoHeight===0){let c=setTimeout(()=>{L.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(c)}(i.width!==n.videoWidth||i.height!==n.videoHeight)&&(i.width=n.videoWidth,i.height=n.videoHeight);let o=()=>S(null,null,function*(){!B||!J||Q.current||(yield xe(),L.current=requestAnimationFrame(o))});return L.current=requestAnimationFrame(o),()=>{L.current&&cancelAnimationFrame(L.current)}},[B,J]),(0,we.jsx)("canvas",{ref:g,className:`absolute inset-0 pointer-events-none ${u||""}`,style:Re({zIndex:10,width:"100%",height:"100%"},l)})});ge.displayName="JerseyDetector";0&&(module.exports={DEFAULT_CONFIG,JerseyDetector,useJerseyWorker});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var We=Object.defineProperty;var ye=Object.getOwnPropertySymbols;var Se=Object.prototype.hasOwnProperty,Oe=Object.prototype.propertyIsEnumerable;var De=(t,o,n)=>o in t?We(t,o,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[o]=n,Ee=(t,o)=>{for(var n in o||(o={}))Se.call(o,n)&&De(t,n,o[n]);if(ye)for(var n of ye(o))Oe.call(o,n)&&De(t,n,o[n]);return t};var W=(t,o,n)=>new Promise((b,l)=>{var S=g=>{try{w(n.next(g))}catch(k){l(k)}},D=g=>{try{w(n.throw(g))}catch(k){l(k)}},w=g=>g.done?b(g.value):Promise.resolve(g.value).then(S,D);w((n=n.apply(t,o)).next())});import{forwardRef as Je,useImperativeHandle as Pe,useRef as T,useEffect as ge,useMemo as Ie,useCallback as je}from"react";import{useEffect as Re,useState as fe,useCallback as Ae,useRef as j}from"react";var u=null,C=!1,Y=null,me=0,te=null,y=new Map,Ne=0,ne=new Map;function de(t,o){let n=j(!1),[b,l]=fe(!1),[S,D]=fe(null),w=j(!0),g=j(!1),k=j(`instance_${Math.random().toString(36).substr(2,9)}`),O=j(0),[U,q]=fe(0);Re(()=>{var B;if(!t)return;w.current=!0,O.current++;let E=O.current,R=k.current,A=(B=ne.get(R))!=null?B:0;return E>A&&(me++,ne.set(R,E)),W(null,null,function*(){var p;if(!u||!He(te,t)){u&&(u.terminate(),u=null,C=!1,console.log("[v0 useJerseyWorker] Worker terminated because of change in config or watchdog"));try{g.current=(p=t.verbose)!=null?p:g.current;let f=o||"/jersey-detector-worker.js";u=new Worker(f),te=t,C=!1,Y=null,l(!1),D(null),u.onmessage=I=>{let i=I.data;switch(i.type){case"ready":C=!0,l(!0);break;case"debug":g.current&&console.log(i.debug_message);break;case"error":let c=i.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",c),C=!1,Y=c,l(!1),D(c);break;case"detect_response":if(i.requestId&&y.has(i.requestId)){let M=y.get(i.requestId);M==null||M.resolve(i),y.delete(i.requestId)}break}},u.onerror=I=>{let i=I.message||"Worker initialization error";C=!1,Y=i,l(!1),D(i)},u.postMessage({type:"init",config:t})}catch(f){l(!1),D((f==null?void 0:f.message)||String(f))}}else l(C),D(Y)}),()=>{w.current=!1;let p=k.current,f=ne.get(p),I=O.current;f===I&&(me--,ne.delete(p),me<=0&&u&&(u.terminate(),u=null,C=!1,Y=null,te=null,y.clear()))}},[t,o,U]);let _=j(0);Re(()=>{if(!u)return;let E=setInterval(()=>{y.size>0?_.current>=3&&(console.error("[v0 useJerseyWorker] Watchdog: Worker appears hung after 3 consecutive timeouts. Restarting..."),_.current=0,u&&(u.terminate(),u=null,C=!1,te=null,l(!1),q(R=>R+1))):_.current=0},2e3);return()=>clearInterval(E)},[b,U]);let X=Ae((E,R,A=.5,N=!0,B)=>W(null,null,function*(){if(!u||!C)return null;if(n.current||y.size>0)return g.current,null;let p=`req_${++Ne}_${Date.now()}`;return new Promise((f,I)=>{let i=setTimeout(()=>{if(y.has(p)){_.current++;let m=y.get(p);m==null||m.reject(new Error("Detection timeout")),y.delete(p),n.current=!1}},5e3),c=m=>{_.current=0,clearTimeout(i),n.current=!1,f(m)},M=m=>{clearTimeout(i),n.current=!1,I(m)};y.set(p,{resolve:c,reject:M});try{n.current=!0,u.postMessage({type:"detect",requestId:p,dimensions:R,bitmap:E,threshold:A,includeSegmentedImages:N,lastJerseyCount:B},[E])}catch(m){clearTimeout(i),y.delete(p),n.current=!1,I(new Error(`Failed to send detect: ${m==null?void 0:m.message}`))}})}),[b]);return{isReady:b,workerReady:b,lastError:S,detect:X}}function He(t,o){return t?JSON.stringify(t)===JSON.stringify(o):!1}var d={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,IMAGES_TO_RETURN:"mask",VERBOSE:!1,MIN_DETECTION_AREA:1e4};import Ue from"p-limit";import{jsx as Ve}from"react/jsx-runtime";var be=Je(({videoRef:t,onWorkerReady:o,onWorkerError:n,onStatsUpdate:b,onSegmentedImage:l,task:S=d.TASK,model:D=d.MODEL,verbose:w=d.VERBOSE,bodyPixArchitecture:g=d.BODYPIX_ARCHITECTURE,bodyPixMultiplier:k=d.BODYPIX_MULTIPLIER,bodyPixQuantBytes:O=d.BODYPIX_QUANT_BYTES,bodyPixStride:U=d.BODYPIX_STRIDE,multiSegmentation:q=d.MULTI_SEGMENTATION,segmentBodyParts:_=d.SEGMENT_BODY_PARTS,backgroundShade:X=d.BACKGROUND_SHADE,shirtShade:E=d.SHIRT_SHADE,threshold:R=d.DETECTION_THRESHOLD,targetPartId:A=d.TARGET_PART_ID,imagesToReturn:N=d.IMAGES_TO_RETURN,minDetectionArea:B=d.MIN_DETECTION_AREA,throttleMs:p=1e3,onImageSegmentedLimit:f=2,workerUrl:I,className:i,style:c},M)=>{let m=T(null),oe=T(null),V=T(null),z=T(!1),L=T(null),se=T(!1),$=T([]),we=T(null),K=T(!1),Q=T(void 0);Q.current=n;let Z=T({jerseyCount:0,confidence:0,fps:0,processingTime:0}),ae=T(0),ie=Ie(()=>Ue(f),[f]),ee=Ie(()=>({task:S,model:D,verbose:w,bodyPixArchitecture:g,bodyPixMultiplier:k,bodyPixQuantBytes:O,bodyPixStride:U,multiSegmentation:q,segmentBodyParts:_,backgroundShade:X,shirtShade:E,threshold:R,targetPartId:A,imagesToReturn:N,minDetectionArea:B,mirror:(c==null?void 0:c.transform)==="scaleX(-1)"||typeof(c==null?void 0:c.transform)=="string"&&c.transform.includes("scaleX(-1)")}),[S,D,w,g,k,O,U,q,_,X,E,R,A,N,B,c==null?void 0:c.transform]),ke=()=>{var e,s;return{width:((e=t.current)==null?void 0:e.videoWidth)||0,height:((s=t.current)==null?void 0:s.videoHeight)||0}},{isReady:H,workerReady:x,lastError:F,detect:ve}=de(ee,I);ge(()=>{x&&(console.log("[JerseyDetector] Worker Ready with config:",ee),K.current=!1),o==null||o(x)},[x,o,ee]),ge(()=>{var e;F&&((e=Q.current)==null||e.call(Q,F))},[F]);let Ce=je((e,s)=>{if(ie.activeCount>=f){e.forEach(r=>{var a;return(a=r==null?void 0:r.close)==null?void 0:a.call(r)}),console.warn(`[JerseyDetector] Dropped new segmented images \u2014 max ${f} classifications running`);return}ie(()=>W(null,null,function*(){try{l==null||l(e,s)}catch(r){console.error("[JerseyDetector] Classification error:",r)}finally{e.forEach(r=>{var a;return(a=r==null?void 0:r.close)==null?void 0:a.call(r)})}}))},[l,f,ie]),_e=()=>W(null,null,function*(){var J,ce,pe;let e=t.current,s=m.current;if(K.current||!H||!x||!e||!s||se.current||e.readyState<2||e.paused||e.ended||e.videoWidth===0||e.videoHeight===0)return;!V.current&&!oe.current&&(V.current=s.getContext("bitmaprenderer"),z.current=!!V.current,z.current||(oe.current=s.getContext("2d")));let r=oe.current;if(!z.current&&!r||s.width<=0||s.height<=0)return;let a=null,v=null;try{se.current=!0;let G=e.videoWidth,ue=e.videoHeight;we.current={width:G,height:ue},a=yield createImageBitmap(e);let xe=ke(),le=Date.now(),Be=le-ae.current>p,Me=Z.current.jerseyCount,h=yield ve(a,xe,R,Be,Me);if((h==null?void 0:h.type)==="detect_response"){if(N!=="none"&&((s.width!==G||s.height!==ue)&&(s.width=G,s.height=ue),h.bitmap)){let P=h.bitmap;z.current&&V.current?V.current.transferFromImageBitmap(P):(r&&r.drawImage(P,0,0),P.close())}$.current.push(Date.now()),$.current=$.current.filter(P=>Date.now()-P<1e3);let re={jerseyCount:((J=h.stats)==null?void 0:J.jerseyCount)||0,confidence:((ce=h.stats)==null?void 0:ce.confidence)||0,fps:$.current.length,processingTime:((pe=h.stats)==null?void 0:pe.processingTime)||0},he=Z.current;Z.current=re;let Te=le-ae.current>p||re.jerseyCount!==he.jerseyCount||re.confidence!==he.confidence;Te&&b&&(b(re),ae.current=le),Te&&h.segmentedImages&&h.segmentedImages.length>0&&l&&Ce(h.segmentedImages,h.bboxes)}}catch(G){console.warn("[JerseyDetector] Detection error (skipping frame):",G)}finally{a==null||a.close(),se.current=!1}});return Pe(M,()=>({get isReady(){return H},get lastError(){return F},get stats(){return Z.current},capture:(e="image/jpeg",s=.92)=>{let r=t.current,a=m.current;if(!r||r.videoWidth<=0||r.videoHeight<=0)throw new Error("Video not ready for capture");let v=document.createElement("canvas");v.width=r.videoWidth,v.height=r.videoHeight;let J=v.getContext("2d");if(!J)throw new Error("Failed to get context for capture canvas");let ce=ee.mirror;return J.drawImage(r,0,0,v.width,v.height),a&&a.width>0&&a.height>0&&J.drawImage(a,0,0,v.width,v.height),v.toDataURL(e,s)}}),[H,F,x]),ge(()=>{if(!x||!H||K.current)return;let e=t.current,s=m.current;if(!e||!s||e.videoWidth===0||e.videoHeight===0){let a=setTimeout(()=>{L.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(a)}(s.width!==e.videoWidth||s.height!==e.videoHeight)&&(s.width=e.videoWidth,s.height=e.videoHeight);let r=()=>W(null,null,function*(){!x||!H||K.current||(yield _e(),L.current=requestAnimationFrame(r))});return L.current=requestAnimationFrame(r),()=>{L.current&&cancelAnimationFrame(L.current)}},[x,H]),Ve("canvas",{ref:m,className:`absolute inset-0 pointer-events-none ${i||""}`,style:Ee({zIndex:10,width:"100%",height:"100%"},c)})});be.displayName="JerseyDetector";export{d as DEFAULT_CONFIG,be as JerseyDetector,de as useJerseyWorker};
|
package/package.json
CHANGED
|
@@ -82168,7 +82168,7 @@ var BodyPixSegmenter = class {
|
|
|
82168
82168
|
};
|
|
82169
82169
|
BodyPixSegmenter.instance = null;
|
|
82170
82170
|
BodyPixSegmenter.isInitialized = false;
|
|
82171
|
-
async function processSinglePerson(person, originalImageTensor) {
|
|
82171
|
+
async function processSinglePerson(person, originalImageTensor, includeSegmentedImages = true) {
|
|
82172
82172
|
const width = originalImageTensor.shape[1];
|
|
82173
82173
|
const height = originalImageTensor.shape[0];
|
|
82174
82174
|
const rawMaskTensor = await person.mask.toTensor();
|
|
@@ -82224,15 +82224,18 @@ async function processSinglePerson(person, originalImageTensor) {
|
|
|
82224
82224
|
sendDebug(`[Worker] No torso or too small: ${hasTorso}, ${area}`);
|
|
82225
82225
|
return { personBitmap: null, isUpperTorso: null, bbox };
|
|
82226
82226
|
}
|
|
82227
|
-
|
|
82228
|
-
|
|
82229
|
-
const
|
|
82230
|
-
|
|
82231
|
-
|
|
82232
|
-
|
|
82233
|
-
|
|
82234
|
-
|
|
82235
|
-
|
|
82227
|
+
let personBitmap = null;
|
|
82228
|
+
if (includeSegmentedImages) {
|
|
82229
|
+
const rgbaTensor = tf.tidy(() => {
|
|
82230
|
+
const rgbTensor = tf.slice(originalImageTensor, [top, left, 0], [bboxHeight, bboxWidth, 3]);
|
|
82231
|
+
const alphaTensor = tf.fill([bboxHeight, bboxWidth, 1], 255);
|
|
82232
|
+
return tf.concat([rgbTensor, alphaTensor], 2);
|
|
82233
|
+
});
|
|
82234
|
+
const pixelData = await rgbaTensor.data();
|
|
82235
|
+
const imageData = new ImageData(new Uint8ClampedArray(pixelData), bboxWidth, bboxHeight);
|
|
82236
|
+
personBitmap = await createImageBitmap(imageData);
|
|
82237
|
+
rgbaTensor.dispose();
|
|
82238
|
+
}
|
|
82236
82239
|
partIds.dispose();
|
|
82237
82240
|
return {
|
|
82238
82241
|
personBitmap,
|
|
@@ -82243,6 +82246,8 @@ async function processSinglePerson(person, originalImageTensor) {
|
|
|
82243
82246
|
}
|
|
82244
82247
|
var canvas = null;
|
|
82245
82248
|
var ctx = null;
|
|
82249
|
+
var mirrorCanvas = null;
|
|
82250
|
+
var mirrorCtx = null;
|
|
82246
82251
|
var currentConfig = null;
|
|
82247
82252
|
var isProcessing = false;
|
|
82248
82253
|
var isInitInProgress = false;
|
|
@@ -82275,9 +82280,10 @@ var handleInit = async (message) => {
|
|
|
82275
82280
|
}
|
|
82276
82281
|
};
|
|
82277
82282
|
var handleDetect = async (message) => {
|
|
82278
|
-
const { requestId, dimensions, bitmap: inputBitmap, threshold: threshold3 } = message;
|
|
82283
|
+
const { requestId, dimensions, bitmap: inputBitmap, threshold: threshold3, includeSegmentedImages = true, lastJerseyCount } = message;
|
|
82279
82284
|
let outputBitmap;
|
|
82280
82285
|
let originalImageTensor = null;
|
|
82286
|
+
let fallbackImageData = null;
|
|
82281
82287
|
try {
|
|
82282
82288
|
if (isProcessing) throw new Error("New request before previous finished");
|
|
82283
82289
|
isProcessing = true;
|
|
@@ -82289,32 +82295,41 @@ var handleDetect = async (message) => {
|
|
|
82289
82295
|
}
|
|
82290
82296
|
if (!ctx) throw new Error("Failed to get canvas context");
|
|
82291
82297
|
const { width, height } = canvas;
|
|
82292
|
-
|
|
82293
|
-
|
|
82294
|
-
|
|
82295
|
-
|
|
82296
|
-
|
|
82297
|
-
|
|
82298
|
-
|
|
82299
|
-
|
|
82298
|
+
let segmentInput = inputBitmap;
|
|
82299
|
+
try {
|
|
82300
|
+
originalImageTensor = tf.browser.fromPixels(inputBitmap, 3);
|
|
82301
|
+
} catch {
|
|
82302
|
+
ctx.clearRect(0, 0, width, height);
|
|
82303
|
+
ctx.drawImage(inputBitmap, 0, 0);
|
|
82304
|
+
fallbackImageData = ctx.getImageData(0, 0, width, height);
|
|
82305
|
+
segmentInput = fallbackImageData;
|
|
82306
|
+
originalImageTensor = tf.tidy(() => {
|
|
82307
|
+
const rgba = tf.tensor3d(new Uint8Array(fallbackImageData.data), [height, width, 4], "int32");
|
|
82308
|
+
return tf.slice(rgba, [0, 0, 0], [-1, -1, 3]);
|
|
82309
|
+
});
|
|
82310
|
+
}
|
|
82300
82311
|
const segmenter = await BodyPixSegmenter.getInstance();
|
|
82301
|
-
const people = await segmenter.segmentPeople(
|
|
82312
|
+
const people = await segmenter.segmentPeople(segmentInput, {
|
|
82302
82313
|
multiSegmentation: currentConfig?.multiSegmentation ?? true,
|
|
82303
82314
|
segmentBodyParts: currentConfig?.segmentBodyParts ?? true,
|
|
82304
82315
|
segmentationThreshold: currentConfig?.threshold ?? 0.5
|
|
82305
82316
|
});
|
|
82317
|
+
inputBitmap.close();
|
|
82306
82318
|
const segmentedImages = [];
|
|
82307
82319
|
const bboxes = [];
|
|
82308
82320
|
let allTorsosMask = null;
|
|
82309
82321
|
sendDebug(`[Worker] Found ${people.length} person(s)`);
|
|
82310
82322
|
if (people && people.length > 0) {
|
|
82311
82323
|
const imagesToReturn = currentConfig?.imagesToReturn ?? "mask";
|
|
82324
|
+
const shouldExtract = includeSegmentedImages || lastJerseyCount !== void 0 && people.length !== lastJerseyCount;
|
|
82312
82325
|
for (const person of people) {
|
|
82313
|
-
const { personBitmap, isUpperTorso, bbox } = await processSinglePerson(person, originalImageTensor);
|
|
82326
|
+
const { personBitmap, isUpperTorso, bbox } = await processSinglePerson(person, originalImageTensor, shouldExtract);
|
|
82314
82327
|
if (!isUpperTorso) continue;
|
|
82315
82328
|
if (personBitmap) {
|
|
82316
82329
|
segmentedImages.push(personBitmap);
|
|
82317
82330
|
bboxes.push(bbox);
|
|
82331
|
+
} else {
|
|
82332
|
+
bboxes.push(bbox);
|
|
82318
82333
|
}
|
|
82319
82334
|
if (imagesToReturn !== "none") {
|
|
82320
82335
|
if (!allTorsosMask) {
|
|
@@ -82362,12 +82377,16 @@ var handleDetect = async (message) => {
|
|
|
82362
82377
|
const overlayData = await overlayTensor.data();
|
|
82363
82378
|
ctx.putImageData(new ImageData(new Uint8ClampedArray(overlayData), width, height), 0, 0);
|
|
82364
82379
|
if (currentConfig?.mirror) {
|
|
82365
|
-
|
|
82366
|
-
|
|
82367
|
-
|
|
82368
|
-
|
|
82369
|
-
|
|
82370
|
-
|
|
82380
|
+
if (!mirrorCanvas || mirrorCanvas.width !== width || mirrorCanvas.height !== height) {
|
|
82381
|
+
mirrorCanvas = new OffscreenCanvas(width, height);
|
|
82382
|
+
mirrorCtx = mirrorCanvas.getContext("2d");
|
|
82383
|
+
}
|
|
82384
|
+
if (mirrorCtx && mirrorCanvas) {
|
|
82385
|
+
mirrorCtx.setTransform(1, 0, 0, 1, 0, 0);
|
|
82386
|
+
mirrorCtx.clearRect(0, 0, width, height);
|
|
82387
|
+
mirrorCtx.translate(width, 0);
|
|
82388
|
+
mirrorCtx.scale(-1, 1);
|
|
82389
|
+
mirrorCtx.drawImage(canvas, 0, 0);
|
|
82371
82390
|
outputBitmap = await createImageBitmap(mirrorCanvas);
|
|
82372
82391
|
} else {
|
|
82373
82392
|
outputBitmap = await createImageBitmap(canvas);
|
|
@@ -82385,7 +82404,9 @@ var handleDetect = async (message) => {
|
|
|
82385
82404
|
} else {
|
|
82386
82405
|
sendDebug("[Worker] No output bitmap created");
|
|
82387
82406
|
}
|
|
82388
|
-
segmentedImages.forEach((img) =>
|
|
82407
|
+
segmentedImages.forEach((img) => {
|
|
82408
|
+
if (img) transferList.push(img);
|
|
82409
|
+
});
|
|
82389
82410
|
self.postMessage({
|
|
82390
82411
|
type: "detect_response",
|
|
82391
82412
|
requestId,
|