seg-cam 0.4.5 → 0.4.7

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.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import * as react from 'react';
2
2
 
3
3
  type TaskType = "object-detection" | "image-segmentation";
4
4
  type ModelType = "BodyPix";
@@ -17,6 +17,7 @@ type ImageSegmentationType = {
17
17
  score?: number;
18
18
  mask: any;
19
19
  };
20
+ type ImagesToReturn = "mask" | "mask_with_image" | "none";
20
21
  declare const DEFAULT_CONFIG: {
21
22
  TASK: TaskType;
22
23
  MODEL: ModelType;
@@ -30,7 +31,7 @@ declare const DEFAULT_CONFIG: {
30
31
  SHIRT_SHADE: number;
31
32
  DETECTION_THRESHOLD: number;
32
33
  TARGET_PART_ID: number;
33
- ONLY_DRAW_MASK: boolean;
34
+ IMAGES_TO_RETURN: ImagesToReturn;
34
35
  VERBOSE: boolean;
35
36
  };
36
37
 
@@ -52,6 +53,7 @@ interface JerseyDetectorHandle {
52
53
  isReady: boolean;
53
54
  stats: DetectionStats;
54
55
  lastError: string | null;
56
+ capture: (format?: "image/jpeg" | "image/png", quality?: number) => string;
55
57
  }
56
58
  interface JerseyDetectorProps {
57
59
  videoRef: React.RefObject<HTMLVideoElement>;
@@ -62,7 +64,7 @@ interface JerseyDetectorProps {
62
64
  task?: TaskType;
63
65
  model?: ModelType;
64
66
  verbose?: boolean;
65
- bodyPixArchitecture?: 'MobileNetV1' | 'ResNet50';
67
+ bodyPixArchitecture?: "MobileNetV1" | "ResNet50";
66
68
  bodyPixMultiplier?: number;
67
69
  bodyPixQuantBytes?: number;
68
70
  bodyPixStride?: number;
@@ -72,10 +74,10 @@ interface JerseyDetectorProps {
72
74
  shirtShade?: number;
73
75
  threshold?: number;
74
76
  targetPartId?: number;
75
- onlyDrawMask?: boolean;
77
+ imagesToReturn?: ImagesToReturn;
76
78
  workerUrl?: string;
77
79
  }
78
- declare const JerseyDetector: React.ForwardRefExoticComponent<JerseyDetectorProps & React.RefAttributes<JerseyDetectorHandle>>;
80
+ declare const JerseyDetector: react.ForwardRefExoticComponent<JerseyDetectorProps & react.RefAttributes<JerseyDetectorHandle>>;
79
81
 
80
82
  type WorkerConfig = {
81
83
  task: TaskType;
@@ -91,6 +93,7 @@ type WorkerConfig = {
91
93
  shirtShade?: number;
92
94
  threshold?: number;
93
95
  targetPartId?: number;
96
+ imagesToReturn?: ImagesToReturn;
94
97
  };
95
98
  type ImageDimensions$1 = {
96
99
  width: number;
@@ -121,7 +124,7 @@ type WorkerErrorMessage = {
121
124
  };
122
125
  type WorkerDetectResponseMessage = {
123
126
  type: "detect_response";
124
- bitmap: ImageBitmap;
127
+ bitmap?: ImageBitmap;
125
128
  stats: DetectionStats;
126
129
  segmentedImages?: ImageBitmap[];
127
130
  };
@@ -147,4 +150,4 @@ declare function useJerseyWorker(config: WorkerConfig, workerUrlProp?: string):
147
150
  detect: (bitmap: ImageBitmap, dimensions: ImageDimensions, threshold?: number) => Promise<any>;
148
151
  };
149
152
 
150
- export { DEFAULT_CONFIG, type DetectionStats, type ImageDimensions$1 as ImageDimensions, type ImageSegmentationType, JerseyDetector, type JerseyDetectorHandle, type JerseyDetectorProps, type ModelType, type ObjectDetectionType, type TaskType, type WorkerConfig, type WorkerDebugMessage, type WorkerDetectMessage, type WorkerDetectResponseMessage, type WorkerErrorMessage, type WorkerInitMessage, type WorkerPostMessage, type WorkerProgressMessage, type WorkerReadyMessage, type WorkerResponseMessage, useJerseyWorker };
153
+ export { DEFAULT_CONFIG, type DetectionStats, type ImageDimensions$1 as ImageDimensions, type ImageSegmentationType, type ImagesToReturn, JerseyDetector, type JerseyDetectorHandle, type JerseyDetectorProps, type ModelType, type ObjectDetectionType, type TaskType, type WorkerConfig, type WorkerDebugMessage, type WorkerDetectMessage, type WorkerDetectResponseMessage, type WorkerErrorMessage, type WorkerInitMessage, type WorkerPostMessage, type WorkerProgressMessage, type WorkerReadyMessage, type WorkerResponseMessage, useJerseyWorker };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import * as react from 'react';
2
2
 
3
3
  type TaskType = "object-detection" | "image-segmentation";
4
4
  type ModelType = "BodyPix";
@@ -17,6 +17,7 @@ type ImageSegmentationType = {
17
17
  score?: number;
18
18
  mask: any;
19
19
  };
20
+ type ImagesToReturn = "mask" | "mask_with_image" | "none";
20
21
  declare const DEFAULT_CONFIG: {
21
22
  TASK: TaskType;
22
23
  MODEL: ModelType;
@@ -30,7 +31,7 @@ declare const DEFAULT_CONFIG: {
30
31
  SHIRT_SHADE: number;
31
32
  DETECTION_THRESHOLD: number;
32
33
  TARGET_PART_ID: number;
33
- ONLY_DRAW_MASK: boolean;
34
+ IMAGES_TO_RETURN: ImagesToReturn;
34
35
  VERBOSE: boolean;
35
36
  };
36
37
 
@@ -63,7 +64,7 @@ interface JerseyDetectorProps {
63
64
  task?: TaskType;
64
65
  model?: ModelType;
65
66
  verbose?: boolean;
66
- bodyPixArchitecture?: 'MobileNetV1' | 'ResNet50';
67
+ bodyPixArchitecture?: "MobileNetV1" | "ResNet50";
67
68
  bodyPixMultiplier?: number;
68
69
  bodyPixQuantBytes?: number;
69
70
  bodyPixStride?: number;
@@ -73,10 +74,10 @@ interface JerseyDetectorProps {
73
74
  shirtShade?: number;
74
75
  threshold?: number;
75
76
  targetPartId?: number;
76
- onlyDrawMask?: boolean;
77
+ imagesToReturn?: ImagesToReturn;
77
78
  workerUrl?: string;
78
79
  }
79
- declare const JerseyDetector: React.ForwardRefExoticComponent<JerseyDetectorProps & React.RefAttributes<JerseyDetectorHandle>>;
80
+ declare const JerseyDetector: react.ForwardRefExoticComponent<JerseyDetectorProps & react.RefAttributes<JerseyDetectorHandle>>;
80
81
 
81
82
  type WorkerConfig = {
82
83
  task: TaskType;
@@ -92,6 +93,7 @@ type WorkerConfig = {
92
93
  shirtShade?: number;
93
94
  threshold?: number;
94
95
  targetPartId?: number;
96
+ imagesToReturn?: ImagesToReturn;
95
97
  };
96
98
  type ImageDimensions$1 = {
97
99
  width: number;
@@ -122,7 +124,7 @@ type WorkerErrorMessage = {
122
124
  };
123
125
  type WorkerDetectResponseMessage = {
124
126
  type: "detect_response";
125
- bitmap: ImageBitmap;
127
+ bitmap?: ImageBitmap;
126
128
  stats: DetectionStats;
127
129
  segmentedImages?: ImageBitmap[];
128
130
  };
@@ -148,4 +150,4 @@ declare function useJerseyWorker(config: WorkerConfig, workerUrlProp?: string):
148
150
  detect: (bitmap: ImageBitmap, dimensions: ImageDimensions, threshold?: number) => Promise<any>;
149
151
  };
150
152
 
151
- export { DEFAULT_CONFIG, type DetectionStats, type ImageDimensions$1 as ImageDimensions, type ImageSegmentationType, JerseyDetector, type JerseyDetectorHandle, type JerseyDetectorProps, type ModelType, type ObjectDetectionType, type TaskType, type WorkerConfig, type WorkerDebugMessage, type WorkerDetectMessage, type WorkerDetectResponseMessage, type WorkerErrorMessage, type WorkerInitMessage, type WorkerPostMessage, type WorkerProgressMessage, type WorkerReadyMessage, type WorkerResponseMessage, useJerseyWorker };
153
+ export { DEFAULT_CONFIG, type DetectionStats, type ImageDimensions$1 as ImageDimensions, type ImageSegmentationType, type ImagesToReturn, JerseyDetector, type JerseyDetectorHandle, type JerseyDetectorProps, type ModelType, type ObjectDetectionType, type TaskType, type WorkerConfig, type WorkerDebugMessage, type WorkerDetectMessage, type WorkerDetectResponseMessage, type WorkerErrorMessage, type WorkerInitMessage, type WorkerPostMessage, type WorkerProgressMessage, type WorkerReadyMessage, type WorkerResponseMessage, useJerseyWorker };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var de=Object.create;var L=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var pe=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var ke=(e,t)=>{for(var o in t)L(e,o,{get:t[o],enumerable:!0})},te=(e,t,o,m)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ye(t))!Te.call(e,s)&&s!==o&&L(e,s,{get:()=>t[s],enumerable:!(m=ge(t,s))||m.enumerable});return e};var De=(e,t,o)=>(o=e!=null?de(pe(e)):{},te(t||!e||!e.__esModule?L(o,"default",{value:e,enumerable:!0}):o,e)),be=e=>te(L({},"__esModule",{value:!0}),e);var h=(e,t,o)=>new Promise((m,s)=>{var _=i=>{try{b(o.next(i))}catch(R){s(R)}},y=i=>{try{b(o.throw(i))}catch(R){s(R)}},b=i=>i.done?m(i.value):Promise.resolve(i.value).then(_,y);b((o=o.apply(e,t)).next())});var Re={};ke(Re,{DEFAULT_CONFIG:()=>a,JerseyDetector:()=>X,useJerseyWorker:()=>Y});module.exports=be(Re);var n=require("react"),oe=De(require("react"));var g=require("react");var f=null,I=!1,O=null,q=0,G=null,p=new Map,Ee=0;function Y(e,t){let o=(0,g.useRef)(!1),[m,s]=(0,g.useState)(!1),[_,y]=(0,g.useState)(null),b=(0,g.useRef)(!0),i=(0,g.useRef)(!1);(0,g.useEffect)(()=>{s(I),y(O)},[]),(0,g.useEffect)(()=>e?(b.current=!0,q++,h(null,null,function*(){var w;if(!f||!Ie(G,e)){f&&(console.log("[useJerseyWorker] Terminating old worker due to config change"),f.terminate(),f=null,I=!1);try{i.current=(w=e.verbose)!=null?w:i.current,console.log(`[useJerseyWorker] Verbose set to ${i.current}`);let d=t||"/jersey-detector-worker.js";console.log(`[useJerseyWorker] Initializing worker from: ${d}`),f=new Worker(d),G=e,I=!1,O=null,s(!1),y(null),f.onmessage=c=>{let r=c.data;switch(r.type){case"ready":I=!0,s(!0),console.log(`[v0 useJerseyWorker] Worker ready: ${r.task} | ${r.model} | device: ${r.device} | dtype: ${r.dtype}`);break;case"loading_progress":i.current&&console.log(`[v0 useJerseyWorker] Loaded ${r.progress}% of ${r.file}`);break;case"debug":i.current&&console.log(r.debug_message);break;case"error":let T=r.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",T),I=!1,O=T,s(!1),y(T);break;case"detect_response":if(r.requestId&&p.has(r.requestId)){let l=p.get(r.requestId);if(l){if(i.current){let k=r.stats;console.log(`Det count ${k.detectionCount} | Conf: ${k.averageConfidence} | proc time: ${k.processingTime}ms`)}l.resolve(r),p.delete(r.requestId)}}else if(p.size>0){let l=p.entries().next();if(!l.done){let[k,$]=l.value;$.resolve(r),p.delete(k)}}break}},f.onerror=c=>{let r=c.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",r),I=!1,O=r,s(!1),y(r)},f.postMessage({type:"init",config:e})}catch(d){let c=(d==null?void 0:d.message)||String(d);console.error("[useJerseyWorker] Failed to create worker:",c),s(!1),y(c)}}else s(I),y(O)}),()=>{b.current=!1,q--,q<=0&&f&&(console.log("[useJerseyWorker] Terminating worker (refCount 0)"),f.terminate(),f=null,I=!1,O=null,G=null,p.clear())}):void 0,[e]);let R=(0,g.useCallback)((v,w,d=.5)=>h(null,null,function*(){if(!f||!I)throw new Error("Worker not ready");if(o.current)return console.log("[v0 useJerseyWorker] New request before detection completed"),null;let c=`req_${++Ee}_${Date.now()}`;return new Promise((r,T)=>{p.set(c,{resolve:r,reject:T});try{o.current=!0,f.postMessage({type:"detect",requestId:c,dimensions:w,bitmap:v,threshold:d},[v])}catch(l){p.delete(c);let k=`Failed to send detect: ${l==null?void 0:l.message}`;T(new Error(k))}finally{o.current=!1}setTimeout(()=>{p.has(c)&&(p.delete(c),T(new Error("Detection timeout")))},1e4)})}),[m]);return{isReady:m,workerReady:m,lastError:_,detect:R}}function Ie(e,t){return e?JSON.stringify(e)===JSON.stringify(t):!1}var a={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,ONLY_DRAW_MASK:!0,VERBOSE:!1};var X=(0,n.forwardRef)(({videoRef:e,onWorkerReady:t,onWorkerError:o,onStatsUpdate:m,onSegmentedImage:s,task:_=a.TASK,model:y=a.MODEL,verbose:b=a.VERBOSE,bodyPixArchitecture:i=a.BODYPIX_ARCHITECTURE,bodyPixMultiplier:R=a.BODYPIX_MULTIPLIER,bodyPixQuantBytes:v=a.BODYPIX_QUANT_BYTES,bodyPixStride:w=a.BODYPIX_STRIDE,multiSegmentation:d=a.MULTI_SEGMENTATION,segmentBodyParts:c=a.SEGMENT_BODY_PARTS,backgroundShade:r=a.BACKGROUND_SHADE,shirtShade:T=a.SHIRT_SHADE,threshold:l=a.DETECTION_THRESHOLD,targetPartId:k=a.TARGET_PART_ID,onlyDrawMask:$=a.ONLY_DRAW_MASK,workerUrl:se},ne)=>{var V,z;let j=(0,n.useRef)(null),B=(0,n.useRef)(null),U=(0,n.useRef)(!1),N=(0,n.useRef)([]),ie=(0,n.useRef)(null),A=(0,n.useRef)(!1),[K,ae]=(0,n.useState)({jerseyCount:0,confidence:0,fps:0,processingTime:0}),ce=(0,n.useMemo)(()=>({task:_,model:y,verbose:b,bodyPixArchitecture:i,bodyPixMultiplier:R,bodyPixQuantBytes:v,bodyPixStride:w,multiSegmentation:d,segmentBodyParts:c,backgroundShade:r,shirtShade:T,threshold:l,targetPartId:k}),[_,y,b,i,R,v,w,d,c,r,T,l,k]),le=(0,n.useMemo)(()=>{var u,E;return{width:((u=e.current)==null?void 0:u.videoWidth)||0,height:((E=e.current)==null?void 0:E.videoHeight)||0}},[(V=e.current)==null?void 0:V.videoWidth,(z=e.current)==null?void 0:z.videoHeight]),{isReady:C,workerReady:M,lastError:W,detect:ue}=Y(ce,se);(0,n.useEffect)(()=>{t==null||t(M)},[M,t]),(0,n.useEffect)(()=>{W&&(A.current=!0,console.error("[v0] Worker error detected, stopping detection loop:",W)),o==null||o(W)},[W,o]);let fe=()=>h(null,null,function*(){var Q,Z,ee;let u=e.current,E=j.current;if(A.current||!M||!C||!u||!E||U.current||u.readyState<2||u.paused||u.ended)return;let J=null,x=null;try{U.current=!0;let S=u.videoWidth,P=u.videoHeight;ie.current={width:S,height:P},J=yield createImageBitmap(u);let D=yield ue(J,le,l);if((D==null?void 0:D.type)==="detect_response"&&D.bitmap){x=D.bitmap;let F=E.getContext("2d");F&&((E.width!==S||E.height!==P)&&(E.width=S,E.height=P),$&&F.clearRect(0,0,S,P),x&&F.drawImage(x,0,0)),N.current.push(Date.now()),N.current=N.current.filter(H=>Date.now()-H<1e3);let re={jerseyCount:((Q=D.stats)==null?void 0:Q.detectionCount)||0,confidence:((Z=D.stats)==null?void 0:Z.averageConfidence)||0,fps:N.current.length,processingTime:((ee=D.stats)==null?void 0:ee.processingTime)||0};if(ae(re),m==null||m(re),D.segmentedImages){let H=D.segmentedImages;h(null,null,function*(){try{yield s==null?void 0:s(H)}finally{H.forEach(me=>me.close())}})}}}catch(S){console.error("[v0] Detection error:",S),A.current=!0}finally{J&&J.close(),x&&x.close(),U.current=!1}});return(0,n.useEffect)(()=>{if(!M||!C||A.current)return;let u=()=>h(null,null,function*(){!M||!C||A.current||(yield fe(),B.current=requestAnimationFrame(u))});return B.current=requestAnimationFrame(u),()=>{B.current&&cancelAnimationFrame(B.current)}},[M,C]),(0,n.useImperativeHandle)(ne,()=>({isReady:C,lastError:W,stats:K}),[C,W,K]),oe.default.createElement("canvas",{ref:j,className:"absolute inset-0 w-full h-full pointer-events-none",style:{zIndex:10}})});X.displayName="JerseyDetector";0&&(module.exports={DEFAULT_CONFIG,JerseyDetector,useJerseyWorker});
1
+ "use strict";var K=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var he=Object.prototype.hasOwnProperty;var De=(e,n)=>{for(var u in n)K(e,u,{get:n[u],enumerable:!0})},be=(e,n,u,y)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of Ee(n))!he.call(e,s)&&s!==u&&K(e,s,{get:()=>n[s],enumerable:!(y=Te(n,s))||y.enumerable});return e};var ke=e=>be(K({},"__esModule",{value:!0}),e);var W=(e,n,u)=>new Promise((y,s)=>{var O=l=>{try{D(u.next(l))}catch(b){s(b)}},E=l=>{try{D(u.throw(l))}catch(b){s(b)}},D=l=>l.done?y(l.value):Promise.resolve(l.value).then(O,E);D((u=u.apply(e,n)).next())});var we={};De(we,{DEFAULT_CONFIG:()=>c,JerseyDetector:()=>ee,useJerseyWorker:()=>$});module.exports=ke(we);var t=require("react");var f=require("react");var m=null,v=!1,F=null,Q=0,Z=null,T=new Map,Ie=0,X=new Map;function $(e,n){let u=(0,f.useRef)(!1),[y,s]=(0,f.useState)(!1),[O,E]=(0,f.useState)(null),D=(0,f.useRef)(!0),l=(0,f.useRef)(!1),b=(0,f.useRef)(`instance_${Math.random().toString(36).substr(2,9)}`),A=(0,f.useRef)(0);(0,f.useEffect)(()=>{var w;if(!e)return;D.current=!0,A.current++;let R=A.current,M=b.current,N=(w=X.get(M))!=null?w:0;return R>N&&(Q++,X.set(M,R)),W(null,null,function*(){var d;if(!m||!Re(Z,e)){m&&(m.terminate(),m=null,v=!1);try{l.current=(d=e.verbose)!=null?d:l.current;let a=n||"/jersey-detector-worker.js";m=new Worker(a),Z=e,v=!1,F=null,s(!1),E(null),m.onmessage=g=>{let i=g.data;switch(i.type){case"ready":v=!0,s(!0);break;case"loading_progress":l.current&&console.log(`[v0 useJerseyWorker] Loaded ${i.progress}% of ${i.file}`);break;case"debug":l.current&&console.log(i.debug_message);break;case"error":let _=i.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",_),v=!1,F=_,s(!1),E(_);break;case"detect_response":if(i.requestId&&T.has(i.requestId)){let p=T.get(i.requestId);p&&(p.resolve(i),T.delete(i.requestId))}else if(T.size>0){let p=T.entries().next();if(!p.done){let[B,x]=p.value;x.resolve(i),T.delete(B)}}break}},m.onerror=g=>{let i=g.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",i),v=!1,F=i,s(!1),E(i)},m.postMessage({type:"init",config:e})}catch(a){let g=(a==null?void 0:a.message)||String(a);console.error("[useJerseyWorker] Failed to create worker:",g),s(!1),E(g)}}else s(v),E(F)}),()=>{D.current=!1;let d=b.current,a=X.get(d),g=A.current;a===g&&(Q--,X.delete(d),Q<=0&&m&&(m.terminate(),m=null,v=!1,F=null,Z=null,T.clear()))}},[]);let G=(0,f.useCallback)((R,M,N=.5)=>W(null,null,function*(){if(!m||!v)throw new Error("Worker not ready");if(u.current)return null;let k=`req_${++Ie}_${Date.now()}`;return new Promise((w,d)=>{T.set(k,{resolve:w,reject:d});try{u.current=!0,m.postMessage({type:"detect",requestId:k,dimensions:M,bitmap:R,threshold:N},[R])}catch(a){T.delete(k);let g=`Failed to send detect: ${a==null?void 0:a.message}`;d(new Error(g))}finally{u.current=!1}setTimeout(()=>{T.has(k)&&(T.delete(k),d(new Error("Detection timeout")))},1e4)})}),[y]);return{isReady:y,workerReady:y,lastError:O,detect:G}}function Re(e,n){return e?JSON.stringify(e)===JSON.stringify(n):!1}var c={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};var ue=require("react/jsx-runtime"),ee=(0,t.forwardRef)(({videoRef:e,onWorkerReady:n,onWorkerError:u,onStatsUpdate:y,onSegmentedImage:s,task:O=c.TASK,model:E=c.MODEL,verbose:D=c.VERBOSE,bodyPixArchitecture:l=c.BODYPIX_ARCHITECTURE,bodyPixMultiplier:b=c.BODYPIX_MULTIPLIER,bodyPixQuantBytes:A=c.BODYPIX_QUANT_BYTES,bodyPixStride:G=c.BODYPIX_STRIDE,multiSegmentation:R=c.MULTI_SEGMENTATION,segmentBodyParts:M=c.SEGMENT_BODY_PARTS,backgroundShade:N=c.BACKGROUND_SHADE,shirtShade:k=c.SHIRT_SHADE,threshold:w=c.DETECTION_THRESHOLD,targetPartId:d=c.TARGET_PART_ID,imagesToReturn:a=c.IMAGES_TO_RETURN,workerUrl:g},i)=>{var te,ne;let _=(0,t.useRef)(null),p=(0,t.useRef)(null),B=(0,t.useRef)(!1),x=(0,t.useRef)([]),le=(0,t.useRef)(null),J=(0,t.useRef)(!1),Y=(0,t.useRef)(void 0);Y.current=u;let z=(0,t.useRef)({jerseyCount:0,confidence:0,fps:0,processingTime:0}),re=(0,t.useRef)(0),me=500,fe=(0,t.useMemo)(()=>({task:O,model:E,verbose:D,bodyPixArchitecture:l,bodyPixMultiplier:b,bodyPixQuantBytes:A,bodyPixStride:G,multiSegmentation:R,segmentBodyParts:M,backgroundShade:N,shirtShade:k,threshold:w,targetPartId:d,imagesToReturn:a}),[O,E,D,l,b,A,G,R,M,N,k,w,d,a]),de=(0,t.useMemo)(()=>{var r,o;return{width:((r=e.current)==null?void 0:r.videoWidth)||0,height:((o=e.current)==null?void 0:o.videoHeight)||0}},[(te=e.current)==null?void 0:te.videoWidth,(ne=e.current)==null?void 0:ne.videoHeight]),{isReady:H,workerReady:S,lastError:L,detect:ge}=$(fe,g);(0,t.useEffect)(()=>{n==null||n(S)},[S,n]),(0,t.useEffect)(()=>{var r;L&&(J.current=!0,(r=Y.current)==null||r.call(Y,L))},[L]);let ye=()=>W(null,null,function*(){var se,oe,ie;let r=e.current,o=_.current;if(J.current||!H||!S||!r||!o||B.current||r.readyState<2||r.paused||r.ended||r.videoWidth===0||r.videoHeight===0)return;let I=o.getContext("2d");if(!I||o.width<=0||o.height<=0)return;let C=null,P=null;try{B.current=!0;let U=r.videoWidth,j=r.videoHeight;le.current={width:U,height:j},C=yield createImageBitmap(r);let h=yield ge(C,de,w);if((h==null?void 0:h.type)==="detect_response"&&h.bitmap){P=h.bitmap,(o.width!==U||o.height!==j)&&(o.width=U,o.height=j),a==="mask"&&I.clearRect(0,0,U,j),P&&I.drawImage(P,0,0),x.current.push(Date.now()),x.current=x.current.filter(V=>Date.now()-V<1e3);let q={jerseyCount:((se=h.stats)==null?void 0:se.detectionCount)||0,confidence:((oe=h.stats)==null?void 0:oe.averageConfidence)||0,fps:x.current.length,processingTime:((ie=h.stats)==null?void 0:ie.processingTime)||0},ae=z.current;z.current=q;let ce=Date.now();if((ce-re.current>me||q.jerseyCount!==ae.jerseyCount||q.confidence!==ae.confidence)&&y&&(y(q),re.current=ce),h.segmentedImages){let V=h.segmentedImages;W(null,null,function*(){try{yield s==null?void 0:s(V)}finally{V.forEach(pe=>pe.close())}})}}}catch(U){J.current=!0}finally{C==null||C.close(),P==null||P.close(),B.current=!1}});return(0,t.useImperativeHandle)(i,()=>({get isReady(){return H},get lastError(){return L},get stats(){return z.current},capture:(r="image/jpeg",o=.92)=>{let I=_.current;if(!I)throw new Error("Canvas not ready for capture");return I.toDataURL(r,o)}}),[H,L,S]),(0,t.useEffect)(()=>{if(!S||!H||J.current)return;let r=e.current,o=_.current;if(!r||!o||r.videoWidth===0||r.videoHeight===0){let C=setTimeout(()=>{p.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(C)}(o.width!==r.videoWidth||o.height!==r.videoHeight)&&(o.width=r.videoWidth,o.height=r.videoHeight);let I=()=>W(null,null,function*(){!S||!H||J.current||(yield ye(),p.current=requestAnimationFrame(I))});return p.current=requestAnimationFrame(I),()=>{p.current&&cancelAnimationFrame(p.current)}},[S,H]),(0,ue.jsx)("canvas",{ref:_,className:"absolute inset-0 pointer-events-none",style:{zIndex:10,width:"100%",height:"100%"}})});ee.displayName="JerseyDetector";0&&(module.exports={DEFAULT_CONFIG,JerseyDetector,useJerseyWorker});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var R=(r,d,i)=>new Promise((T,n)=>{var w=t=>{try{k(i.next(t))}catch(E){n(E)}},f=t=>{try{k(i.throw(t))}catch(E){n(E)}},k=t=>t.done?T(t.value):Promise.resolve(t.value).then(w,f);k((i=i.apply(r,d)).next())});import{forwardRef as Te,useImperativeHandle as ke,useRef as S,useEffect as G,useState as De,useMemo as oe}from"react";import be from"react";import{useEffect as re,useState as te,useCallback as ge,useRef as $}from"react";var l=null,b=!1,W=null,U=0,F=null,m=new Map,ye=0;function q(r,d){let i=$(!1),[T,n]=te(!1),[w,f]=te(null),k=$(!0),t=$(!1);re(()=>{n(b),f(W)},[]),re(()=>r?(k.current=!0,U++,R(null,null,function*(){var I;if(!l||!pe(F,r)){l&&(console.log("[useJerseyWorker] Terminating old worker due to config change"),l.terminate(),l=null,b=!1);try{t.current=(I=r.verbose)!=null?I:t.current,console.log(`[useJerseyWorker] Verbose set to ${t.current}`);let u=d||"/jersey-detector-worker.js";console.log(`[useJerseyWorker] Initializing worker from: ${u}`),l=new Worker(u),F=r,b=!1,W=null,n(!1),f(null),l.onmessage=o=>{let e=o.data;switch(e.type){case"ready":b=!0,n(!0),console.log(`[v0 useJerseyWorker] Worker ready: ${e.task} | ${e.model} | device: ${e.device} | dtype: ${e.dtype}`);break;case"loading_progress":t.current&&console.log(`[v0 useJerseyWorker] Loaded ${e.progress}% of ${e.file}`);break;case"debug":t.current&&console.log(e.debug_message);break;case"error":let g=e.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",g),b=!1,W=g,n(!1),f(g);break;case"detect_response":if(e.requestId&&m.has(e.requestId)){let a=m.get(e.requestId);if(a){if(t.current){let y=e.stats;console.log(`Det count ${y.detectionCount} | Conf: ${y.averageConfidence} | proc time: ${y.processingTime}ms`)}a.resolve(e),m.delete(e.requestId)}}else if(m.size>0){let a=m.entries().next();if(!a.done){let[y,H]=a.value;H.resolve(e),m.delete(y)}}break}},l.onerror=o=>{let e=o.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",e),b=!1,W=e,n(!1),f(e)},l.postMessage({type:"init",config:r})}catch(u){let o=(u==null?void 0:u.message)||String(u);console.error("[useJerseyWorker] Failed to create worker:",o),n(!1),f(o)}}else n(b),f(W)}),()=>{k.current=!1,U--,U<=0&&l&&(console.log("[useJerseyWorker] Terminating worker (refCount 0)"),l.terminate(),l=null,b=!1,W=null,F=null,m.clear())}):void 0,[r]);let E=ge((h,I,u=.5)=>R(null,null,function*(){if(!l||!b)throw new Error("Worker not ready");if(i.current)return console.log("[v0 useJerseyWorker] New request before detection completed"),null;let o=`req_${++ye}_${Date.now()}`;return new Promise((e,g)=>{m.set(o,{resolve:e,reject:g});try{i.current=!0,l.postMessage({type:"detect",requestId:o,dimensions:I,bitmap:h,threshold:u},[h])}catch(a){m.delete(o);let y=`Failed to send detect: ${a==null?void 0:a.message}`;g(new Error(y))}finally{i.current=!1}setTimeout(()=>{m.has(o)&&(m.delete(o),g(new Error("Detection timeout")))},1e4)})}),[T]);return{isReady:T,workerReady:T,lastError:w,detect:E}}function pe(r,d){return r?JSON.stringify(r)===JSON.stringify(d):!1}var s={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,ONLY_DRAW_MASK:!0,VERBOSE:!1};var se=Te(({videoRef:r,onWorkerReady:d,onWorkerError:i,onStatsUpdate:T,onSegmentedImage:n,task:w=s.TASK,model:f=s.MODEL,verbose:k=s.VERBOSE,bodyPixArchitecture:t=s.BODYPIX_ARCHITECTURE,bodyPixMultiplier:E=s.BODYPIX_MULTIPLIER,bodyPixQuantBytes:h=s.BODYPIX_QUANT_BYTES,bodyPixStride:I=s.BODYPIX_STRIDE,multiSegmentation:u=s.MULTI_SEGMENTATION,segmentBodyParts:o=s.SEGMENT_BODY_PARTS,backgroundShade:e=s.BACKGROUND_SHADE,shirtShade:g=s.SHIRT_SHADE,threshold:a=s.DETECTION_THRESHOLD,targetPartId:y=s.TARGET_PART_ID,onlyDrawMask:H=s.ONLY_DRAW_MASK,workerUrl:ne},ie)=>{var K,V;let X=S(null),x=S(null),L=S(!1),B=S([]),ae=S(null),O=S(!1),[j,ce]=De({jerseyCount:0,confidence:0,fps:0,processingTime:0}),le=oe(()=>({task:w,model:f,verbose:k,bodyPixArchitecture:t,bodyPixMultiplier:E,bodyPixQuantBytes:h,bodyPixStride:I,multiSegmentation:u,segmentBodyParts:o,backgroundShade:e,shirtShade:g,threshold:a,targetPartId:y}),[w,f,k,t,E,h,I,u,o,e,g,a,y]),ue=oe(()=>{var c,D;return{width:((c=r.current)==null?void 0:c.videoWidth)||0,height:((D=r.current)==null?void 0:D.videoHeight)||0}},[(K=r.current)==null?void 0:K.videoWidth,(V=r.current)==null?void 0:V.videoHeight]),{isReady:_,workerReady:v,lastError:C,detect:fe}=q(le,ne);G(()=>{d==null||d(v)},[v,d]),G(()=>{C&&(O.current=!0,console.error("[v0] Worker error detected, stopping detection loop:",C)),i==null||i(C)},[C,i]);let me=()=>R(null,null,function*(){var z,Q,Z;let c=r.current,D=X.current;if(O.current||!v||!_||!c||!D||L.current||c.readyState<2||c.paused||c.ended)return;let N=null,A=null;try{L.current=!0;let M=c.videoWidth,J=c.videoHeight;ae.current={width:M,height:J},N=yield createImageBitmap(c);let p=yield fe(N,ue,a);if((p==null?void 0:p.type)==="detect_response"&&p.bitmap){A=p.bitmap;let Y=D.getContext("2d");Y&&((D.width!==M||D.height!==J)&&(D.width=M,D.height=J),H&&Y.clearRect(0,0,M,J),A&&Y.drawImage(A,0,0)),B.current.push(Date.now()),B.current=B.current.filter(P=>Date.now()-P<1e3);let ee={jerseyCount:((z=p.stats)==null?void 0:z.detectionCount)||0,confidence:((Q=p.stats)==null?void 0:Q.averageConfidence)||0,fps:B.current.length,processingTime:((Z=p.stats)==null?void 0:Z.processingTime)||0};if(ce(ee),T==null||T(ee),p.segmentedImages){let P=p.segmentedImages;R(null,null,function*(){try{yield n==null?void 0:n(P)}finally{P.forEach(de=>de.close())}})}}}catch(M){console.error("[v0] Detection error:",M),O.current=!0}finally{N&&N.close(),A&&A.close(),L.current=!1}});return G(()=>{if(!v||!_||O.current)return;let c=()=>R(null,null,function*(){!v||!_||O.current||(yield me(),x.current=requestAnimationFrame(c))});return x.current=requestAnimationFrame(c),()=>{x.current&&cancelAnimationFrame(x.current)}},[v,_]),ke(ie,()=>({isReady:_,lastError:C,stats:j}),[_,C,j]),be.createElement("canvas",{ref:X,className:"absolute inset-0 w-full h-full pointer-events-none",style:{zIndex:10}})});se.displayName="JerseyDetector";export{s as DEFAULT_CONFIG,se as JerseyDetector,q as useJerseyWorker};
1
+ var C=(t,d,g)=>new Promise((k,a)=>{var W=o=>{try{T(g.next(o))}catch(E){a(E)}},y=o=>{try{T(g.throw(o))}catch(E){a(E)}},T=o=>o.done?k(o.value):Promise.resolve(o.value).then(W,y);T((g=g.apply(t,d)).next())});import{forwardRef as ke,useImperativeHandle as Ie,useRef as b,useEffect as Z,useMemo as ue}from"react";import{useEffect as Ee,useState as ce,useCallback as he,useRef as U}from"react";var c=null,_=!1,F=null,z=0,K=null,f=new Map,De=0,X=new Map;function Q(t,d){let g=U(!1),[k,a]=ce(!1),[W,y]=ce(null),T=U(!0),o=U(!1),E=U(`instance_${Math.random().toString(36).substr(2,9)}`),O=U(0);Ee(()=>{var R;if(!t)return;T.current=!0,O.current++;let I=O.current,v=E.current,A=(R=X.get(v))!=null?R:0;return I>A&&(z++,X.set(v,I)),C(null,null,function*(){var u;if(!c||!be(K,t)){c&&(c.terminate(),c=null,_=!1);try{o.current=(u=t.verbose)!=null?u:o.current;let s=d||"/jersey-detector-worker.js";c=new Worker(s),K=t,_=!1,F=null,a(!1),y(null),c.onmessage=l=>{let n=l.data;switch(n.type){case"ready":_=!0,a(!0);break;case"loading_progress":o.current&&console.log(`[v0 useJerseyWorker] Loaded ${n.progress}% of ${n.file}`);break;case"debug":o.current&&console.log(n.debug_message);break;case"error":let w=n.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",w),_=!1,F=w,a(!1),y(w);break;case"detect_response":if(n.requestId&&f.has(n.requestId)){let m=f.get(n.requestId);m&&(m.resolve(n),f.delete(n.requestId))}else if(f.size>0){let m=f.entries().next();if(!m.done){let[P,N]=m.value;N.resolve(n),f.delete(P)}}break}},c.onerror=l=>{let n=l.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",n),_=!1,F=n,a(!1),y(n)},c.postMessage({type:"init",config:t})}catch(s){let l=(s==null?void 0:s.message)||String(s);console.error("[useJerseyWorker] Failed to create worker:",l),a(!1),y(l)}}else a(_),y(F)}),()=>{T.current=!1;let u=E.current,s=X.get(u),l=O.current;s===l&&(z--,X.delete(u),z<=0&&c&&(c.terminate(),c=null,_=!1,F=null,K=null,f.clear()))}},[]);let G=he((I,v,A=.5)=>C(null,null,function*(){if(!c||!_)throw new Error("Worker not ready");if(g.current)return null;let h=`req_${++De}_${Date.now()}`;return new Promise((R,u)=>{f.set(h,{resolve:R,reject:u});try{g.current=!0,c.postMessage({type:"detect",requestId:h,dimensions:v,bitmap:I,threshold:A},[I])}catch(s){f.delete(h);let l=`Failed to send detect: ${s==null?void 0:s.message}`;u(new Error(l))}finally{g.current=!1}setTimeout(()=>{f.has(h)&&(f.delete(h),u(new Error("Detection timeout")))},1e4)})}),[k]);return{isReady:k,workerReady:k,lastError:W,detect:G}}function be(t,d){return t?JSON.stringify(t)===JSON.stringify(d):!1}var i={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};import{jsx as Re}from"react/jsx-runtime";var le=ke(({videoRef:t,onWorkerReady:d,onWorkerError:g,onStatsUpdate:k,onSegmentedImage:a,task:W=i.TASK,model:y=i.MODEL,verbose:T=i.VERBOSE,bodyPixArchitecture:o=i.BODYPIX_ARCHITECTURE,bodyPixMultiplier:E=i.BODYPIX_MULTIPLIER,bodyPixQuantBytes:O=i.BODYPIX_QUANT_BYTES,bodyPixStride:G=i.BODYPIX_STRIDE,multiSegmentation:I=i.MULTI_SEGMENTATION,segmentBodyParts:v=i.SEGMENT_BODY_PARTS,backgroundShade:A=i.BACKGROUND_SHADE,shirtShade:h=i.SHIRT_SHADE,threshold:R=i.DETECTION_THRESHOLD,targetPartId:u=i.TARGET_PART_ID,imagesToReturn:s=i.IMAGES_TO_RETURN,workerUrl:l},n)=>{var re,te;let w=b(null),m=b(null),P=b(!1),N=b([]),me=b(null),B=b(!1),Y=b(void 0);Y.current=g;let $=b({jerseyCount:0,confidence:0,fps:0,processingTime:0}),ee=b(0),fe=500,de=ue(()=>({task:W,model:y,verbose:T,bodyPixArchitecture:o,bodyPixMultiplier:E,bodyPixQuantBytes:O,bodyPixStride:G,multiSegmentation:I,segmentBodyParts:v,backgroundShade:A,shirtShade:h,threshold:R,targetPartId:u,imagesToReturn:s}),[W,y,T,o,E,O,G,I,v,A,h,R,u,s]),ge=ue(()=>{var e,r;return{width:((e=t.current)==null?void 0:e.videoWidth)||0,height:((r=t.current)==null?void 0:r.videoHeight)||0}},[(re=t.current)==null?void 0:re.videoWidth,(te=t.current)==null?void 0:te.videoHeight]),{isReady:x,workerReady:M,lastError:J,detect:ye}=Q(de,l);Z(()=>{d==null||d(M)},[M,d]),Z(()=>{var e;J&&(B.current=!0,(e=Y.current)==null||e.call(Y,J))},[J]);let pe=()=>C(null,null,function*(){var ne,se,oe;let e=t.current,r=w.current;if(B.current||!x||!M||!e||!r||P.current||e.readyState<2||e.paused||e.ended||e.videoWidth===0||e.videoHeight===0)return;let D=r.getContext("2d");if(!D||r.width<=0||r.height<=0)return;let S=null,H=null;try{P.current=!0;let L=e.videoWidth,j=e.videoHeight;me.current={width:L,height:j},S=yield createImageBitmap(e);let p=yield ye(S,ge,R);if((p==null?void 0:p.type)==="detect_response"&&p.bitmap){H=p.bitmap,(r.width!==L||r.height!==j)&&(r.width=L,r.height=j),s==="mask"&&D.clearRect(0,0,L,j),H&&D.drawImage(H,0,0),N.current.push(Date.now()),N.current=N.current.filter(V=>Date.now()-V<1e3);let q={jerseyCount:((ne=p.stats)==null?void 0:ne.detectionCount)||0,confidence:((se=p.stats)==null?void 0:se.averageConfidence)||0,fps:N.current.length,processingTime:((oe=p.stats)==null?void 0:oe.processingTime)||0},ie=$.current;$.current=q;let ae=Date.now();if((ae-ee.current>fe||q.jerseyCount!==ie.jerseyCount||q.confidence!==ie.confidence)&&k&&(k(q),ee.current=ae),p.segmentedImages){let V=p.segmentedImages;C(null,null,function*(){try{yield a==null?void 0:a(V)}finally{V.forEach(Te=>Te.close())}})}}}catch(L){B.current=!0}finally{S==null||S.close(),H==null||H.close(),P.current=!1}});return Ie(n,()=>({get isReady(){return x},get lastError(){return J},get stats(){return $.current},capture:(e="image/jpeg",r=.92)=>{let D=w.current;if(!D)throw new Error("Canvas not ready for capture");return D.toDataURL(e,r)}}),[x,J,M]),Z(()=>{if(!M||!x||B.current)return;let e=t.current,r=w.current;if(!e||!r||e.videoWidth===0||e.videoHeight===0){let S=setTimeout(()=>{m.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(S)}(r.width!==e.videoWidth||r.height!==e.videoHeight)&&(r.width=e.videoWidth,r.height=e.videoHeight);let D=()=>C(null,null,function*(){!M||!x||B.current||(yield pe(),m.current=requestAnimationFrame(D))});return m.current=requestAnimationFrame(D),()=>{m.current&&cancelAnimationFrame(m.current)}},[M,x]),Re("canvas",{ref:w,className:"absolute inset-0 pointer-events-none",style:{zIndex:10,width:"100%",height:"100%"}})});le.displayName="JerseyDetector";export{i as DEFAULT_CONFIG,le as JerseyDetector,Q as useJerseyWorker};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seg-cam",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -82213,10 +82213,13 @@ var handleInit = async (message) => {
82213
82213
  sendDebug(`[Worker] Runing in production: ${isProduction}`);
82214
82214
  await loadModules();
82215
82215
  await BodyPixSegmenter.getInstance();
82216
+ const device = tf.backend().device ? tf.backend().device : "unknown";
82216
82217
  self.postMessage({
82217
82218
  type: "ready",
82218
82219
  task: config.task,
82219
- model: "BodyPix"
82220
+ model: "BodyPix",
82221
+ device,
82222
+ dtype: "float32"
82220
82223
  });
82221
82224
  modelLoaded = true;
82222
82225
  } catch (error) {
@@ -82229,6 +82232,7 @@ var handleDetect = async (message) => {
82229
82232
  const { requestId, dimensions, bitmap: inputBitmap, threshold: threshold3 } = message;
82230
82233
  let outputBitmap;
82231
82234
  try {
82235
+ console.log("[Worker] handleDetect called with requestId:", requestId, "dimensions:", dimensions, "bitmap:", !!inputBitmap, "threshold:", threshold3);
82232
82236
  if (isProcessing) {
82233
82237
  throw new Error("New request before previous finished");
82234
82238
  }
@@ -82347,12 +82351,15 @@ var handleDetect = async (message) => {
82347
82351
  };
82348
82352
  self.onmessage = async (event) => {
82349
82353
  const message = event.data;
82354
+ console.log("[Worker] Received message type:", message.type, "requestId:", message.requestId);
82350
82355
  try {
82351
82356
  switch (message.type) {
82352
82357
  case "init":
82358
+ console.log("[Worker] Processing init message");
82353
82359
  await handleInit(message);
82354
82360
  break;
82355
82361
  case "detect":
82362
+ console.log("[Worker] Processing detect message with requestId:", message.requestId);
82356
82363
  await handleDetect(message);
82357
82364
  break;
82358
82365
  default: