4
4
// https://opensource.org/licenses/MIT
5
5
6
6
/*
7
- COCO-SSD Object detection
7
+ COCO-SSD Object detection model
8
8
Wraps the coco-ssd model in tfjs to be used in ml5
9
9
*/
10
10
import * as tf from "@tensorflow/tfjs" ;
11
11
import * as cocoSsd from "@tensorflow-models/coco-ssd" ;
12
- import callCallback from "../utils/callcallback" ;
13
- import handleArguments from "../utils/handleArguments" ;
14
12
import { mediaReady } from "../utils/imageUtilities" ;
15
13
16
14
const DEFAULTS = {
17
15
base : "lite_mobilenet_v2" ,
18
16
modelUrl : undefined ,
19
17
} ;
20
18
21
- export class CocoSsdBase {
22
- /**
23
- * Create CocoSsd model. Works on video and images.
24
- * @param {function } constructorCallback - Optional. A callback function that is called once the model has loaded. If no callback is provided, it will return a promise
25
- * that will be resolved once the model has loaded.
26
- */
27
- constructor ( video , options , constructorCallback ) {
28
- this . video = video || null ;
29
- this . modelReady = false ;
30
-
31
- this . isPredicting = false ;
32
- this . signalStop = false ;
33
- this . prevCall = "" ;
34
-
19
+ export class CocoSsd {
20
+ constructor ( options = { } ) {
21
+ this . model = null ;
35
22
this . config = {
36
23
base : options . base || DEFAULTS . base ,
37
24
modelUrl : options . modelUrl || DEFAULTS . modelUrl ,
38
25
} ;
39
- this . callback = constructorCallback ;
40
-
41
- this . ready = callCallback ( this . loadModel ( ) , this . callback ) ;
42
26
}
43
27
44
- async loadModel ( ) {
28
+ async load ( ) {
45
29
await tf . setBackend ( "webgl" ) ; // this line resolves warning : performance is poor on webgpu backend
46
30
await tf . ready ( ) ;
47
31
48
32
this . model = await cocoSsd . load ( this . config ) ;
49
-
50
- this . modelReady = true ;
51
33
return this ;
52
34
}
53
35
54
36
/**
55
- * @typedef {Object } ObjectDetectorPrediction
56
- * @property {number } x - top left x coordinate of the prediction box in pixels.
57
- * @property {number } y - top left y coordinate of the prediction box in pixels.
58
- * @property {number } width - width of the prediction box in pixels.
59
- * @property {number } height - height of the prediction box in pixels.
60
- * @property {string } label - the label given.
61
- * @property {number } confidence - the confidence score (0 to 1).
62
- * @property {ObjectDetectorPredictionNormalized } normalized - a normalized object of the predicition
37
+ * Detect objects that are in the image/video/canvas
38
+ * @param {HTMLVideoElement|HTMLImageElement|HTMLCanvasElement|ImageData } imgToPredict - Subject of the detection.
39
+ * @returns {Array } Array of detection detections
63
40
*/
64
-
65
- /**
66
- * @typedef {Object } ObjectDetectorPredictionNormalized
67
- * @property {number } x - top left x coordinate of the prediction box (0 to 1).
68
- * @property {number } y - top left y coordinate of the prediction box (0 to 1).
69
- * @property {number } width - width of the prediction box (0 to 1).
70
- * @property {number } height - height of the prediction box (0 to 1).
71
- */
72
- /**
73
- * Detect objects that are in video, returns bounding box, label, and confidence scores
74
- * @param {HTMLVideoElement|HTMLImageElement|HTMLCanvasElement|ImageData } subject - Subject of the detection.
75
- * @returns {ObjectDetectorPrediction }
76
- */
77
- async detectInternal ( imgToPredict ) {
78
- // this.isPredicting = true;
79
- await this . ready ;
80
-
41
+ async detect ( imgToPredict ) {
81
42
mediaReady ( imgToPredict , true ) ;
82
-
83
43
await tf . nextFrame ( ) ;
84
44
85
- const predictions = await this . model . detect ( imgToPredict ) ;
86
- const formattedPredictions = predictions . map ( prediction => {
45
+ const detections = await this . model . detect ( imgToPredict ) ;
46
+ const formattedDetections = detections . map ( prediction => {
87
47
return {
88
48
label : prediction . class ,
89
49
confidence : prediction . score ,
@@ -100,66 +60,12 @@ export class CocoSsdBase {
100
60
} ;
101
61
} ) ;
102
62
103
- this . isPredicting = false ;
104
-
105
- return formattedPredictions ;
106
- }
107
-
108
- /**
109
- * Detect objects that are in video, returns bounding box, label, and confidence scores
110
- * @param {HTMLVideoElement|HTMLImageElement|HTMLCanvasElement|ImageData } subject - Subject of the detection.
111
- * @param {function } callback - Optional. A callback function that is called once the model has loaded. If no callback is provided, it will return a promise
112
- * that will be resolved once the prediction is done.
113
- * @returns {ObjectDetectorPrediction }
114
- */
115
- async detect ( inputOrCallback , cb ) {
116
- const args = handleArguments ( this . video , inputOrCallback , cb ) ;
117
- args . require ( "image" , "Detection subject not supported" ) ;
118
-
119
- return callCallback ( this . detectInternal ( args . image ) , args . callback ) ;
120
- }
121
-
122
- async detectStart ( inputNumOrCallback , numOrCallback , cb ) {
123
- const { image, number, callback } = handleArguments (
124
- inputNumOrCallback ,
125
- numOrCallback ,
126
- cb
127
- ) . require ( "image" , "No input provided." ) ;
128
-
129
- const detectFrame = async ( ) => {
130
- await mediaReady ( image , true ) ;
131
-
132
- await callCallback ( this . detectInternal ( image ) , callback ) ;
133
-
134
- if ( ! this . signalStop ) {
135
- requestAnimationFrame ( detectFrame ) ;
136
- } else {
137
- this . isPredicting = false ;
138
- }
139
- } ;
140
-
141
- // start the detection
142
- this . signalStop = false ;
143
- if ( ! this . isPredicting ) {
144
- this . isPredicting = true ;
145
- detectFrame ( ) ;
146
- }
147
-
148
- if ( this . prevCall === "start" ) {
149
- console . warn ( "warning" ) ;
150
- }
151
- this . prevCall = "start" ;
152
- }
153
-
154
- detectStop ( ) {
155
- if ( this . isPredicting ) { this . signalStop = true ; }
156
- this . prevCall = "stop" ;
63
+ return formattedDetections ;
157
64
}
158
65
}
159
66
160
- export const CocoSsd = ( ...inputs ) => {
161
- const { video, options = { } , callback } = handleArguments ( ...inputs ) ;
162
- return new CocoSsdBase ( video , options , callback ) ;
163
- } ;
164
-
165
- export default CocoSsd ;
67
+ export async function load ( modelConfig = { } ) {
68
+ const cocoSsdInstance = new CocoSsd ( modelConfig ) ;
69
+ await cocoSsdInstance . load ( ) ;
70
+ return cocoSsdInstance ;
71
+ }
0 commit comments