158 lines
5.8 KiB
JavaScript
158 lines
5.8 KiB
JavaScript
const movingThings = require('shinobi-node-moving-things-tracker').Tracker
|
|
module.exports = (s,config,lang) => {
|
|
const objectTrackers = {}
|
|
const objectTrackerTimeouts = {}
|
|
function resetObjectTracker(trackerId,matrices){
|
|
const Tracker = movingThings.newTracker();
|
|
objectTrackers[trackerId] = {
|
|
frameCount: 1,
|
|
tracker: Tracker,
|
|
lastPositions: []
|
|
}
|
|
return objectTrackers[trackerId]
|
|
}
|
|
function setLastTracked(trackerId, trackedMatrices){
|
|
const theTracker = objectTrackers[trackerId]
|
|
theTracker.lastPositions = trackedMatrices
|
|
}
|
|
function getTracked(trackerId){
|
|
const theTracker = objectTrackers[trackerId]
|
|
const frameCount = theTracker.frameCount
|
|
const trackedObjects = theTracker.tracker.getJSONOfTrackedItems().map((matrix) => {
|
|
return {
|
|
id: matrix.id,
|
|
tag: matrix.name,
|
|
x: matrix.x,
|
|
y: matrix.y,
|
|
width: matrix.w,
|
|
height: matrix.h,
|
|
confidence: matrix.confidence,
|
|
isZombie: matrix.isZombie,
|
|
}
|
|
})
|
|
return trackedObjects;
|
|
}
|
|
function trackObject(trackerId,matrices){
|
|
if(!objectTrackers[trackerId]){
|
|
resetObjectTracker(trackerId)
|
|
}
|
|
const mappedMatrices = matrices.map((matrix) => {
|
|
return {
|
|
x: matrix.x,
|
|
y: matrix.y,
|
|
w: matrix.width,
|
|
h: matrix.height,
|
|
confidence: matrix.confidence,
|
|
name: matrix.tag,
|
|
}
|
|
});
|
|
const theTracker = objectTrackers[trackerId]
|
|
theTracker.tracker.updateTrackedItemsWithNewFrame(mappedMatrices, theTracker.frameCount);
|
|
++theTracker.frameCount
|
|
}
|
|
function trackObjectWithTimeout(trackerId,matrices){
|
|
clearTimeout(objectTrackerTimeouts[trackerId]);
|
|
objectTrackerTimeouts[trackerId] = setTimeout(() => {
|
|
objectTrackers[trackerId].tracker.reset()
|
|
delete(objectTrackers[trackerId])
|
|
delete(objectTrackerTimeouts[trackerId])
|
|
},1000 * 60);
|
|
trackObject(trackerId,matrices);
|
|
}
|
|
function objectHasMoved(matrices, options = {}) {
|
|
const { imgHeight = 1, imgWidth = 1, threshold = 0 } = options;
|
|
for (let i = 0; i < matrices.length; i++) {
|
|
const current = matrices[i];
|
|
if (i < matrices.length - 1) {
|
|
const next = matrices[i + 1];
|
|
let totalDistanceMoved = 0;
|
|
let numPointsCompared = 0;
|
|
if (next) {
|
|
// Compare each corner of the matrices
|
|
const currentCorners = [
|
|
{ x: current.x, y: current.y },
|
|
{ x: current.x + current.width, y: current.y },
|
|
{ x: current.x, y: current.y + current.height },
|
|
{ x: current.x + current.width, y: current.y + current.height }
|
|
];
|
|
const nextCorners = [
|
|
{ x: next.x, y: next.y },
|
|
{ x: next.x + next.width, y: next.y },
|
|
{ x: next.x, y: next.y + next.height },
|
|
{ x: next.x + next.width, y: next.y + next.height }
|
|
];
|
|
for (let j = 0; j < currentCorners.length; j++) {
|
|
const currentCorner = currentCorners[j];
|
|
const nextCorner = nextCorners[j];
|
|
const dx = nextCorner.x - currentCorner.x;
|
|
const dy = nextCorner.y - currentCorner.y;
|
|
const distanceMoved = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
|
const distanceMovedPercent =
|
|
(100 * distanceMoved) / Math.max(current.width, current.height);
|
|
totalDistanceMoved += distanceMovedPercent;
|
|
numPointsCompared++;
|
|
}
|
|
const averageDistanceMoved = totalDistanceMoved / numPointsCompared;
|
|
if (averageDistanceMoved < threshold) {
|
|
continue;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function groupMatricesById(matrices) {
|
|
const matrixById = {};
|
|
const matrixTags = {};
|
|
|
|
matrices.forEach(matrix => {
|
|
const id = matrix.id;
|
|
const tag = matrix.tag;
|
|
if (!matrixById[id]) {
|
|
matrixById[id] = [];
|
|
}
|
|
matrixTags[tag] = id;
|
|
matrixById[id].push(matrix);
|
|
});
|
|
|
|
return matrixById
|
|
}
|
|
function getAllMatricesThatMoved(monitorConfig,matrices){
|
|
const monitorDetails = monitorConfig.details
|
|
const imgWidth = parseInt(monitorDetails.detector_scale_x_object) || 1280
|
|
const imgHeight = parseInt(monitorDetails.detector_scale_y_object) || 720
|
|
const objectMovePercent = parseInt(monitorDetails.detector_object_move_percent) || 5
|
|
const groupKey = monitorConfig.ke
|
|
const monitorId = monitorConfig.mid
|
|
const trackerId = `${groupKey}${monitorId}`
|
|
const theTracker = objectTrackers[trackerId]
|
|
const lastPositions = theTracker.lastPositions
|
|
const sortedById = groupMatricesById([...lastPositions,...matrices])
|
|
const movedMatrices = []
|
|
for (const objectId in sortedById) {
|
|
const sortedList = sortedById[objectId]
|
|
if(sortedList[1]){
|
|
const matrixHasMoved = objectHasMoved(sortedList,{
|
|
threshold: objectMovePercent,
|
|
imgWidth: imgWidth,
|
|
imgHeight: imgHeight,
|
|
});
|
|
if(matrixHasMoved){
|
|
movedMatrices.push(sortedList[1])
|
|
}
|
|
}
|
|
}
|
|
return movedMatrices
|
|
}
|
|
return {
|
|
trackObjectWithTimeout,
|
|
resetObjectTracker,
|
|
trackObject,
|
|
getTracked,
|
|
setLastTracked,
|
|
getAllMatricesThatMoved,
|
|
}
|
|
}
|