17
17
18
18
import * as tf from '@tensorflow/tfjs-core' ;
19
19
// tslint:disable-next-line: no-imports-from-dist
20
- import { ALL_ENVS , BROWSER_ENVS , describeWithFlags } from '@tensorflow/tfjs-core/dist/jasmine_util' ;
20
+ import { ALL_ENVS , BROWSER_ENVS , describeWithFlags } from '@tensorflow/tfjs-core/dist/jasmine_util' ;
21
21
// tslint:disable-next-line: no-imports-from-dist
22
- import { expectArraysClose } from '@tensorflow/tfjs-core/dist/test_util' ;
23
- import { MEDIAPIPE_CONNECTED_KEYPOINTS_PAIRS } from '../constants' ;
22
+ import { expectArraysClose } from '@tensorflow/tfjs-core/dist/test_util' ;
23
+ import { MEDIAPIPE_CONNECTED_KEYPOINTS_PAIRS } from '../constants' ;
24
24
25
25
import * as handPoseDetection from '../index' ;
26
- import { getXYPerFrame , KARMA_SERVER , loadImage , loadVideo } from '../shared/test_util' ;
26
+ import { getXYPerFrame , KARMA_SERVER , loadImage , loadVideo } from '../shared/test_util' ;
27
27
28
28
// Measured in pixels.
29
29
const EPSILON_IMAGE = 12 ;
30
30
// Measured in pixels.
31
- const EPSILON_VIDEO = 18 ;
31
+ const EPSILON_VIDEO = 22 ;
32
32
// Measured in meters.
33
- const EPSILON_VIDEO_WORLD = 0.01 ;
33
+ const EPSILON_VIDEO_WORLD = 0.012 ;
34
34
35
35
// ref:
36
36
// https://github.com/google/mediapipe/blob/master/mediapipe/python/solutions/hands_test.py
37
37
const EXPECTED_HAND_KEYPOINTS_PREDICTION = [
38
38
[
39
- [ 580 , 34 ] , [ 504 , 50 ] , [ 459 , 94 ] , [ 429 , 146 ] , [ 397 , 182 ] , [ 507 , 167 ] ,
39
+ [ 580 , 34 ] , [ 504 , 50 ] , [ 459 , 94 ] , [ 429 , 146 ] , [ 397 , 182 ] , [ 507 , 167 ] ,
40
40
[ 479 , 245 ] , [ 469 , 292 ] , [ 464 , 330 ] , [ 545 , 180 ] , [ 534 , 265 ] , [ 533 , 319 ] ,
41
41
[ 536 , 360 ] , [ 581 , 172 ] , [ 587 , 252 ] , [ 593 , 304 ] , [ 599 , 346 ] , [ 615 , 168 ] ,
42
42
[ 628 , 223 ] , [ 638 , 258 ] , [ 648 , 288 ]
43
43
] ,
44
44
[
45
45
[ 138 , 343 ] , [ 211 , 330 ] , [ 257 , 286 ] , [ 289 , 237 ] , [ 322 , 203 ] , [ 219 , 216 ] ,
46
- [ 238 , 138 ] , [ 249 , 90 ] , [ 253 , 51 ] , [ 177 , 204 ] , [ 184 , 115 ] , [ 187 , 60 ] ,
47
- [ 185 , 19 ] , [ 138 , 208 ] , [ 131 , 127 ] , [ 124 , 77 ] , [ 117 , 36 ] , [ 106 , 222 ] ,
48
- [ 92 , 159 ] , [ 79 , 124 ] , [ 68 , 93 ]
46
+ [ 238 , 138 ] , [ 249 , 90 ] , [ 253 , 51 ] , [ 177 , 204 ] , [ 184 , 115 ] , [ 187 , 60 ] ,
47
+ [ 185 , 19 ] , [ 138 , 208 ] , [ 131 , 127 ] , [ 124 , 77 ] , [ 117 , 36 ] , [ 106 , 222 ] ,
48
+ [ 92 , 159 ] , [ 79 , 124 ] , [ 68 , 93 ]
49
49
]
50
50
] ;
51
51
@@ -66,7 +66,7 @@ describeWithFlags('MediaPipeHands', ALL_ENVS, () => {
66
66
67
67
// Note: this makes a network request for model assets.
68
68
const detector = await handPoseDetection . createDetector (
69
- handPoseDetection . SupportedModels . MediaPipeHands , { runtime : 'tfjs' } ) ;
69
+ handPoseDetection . SupportedModels . MediaPipeHands , { runtime : 'tfjs' } ) ;
70
70
const input : tf . Tensor3D = tf . zeros ( [ 128 , 128 , 3 ] ) ;
71
71
72
72
const beforeTensors = tf . memory ( ) . numTensors ;
@@ -84,12 +84,12 @@ describeWithFlags('MediaPipeHands', ALL_ENVS, () => {
84
84
it ( 'throws error when runtime is not set.' , async ( done ) => {
85
85
try {
86
86
await handPoseDetection . createDetector (
87
- handPoseDetection . SupportedModels . MediaPipeHands ) ;
87
+ handPoseDetection . SupportedModels . MediaPipeHands ) ;
88
88
done . fail ( 'Loading without runtime succeeded unexpectedly.' ) ;
89
89
} catch ( e ) {
90
90
expect ( e . message ) . toEqual (
91
- `Expect modelConfig.runtime to be either ` +
92
- `'tfjs' or 'mediapipe', but got undefined` ) ;
91
+ `Expect modelConfig.runtime to be either ` +
92
+ `'tfjs' or 'mediapipe', but got undefined` ) ;
93
93
done ( ) ;
94
94
}
95
95
} ) ;
@@ -102,7 +102,7 @@ describeWithFlags('MediaPipeHands static image ', BROWSER_ENVS, () => {
102
102
103
103
beforeAll ( async ( ) => {
104
104
timeout = jasmine . DEFAULT_TIMEOUT_INTERVAL ;
105
- jasmine . DEFAULT_TIMEOUT_INTERVAL = 120000 ; // 2mins
105
+ jasmine . DEFAULT_TIMEOUT_INTERVAL = 240000 ; // 2mins
106
106
image = await loadImage ( 'hands.jpg' , 720 , 382 ) ;
107
107
} ) ;
108
108
@@ -115,19 +115,19 @@ describeWithFlags('MediaPipeHands static image ', BROWSER_ENVS, () => {
115
115
116
116
// Note: this makes a network request for model assets.
117
117
detector = await handPoseDetection . createDetector (
118
- handPoseDetection . SupportedModels . MediaPipeHands ,
119
- { runtime : 'tfjs' , modelType : 'lite' } ) ;
118
+ handPoseDetection . SupportedModels . MediaPipeHands ,
119
+ { runtime : 'tfjs' , modelType : 'lite' } ) ;
120
120
121
121
const beforeTensors = tf . memory ( ) . numTensors ;
122
122
123
123
const result = await detector . estimateHands ( image , {
124
124
staticImageMode : true
125
125
} as handPoseDetection . MediaPipeHandsTfjsEstimationConfig ) ;
126
126
const keypoints = result . map (
127
- hand => hand . keypoints . map ( keypoint => [ keypoint . x , keypoint . y ] ) ) ;
127
+ hand => hand . keypoints . map ( keypoint => [ keypoint . x , keypoint . y ] ) ) ;
128
128
129
129
expectArraysClose (
130
- keypoints , EXPECTED_HAND_KEYPOINTS_PREDICTION , EPSILON_IMAGE ) ;
130
+ keypoints , EXPECTED_HAND_KEYPOINTS_PREDICTION , EPSILON_IMAGE ) ;
131
131
132
132
expect ( tf . memory ( ) . numTensors ) . toEqual ( beforeTensors ) ;
133
133
@@ -141,19 +141,19 @@ describeWithFlags('MediaPipeHands static image ', BROWSER_ENVS, () => {
141
141
142
142
// Note: this makes a network request for model assets.
143
143
detector = await handPoseDetection . createDetector (
144
- handPoseDetection . SupportedModels . MediaPipeHands ,
145
- { runtime : 'tfjs' , modelType : 'full' } ) ;
144
+ handPoseDetection . SupportedModels . MediaPipeHands ,
145
+ { runtime : 'tfjs' , modelType : 'full' } ) ;
146
146
147
147
const beforeTensors = tf . memory ( ) . numTensors ;
148
148
149
149
const result = await detector . estimateHands ( image , {
150
150
staticImageMode : true
151
151
} as handPoseDetection . MediaPipeHandsTfjsEstimationConfig ) ;
152
152
const keypoints = result . map (
153
- hand => hand . keypoints . map ( keypoint => [ keypoint . x , keypoint . y ] ) ) ;
153
+ hand => hand . keypoints . map ( keypoint => [ keypoint . x , keypoint . y ] ) ) ;
154
154
155
155
expectArraysClose (
156
- keypoints , EXPECTED_HAND_KEYPOINTS_PREDICTION , EPSILON_IMAGE ) ;
156
+ keypoints , EXPECTED_HAND_KEYPOINTS_PREDICTION , EPSILON_IMAGE ) ;
157
157
158
158
expect ( tf . memory ( ) . numTensors ) . toEqual ( beforeTensors ) ;
159
159
@@ -174,11 +174,11 @@ describeWithFlags('MediaPipe Hands video ', BROWSER_ENVS, () => {
174
174
jasmine . DEFAULT_TIMEOUT_INTERVAL = 120000 ; // 2mins
175
175
176
176
expected = await fetch ( `${ KARMA_SERVER } /asl_hand.full.json` )
177
- . then ( response => response . json ( ) )
178
- . then ( result => getXYPerFrame ( result ) ) ;
177
+ . then ( response => response . json ( ) )
178
+ . then ( result => getXYPerFrame ( result ) ) ;
179
179
180
180
expected3D = await fetch ( `${ KARMA_SERVER } /asl_hand_3d.full.json` )
181
- . then ( response => response . json ( ) ) ;
181
+ . then ( response => response . json ( ) ) ;
182
182
} ) ;
183
183
184
184
afterAll ( ( ) => {
@@ -189,25 +189,25 @@ describeWithFlags('MediaPipe Hands video ', BROWSER_ENVS, () => {
189
189
// Note: this makes a network request for model assets.
190
190
const model = handPoseDetection . SupportedModels . MediaPipeHands ;
191
191
detector = await handPoseDetection . createDetector (
192
- model , { runtime : 'tfjs' , maxHands : 1 } ) ;
192
+ model , { runtime : 'tfjs' , maxHands : 1 } ) ;
193
193
194
194
const result : number [ ] [ ] [ ] = [ ] ;
195
195
const result3D : number [ ] [ ] [ ] = [ ] ;
196
196
197
- const callback = async ( video : HTMLVideoElement , timestamp : number ) :
198
- Promise < handPoseDetection . Keypoint [ ] > => {
199
- const hands = await detector . estimateHands ( video , null /* config */ ) ;
197
+ const callback = async ( video : HTMLVideoElement , timestamp : number ) :
198
+ Promise < handPoseDetection . Keypoint [ ] > => {
199
+ const hands = await detector . estimateHands ( video , null /* config */ ) ;
200
200
201
- // maxNumHands is set to 1.
202
- result . push ( hands [ 0 ] . keypoints . map ( kp => [ kp . x , kp . y ] ) ) ;
203
- result3D . push ( hands [ 0 ] . keypoints3D . map ( kp => [ kp . x , kp . y , kp . z ] ) ) ;
201
+ // maxNumHands is set to 1.
202
+ result . push ( hands [ 0 ] . keypoints . map ( kp => [ kp . x , kp . y ] ) ) ;
203
+ result3D . push ( hands [ 0 ] . keypoints3D . map ( kp => [ kp . x , kp . y , kp . z ] ) ) ;
204
204
205
- return hands [ 0 ] . keypoints ;
206
- } ;
205
+ return hands [ 0 ] . keypoints ;
206
+ } ;
207
207
208
208
await loadVideo (
209
- 'asl_hand.25fps.mp4' , 25 /* fps */ , callback , expected ,
210
- MEDIAPIPE_CONNECTED_KEYPOINTS_PAIRS , 0 /* simulatedInterval unused */ ) ;
209
+ 'asl_hand.25fps.mp4' , 25 /* fps */ , callback , expected ,
210
+ MEDIAPIPE_CONNECTED_KEYPOINTS_PAIRS , 0 /* simulatedInterval unused */ ) ;
211
211
212
212
expectArraysClose ( result , expected , EPSILON_VIDEO ) ;
213
213
expectArraysClose ( result3D , expected3D , EPSILON_VIDEO_WORLD ) ;
0 commit comments