mirror of
https://gitlab.com/Shinobi-Systems/ShinobiCE.git
synced 2025-03-09 15:40:15 +00:00
103 lines
No EOL
3.2 KiB
JavaScript
103 lines
No EOL
3.2 KiB
JavaScript
var cv = require('opencv4nodejs')
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const classNames = require('./dnnCocoClassNames');
|
|
const { extractResults } = require('./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) {
|
|
// 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 => (drawImg, className, getColor, 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.Vec(0, 255, 0),
|
|
bowl: new cv.Vec(255, 0, 0),
|
|
'wine glass': new cv.Vec(0, 0, 255),
|
|
cup: new cv.Vec(0, 255, 255)
|
|
};
|
|
|
|
const legendLeftTop = new cv.Point(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.Vec(Math.random() * 255, Math.random() * 255, 255);
|
|
|
|
drawClassDetections(img, 'car', getRandomColor);
|
|
cv.imshowWait('img', img);
|
|
};
|
|
|
|
runDetectDishesExample();
|
|
runDetectPeopleExample(); |