-
Notifications
You must be signed in to change notification settings - Fork 830
/
Copy pathdnnSSDCoco.ts
109 lines (84 loc) · 3.29 KB
/
dnnSSDCoco.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import * as fs from 'fs';
import * as path from 'path';
import * as cv from '../../';
import {
drawRect
} from './utils';
import { classNames } from './dnnCocoClassNames';
import { extractResults, Prediction } from './dnn/ssdUtils';
if (!cv.xmodules.dnn) {
throw new Error('exiting: opencv4nodejs compiled without dnn module');
}
// replace with path where you unzipped inception model
const ssdcocoModelPath = '../../data/dnn/coco-SSD_300x300';
const prototxt = path.resolve(ssdcocoModelPath, 'deploy.prototxt');
const modelFile = path.resolve(ssdcocoModelPath, 'VGG_coco_SSD_300x300_iter_400000.caffemodel');
if (!fs.existsSync(prototxt) || !fs.existsSync(modelFile)) {
console.log('could not find ssdcoco model');
console.log('download the model from: https://drive.google.com/file/d/0BzKzrI_SkD1_dUY1Ml9GRTFpUWc/view');
throw new Error('exiting: could not find ssdcoco model');
}
// initialize ssdcoco model from prototxt and modelFile
const net = cv.readNetFromCaffe(prototxt, modelFile);
function classifyImg(img: cv.Mat) {
// ssdcoco model works with 300 x 300 images
const imgResized = img.resize(300, 300);
// network accepts blobs as input
const inputBlob = cv.blobFromImage(imgResized);
net.setInput(inputBlob);
// forward pass input through entire network, will return
// classification result as 1x1xNxM Mat
let outputBlob = net.forward();
// extract NxM Mat
outputBlob = outputBlob.flattenFloat(outputBlob.sizes[2], outputBlob.sizes[3]);
return extractResults(outputBlob, img)
.map(r => Object.assign({}, r, { className: classNames[r.classLabel] }));
}
const makeDrawClassDetections = (predictions: Prediction[]) =>
(drawImg: cv.Mat, className: string, getColor: () => cv.Vec3, thickness = 2) => {
predictions
.filter(p => classNames[p.classLabel] === className)
.forEach(p => drawRect(drawImg, p.rect, getColor(), thickness));
return drawImg;
};
const runDetectDishesExample = () => {
const img = cv.imread('../../data/dishes.jpg');
const minConfidence = 0.2;
const predictions = classifyImg(img).filter(res => res.confidence > minConfidence);
const drawClassDetections = makeDrawClassDetections(predictions);
const classColors = {
fork: new cv.Vec3(0, 255, 0),
bowl: new cv.Vec3(255, 0, 0),
'wine glass': new cv.Vec3(0, 0, 255),
cup: new cv.Vec3(0, 255, 255)
};
const legendLeftTop = new cv.Point2(580, 20);
const alpha = 0.4;
cv.drawTextBox(
img,
legendLeftTop,
Object.keys(classColors).map(className => ({
text: className,
fontSize: 0.8,
color: classColors[className]
})),
alpha
);
Object.keys(classColors).forEach((className) => {
const color = classColors[className];
// draw detections
drawClassDetections(img, className, () => color);
});
cv.imshowWait('img', img);
};
const runDetectPeopleExample = () => {
const img = cv.imread('../../data/cars.jpeg');
const minConfidence = 0.4;
const predictions = classifyImg(img).filter(res => res.confidence > minConfidence);
const drawClassDetections = makeDrawClassDetections(predictions);
const getRandomColor = () => new cv.Vec3(Math.random() * 255, Math.random() * 255, 255);
drawClassDetections(img, 'car', getRandomColor);
cv.imshowWait('img', img);
};
runDetectDishesExample();
runDetectPeopleExample();