The code inside the function node is a bit specialized towards my specific setup, I hope it can be understood. At least it could be a point of reference for discussion, everything inside is pretty straight forward I think (and I think I can also clarify any unclear details). Here it is:
Please note that I have assigned a unique number to all my cameras. Like '51' or '11'. So when an image is captured from a camera it is published (by another separate process) to an MQTT broker at a camera specific topic. Like resized/22
In this way I can identify from which camera the image is captured. To be able to set the correct labeling, check the required score etc etc
let conf_lev = {
'XX':0.50,
'51':0.50,
'52':0.50,
'41':0.40,
'42':0.35,
'31':0.65,
'32':0.45,
'21':0.70,
'22':0.45,
'11':0.35,
'12':0.35
};
let min_area = {
'XX':700,
'51':700,
'52':700,
'41':8600,
'42':700,
'31':4900,
'32':5000,
'21':3000,
'22':4000,
'11':1500,
'12':3700
};
let ratios = {
'XX':0.65,
'51':0.65,
'52':0.65,
'41':0.65,
'42':0.65,
'31':0.65,
'32':0.65,
'21':0.65,
'22':0.65,
'11':0.70,
'12':0.70
};
let ar = context.get("ar") || {
'XX':0,
'51':0,
'52':0,
'41':0,
'42':0,
'31':0,
'32':0,
'21':0,
'22':0,
'11':0,
'12':0
};
let tmrs = context.get("tmrs") || {
'XX':null,
'51':null,
'52':null,
'41':null,
'42':null,
'31':null,
'32':null,
'21':null,
'22':null,
'11':null,
'12':null
}
let labels = {
'XX':"Just a demo nbr XX",
'51':"Just a demo nbr 51",
'52':"Just a demo nbr 52",
'41':"At the front entrance door",
'42':"Mobile webcam",
'31':"In front of the carport",
'32':"In the carport",
'22':"Around the washroom entrance",
'21':"In the garden",
'11':"Near the front entrance door",
'12':"Walking towards the carport"
};
let cam_pos = {
'XX':'MotionXX:detect_now1',
'51':'Motion5:detect_now1',
'52':'Motion5:detect_now2',
'41':'Motion4:detect_now1',
'42':'Motion4:detect_now2',
'31':'Motion3:detect_now1',
'32':'Motion3:detect_now2',
'21':'Motion2:detect_now1',
'22':'Motion2:detect_now2',
'11':'Motion1:detect_now1',
'12':'Motion1:detect_now2'
};
function f(cam) {
ar[cam] = 0;
context.set("ar", ar);
tmrs[cam] = null;
context.set("tmrs", tmrs);
// node.warn("Timer triggered: "+cam);
}
let detections = msg.payload;
let cam = msg.topic.split('/')[1];
let score = 0;
let clss = '';
let tclss = '';
let h = 0;
let w = 0;
for (var det in detections) {
// node.warn(detections[det]);
sc = detections[det]['score'];
// node.warn(sc);
clss = detections[det]['class'];
w = detections[det]['bbox']['2'];
h = detections[det]['bbox']['3'];
// node.warn(w*h);
// node.warn(w/h);
if (clss === 'person'){
tclss = clss;
if (w*h > min_area[cam] && w/h < ratios[cam]){
if (sc > score){
score = parseFloat(sc.toPrecision(2));
// node.warn(score);
sc = 0;
}
}
}
}
if (tmrs[cam] == null) {
tmrs[cam] = setTimeout( f, 60000, cam );
context.set("tmrs", tmrs);
}
if ((tclss === 'person' && score > conf_lev[cam] && w*h > ar[cam]) || cam === 'XX'){
ar[cam] = w*h;
context.set("ar", ar);
msg.payload = msg.image;
delete msg.image;
msg.filename = '/home/pi/pics/captured'+cam+'.jpg';
let label = labels[cam];
msg.caption = label+' '+tclss+' '+score
msg.itr = 'Intruder detected: '+cam_pos[cam];
return msg;
}