Skip to content

Commit f863868

Browse files
committed
fices some of the travis-ci errors
1 parent b0f1f06 commit f863868

File tree

1 file changed

+66
-96
lines changed

1 file changed

+66
-96
lines changed

src/YOLO/index.js

Lines changed: 66 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@
77
YOLO Object detection
88
Heavily derived from https://github.com/ModelDepot/tfjs-yolo-tiny (ModelDepot: modeldepot.io)
99
*/
10-
import * as tf from "@tensorflow/tfjs";
11-
import CLASS_NAMES from "./../utils/COCO_CLASSES";
10+
import * as tf from '@tensorflow/tfjs';
11+
import CLASS_NAMES from './../utils/COCO_CLASSES';
1212

1313
const DEFAULTS = {
1414
filterBoxesThreshold: 0.01,
1515
IOUThreshold: 0.4,
1616
classProbThreshold: 0.4,
17-
URL:
18-
"https://raw.githubusercontent.com/ml5js/ml5-library/master/src/YOLO/model.json"
17+
URL: 'https://raw.githubusercontent.com/ml5js/ml5-library/master/src/YOLO/model.json'
18+
1919
};
2020

2121
class YOLO {
2222
constructor(options) {
2323
this.filterBoxesThreshold = options.filterBoxesThreshold || DEFAULTS.filterBoxesThreshold;
2424
this.IOUThreshold = options.IOUThreshold || DEFAULTS.IOUThreshold;
25-
this.classProbThreshold =options.classProbThreshold || DEFAULTS.classProbThreshold;
25+
this.classProbThreshold = options.classProbThreshold || DEFAULTS.classProbThreshold;
2626
this.modelURL = options.url || DEFAULTS.URL;
2727
this.model = null;
2828
this.inputWidth = 416;
@@ -33,18 +33,18 @@ class YOLO {
3333
[1.87446, 2.06253],
3434
[3.33843, 5.47434],
3535
[7.88282, 3.52778],
36-
[9.77052, 9.16828]
36+
[9.77052, 9.16828],
3737
];
38-
this.scaleX;
39-
this.scaleY;
38+
// this.scaleX;
39+
// this.scaleY;
4040
this.anchorsLength = this.anchors.length;
4141
this.classesLength = this.classNames.length;
4242
this.init();
4343
}
4444

4545
init() {
4646
// indices tensor to filter the elements later on
47-
this.indicesTensor = tf.range(1, 846, 1, "int32");
47+
this.indicesTensor = tf.range(1, 846, 1, 'int32');
4848

4949
// Grid To Split the raw predictions : Assumes Our Model output is 1 Tensor with 13x13x425
5050
// gonna hard code all this stuff see if it works
@@ -53,18 +53,18 @@ class YOLO {
5353

5454
[this.ConvIndex, this.ConvDims, this.AnchorsTensor] = tf.tidy(() => {
5555
let ConvIndex = tf.range(0, 13);
56-
let ConvHeightIndex = tf.tile(ConvIndex, [13]);
56+
const ConvHeightIndex = tf.tile(ConvIndex, [13]);
5757

5858
let ConvWidthindex = tf.tile(tf.expandDims(ConvIndex, 0), [13, 1]);
5959
ConvWidthindex = tf.transpose(ConvWidthindex).flatten();
6060

6161
ConvIndex = tf.transpose(tf.stack([ConvHeightIndex, ConvWidthindex]));
6262
ConvIndex = tf.reshape(ConvIndex, [13, 13, 1, 2]);
6363

64-
let ConvDims = tf.reshape(tf.tensor1d([13, 13]), [1, 1, 1, 2]);
65-
//AnchorsTensor
66-
let Aten = tf.tensor2d(this.anchors);
67-
let AnchorsTensor = tf.reshape(Aten, [1, 1, this.anchorsLength, 2]);
64+
const ConvDims = tf.reshape(tf.tensor1d([13, 13]), [1, 1, 1, 2]);
65+
// AnchorsTensor
66+
const Aten = tf.tensor2d(this.anchors);
67+
const AnchorsTensor = tf.reshape(Aten, [1, 1, this.anchorsLength, 2]);
6868

6969
return [ConvIndex, ConvDims, AnchorsTensor];
7070
});
@@ -94,6 +94,7 @@ class YOLO {
9494

9595
//does not dispose of the model atm
9696
dispose() {
97+
this.model = null;
9798
tf.disposeconstiables();
9899
}
99100

@@ -109,31 +110,31 @@ class YOLO {
109110
let img = tf.fromPixels(input);
110111
this.imgWidth = img.shape[1];
111112
this.imgHeight = img.shape[0];
112-
img = tf.image.resizeBilinear(img, [this.inputHeight, this.inputWidth])
113-
.toFloat()
114-
.div(tf.scalar(255))
115-
.expandDims(0);
116-
//Scale Stuff
113+
img = tf.image.resizeBilinear(img, [this.inputHeight, this.inputWidth]).toFloat().div(tf.scalar(255)).expandDims(0);
114+
115+
116+
117+
// Scale Stuff
117118
this.scaleX = this.imgHeight / this.inputHeight;
118119
this.scaleY = this.imgWidth / this.inputWidth;
119120
return img;
120121
}
121122

122123
async postProccess(rawPrediction) {
123-
let results = {
124+
const results = {
124125
totalDetections: 0,
125-
detections: []
126+
detections: [],
126127
};
128+
const [boxes, boxScores, classes, Indices,] = tf.tidy(() => {
127129

128-
const [boxes, boxScores, classes, Indices] = tf.tidy(() => {
129-
rawPrediction = tf.reshape(rawPrediction, [13,13,this.anchorsLength,this.classesLength + 5]);
130+
rawPrediction = tf.reshape(rawPrediction, [13, 13, this.anchorsLength, this.classesLength + 5]);
130131
// Box Coords
131-
let BoxXY = tf.sigmoid(rawPrediction.slice([0, 0, 0, 0], [13, 13, this.anchorsLength, 2]));
132-
let BoxWH = tf.exp(rawPrediction.slice([0, 0, 0, 2], [13, 13, this.anchorsLength, 2]));
132+
const boxXY = tf.sigmoid(rawPrediction.slice([0, 0, 0, 0], [13, 13, this.anchorsLength, 2]));
133+
const boxWH = tf.exp(rawPrediction.slice([0, 0, 0, 2], [13, 13, this.anchorsLength, 2]));
133134
// ObjectnessScore
134-
let BoxConfidence = tf.sigmoid(rawPrediction.slice([0, 0, 0, 4], [13, 13, this.anchorsLength, 1]));
135+
const boxConfidence = tf.sigmoid(rawPrediction.slice([0, 0, 0, 4], [13, 13, this.anchorsLength, 1]));
135136
// ClassProb
136-
let BoxClassProbs = tf.softmax(rawPrediction.slice([0, 0, 0, 5],[13, 13, this.anchorsLength, this.classesLength]));
137+
const boxClassProbs = tf.softmax(rawPrediction.slice([0, 0, 0, 5],[13, 13, this.anchorsLength, this.classesLength]));
137138

138139
// from boxes with xy wh to x1,y1 x2,y2
139140
// Mainly for NMS + rescaling
@@ -144,98 +145,78 @@ class YOLO {
144145
y2 = y + (w/2)
145146
*/
146147
// BoxScale
147-
BoxXY = tf.div(tf.add(BoxXY, this.ConvIndex), this.ConvDims);
148+
const BoxXY_1 = tf.div(tf.add(boxXY, this.ConvIndex), this.ConvDims);
148149

149-
BoxWH = tf.div(tf.mul(BoxWH, this.AnchorsTensor), this.ConvDims);
150+
const BoxWH_1 = tf.div(tf.mul(boxWH, this.AnchorsTensor), this.ConvDims);
150151

151-
const Div = tf.div(BoxWH, tf.scalar(2));
152+
const Div = tf.div(BoxWH_1, tf.scalar(2));
152153

153-
const BoxMins = tf.sub(BoxXY, Div);
154+
const boxMins = tf.sub(BoxXY_1, Div);
155+
const boxMaxes = tf.add(BoxXY_1, Div);
154156

155-
const BoxMaxes = tf.add(BoxXY, Div);
156-
const Size = [BoxMins.shape[0], BoxMins.shape[1], BoxMins.shape[2], 1];
157+
const size = [boxMins.shape[0], boxMins.shape[1], boxMins.shape[2], 1];
157158

158159
// main box tensor
159-
const boxes = tf
160-
.concat(
161-
[
162-
BoxMins.slice([0, 0, 0, 1], Size),
163-
BoxMins.slice([0, 0, 0, 0], Size),
164-
BoxMaxes.slice([0, 0, 0, 1], Size),
165-
BoxMaxes.slice([0, 0, 0, 0], Size)
166-
],3)
167-
.reshape([845, 4]);
160+
const boxes = tf.concat([boxMins.slice([0, 0, 0, 1], Size), boxMins.slice([0, 0, 0, 0], size), boxMaxes.slice([0, 0, 0, 1], size), boxMaxes.slice([0, 0, 0, 0], size)], 3).reshape([845, 4]);
168161

169162
// Filterboxes by objectness threshold
170163
// not filtering / getting a mask really
171164

172-
BoxConfidence = BoxConfidence.squeeze([3]);
173-
const ObjectnessMask = tf.greaterEqual(
174-
BoxConfidence,
175-
tf.scalar(this.filterboxesThreshold)
176-
);
165+
const boxConfidence_1 = boxConfidence.squeeze([3]);
166+
const objectnessMask = tf.greaterEqual(boxConfidence_1,tf.scalar(this.filterBoxesThreshold));
177167

178168
// Filterboxes by class probability threshold
179-
const boxScores = tf.mul(BoxConfidence, tf.max(BoxClassProbs, 3));
180-
const BoxClassProbMask = tf.greaterEqual(
181-
boxScores,
182-
tf.scalar(this.classProbThreshold)
183-
);
169+
const boxScores = tf.mul(boxConfidence_1, tf.max(boxClassProbs, 3));
170+
const boxClassProbMask = tf.greaterEqual(boxScores,tf.scalar(this.classProbThreshold));
184171

185172
// getting classes indices
186-
const classes = tf.argMax(BoxClassProbs, -1);
173+
const classes = tf.argMax(boxClassProbs, -1);
187174

188175
// Final Mask each elem that survived both filters (0x0 0x1 1x0 = fail ) 1x1 = survived
189-
const FinalMask = BoxClassProbMask.mul(ObjectnessMask);
176+
const finalMask = boxClassProbMask.mul(objectnessMask);
190177

191-
const Indices = FinalMask.flatten()
192-
.toInt()
193-
.mul(this.IndicesTensor);
194-
return [boxes, boxScores, classes, Indices];
178+
const indices = finalMask.flatten().toInt().mul(this.indicesTensor);
179+
return [boxes, boxScores, classes, indices];
195180
});
196181

197182
//we started at one in the range so we remove 1 now
198183

199-
let indicesArr = Array.from(await Indices.data())
200-
.filter(i => i > 0)
201-
.map(i => i - 1);
184+
let indicesArr = Array.from(await Indices.data()).filter(i => i > 0).map(i => i - 1);
202185

203-
if (indicesArr.length == 0) {
186+
if (indicesArr.length === 0) {
204187
boxes.dispose();
205188
boxScores.dispose();
206189
classes.dispose();
207190
return results;
208191
}
192+
const [filteredBoxes, filteredScores, filteredclasses] = tf.tidy(()=>{
209193
const indicesTensor = tf.tensor1d(indicesArr, "int32");
210-
let filteredBoxes = boxes.gather(indicesTensor);
211-
let filteredScores = boxScores.flatten().gather(indicesTensor);
212-
let filteredclasses = classes.flatten().gather(indicesTensor);
213-
boxes.dispose();
214-
boxScores.dispose();
215-
classes.dispose();
216-
indicesTensor.dispose();
217-
218-
//Img Rescale
219-
const Height = tf.scalar(this.imgHeight);
220-
const Width = tf.scalar(this.imgWidth);
221-
const ImageDims = tf.stack([Height, Width, Height, Width]).reshape([1, 4]);
222-
filteredBoxes = filteredBoxes.mul(ImageDims);
223-
194+
const filteredBoxes = boxes.gather(indicesTensor);
195+
const filteredScores = boxScores.flatten().gather(indicesTensor);
196+
const filteredclasses = classes.flatten().gather(indicesTensor);
197+
198+
// Img Rescale
199+
const Height = tf.scalar(this.imgHeight);
200+
const Width = tf.scalar(this.imgWidth);
201+
const ImageDims = tf.stack([Height, Width, Height, Width]).reshape([1, 4]);
202+
const filteredBoxes_1 = filteredBoxes.mul(ImageDims);
203+
204+
return [filteredBoxes_1, filteredScores, filteredclasses]
205+
})
206+
207+
224208
// NonMaxSuppression
225209
// GreedyNMS
226-
const [boxArr, scoreArr, classesArr] = await Promise.all([
227-
filteredBoxes.data(),
228-
filteredScores.data(),
229-
filteredclasses.data()
230-
]);
210+
const [boxArr, scoreArr, classesArr] = await Promise.all([filteredBoxes.data(), filteredScores.data(), filteredclasses.data(), ]);
211+
231212
filteredBoxes.dispose();
232213
filteredScores.dispose();
233214
filteredclasses.dispose();
234215

235216
let zipped = [];
236217
for (let i = 0; i < scoreArr.length; i++) {
237218
// [Score,x,y,w,h,classindex]
238-
zipped.push([scoreArr[i],[boxArr[4 * i],boxArr[4 * i + 1],boxArr[4 * i + 2],boxArr[4 * i + 3]],classesArr[i]]);
219+
zipped.push([scoreArr[i], [boxArr[4 * i], boxArr[4 * i + 1], boxArr[4 * i + 2], boxArr[4 * i + 3]], classesArr[i]]);
239220
}
240221

241222
// Sort by descending order of scores (first index of zipped array)
@@ -247,8 +228,8 @@ class YOLO {
247228
let Push = true;
248229
for (let i = 0; i < selectedBoxes.length; i++) {
249230
// Compare IoU of zipped[1], since that is the box coordinates arr
250-
let w =Math.min(box[1][3], selectedBoxes[i][1][3]) -Math.max(box[1][1], selectedBoxes[i][1][1]);
251-
let h =Math.min(box[1][2], selectedBoxes[i][1][2]) -Math.max(box[1][0], selectedBoxes[i][1][0]);
231+
let w =Math.min(box[1][3], selectedBoxes[i][1][3]) - Math.max(box[1][1], selectedBoxes[i][1][1]);
232+
let h =Math.min(box[1][2], selectedBoxes[i][1][2]) - Math.max(box[1][0], selectedBoxes[i][1][0]);
252233
let Intersection = w < 0 || h < 0 ? 0 : w * h;
253234
let Union = (box[1][3] - box[1][1]) * (box[1][2] - box[1][0]) + (selectedBoxes[i][1][3] - selectedBoxes[i][1][1]) * (selectedBoxes[i][1][2] - selectedBoxes[i][1][0]) - Intersection;
254235
let Iou = Intersection / Union;
@@ -271,24 +252,13 @@ class YOLO {
271252
const [x1, y1, x2, y2] = selectedBoxes[id][1];
272253
// Need to get this out
273254
// TODO : add a hsla color for later visualization
274-
const resultObj = {
275-
id,
276-
className,
277-
classIndex,
278-
classProb,
279-
classProbRounded,
280-
x1,
281-
y1,
282-
x2,
283-
y2
284-
};
255+
const resultObj = {id, className, classIndex, classProb, classProbRounded, x1, y1, x2, y2, };
285256
results.detections.push(resultObj);
286257
}
287258
// Misc
288259
results.totalDetections = results.detections.length;
289260
results.scaleX = this.scaleX;
290261
results.scaleY = this.scaleY;
291-
292262
return results;
293263
}
294264
}

0 commit comments

Comments
 (0)