Shinobi/libs/events/tracking.js

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,
}
}