在视频监控领域,目标检测技术的应用越来越广泛。然而,并非所有场景都需要检测视频中的所有物体。例如,安全监控可能只关注移动物体,而忽略背景中的静态物体。本文将探讨如何通过目标检测模型,仅对视频中的移动物体进行检测。
在实际应用中,可能希望在宠物监控摄像头中设置提醒,当宠物遇到麻烦或做出可爱动作时得到通知。在这种情况下,只需要检测移动物体,而不需要关注背景中的静态物体。
为了实现这一目标,可以使用Roboflow Universe中的目标检测模型,并通过特定的方法仅对移动物体进行检测。具体来说,通过比较连续两帧图像的差异,来确定是否有物体在移动。如果两帧之间的差异超过设定的阈值,则认为检测到移动物体。
在实现过程中,首先启动inferenceJS工作线程,然后定期运行captureMotion函数。该函数会检查前一帧和当前帧之间的差异,并在检测到差异的区域绘制一个框。然后,只对框内的目标进行检测。这个过程每500毫秒重复一次。
video.onplay = function() {
setInterval(captureMotion, 500);
inferEngine.startWorker(model_name, model_version, publishable_key, [{ scoreThreshold: confidence_threshold }])
.then((id) => {
// Start inference
detectFrame();
});
}
为了实现这一功能,需要定义一些全局变量,包括用于差异检测的画布尺寸、像素差异阈值和得分阈值。这些变量可以根据实际需求进行调整。
var isReadyToDiff = false;
var diffWidth = 64;
var diffHeight = 48;
var pixelDiffThreshold = 32;
var scoreThreshold = 16;
var currentMotionBox;
var diffCanvas = document.createElement('canvas');
diffCanvas.width = diffWidth;
diffCanvas.height = diffHeight;
var diffContext = diffCanvas.getContext('2d', { willReadFrequently: true });
接下来,通过captureMotion函数来捕获移动物体。该函数通过比较连续两帧图像的差异,生成一个包含所有差异的框。然后,通过processDiff函数来处理这些差异,并确定是否检测到移动物体。如果得分超过设定的得分阈值,则认为检测到移动物体,并返回相应的框。
function captureMotion() {
diffContext.globalCompositeOperation = 'difference';
diffContext.drawImage(video, 0, 0, diffWidth, diffHeight);
var diffImageData = diffContext.getImageData(0, 0, diffWidth, diffHeight);
if (isReadyToDiff) {
var diff = processDiff(diffImageData);
if (diff.motionBox) {
// Draw rectangle
}
currentMotionBox = diff.motionBox;
}
}
在processDiff函数中,通过遍历差异图像的每个像素点,计算像素差异,并根据差异大小更新得分。如果得分超过设定的得分阈值,则认为检测到移动物体,并返回相应的框。
function processDiff(diffImageData) {
var rgba = diffImageData.data;
var score = 0;
var motionPixels = [];
var motionBox = undefined;
for (var i = 0; i < rgba.length; i += 4) {
var pixelDiff = rgba[i] * 0.3 + rgba[i + 1] * 0.6 + rgba[i + 2] * 0.1;
var normalized = Math.min(255, pixelDiff * (255 / pixelDiffThreshold));
rgba[i] = 0;
rgba[i + 1] = normalized;
rgba[i + 2] = 0;
if (pixelDiff >= pixelDiffThreshold) {
score++;
var coords = calculateCoordinates(i / 4);
motionBox = calculateMotionBox(motionBox, coords.x, coords.y);
motionPixels = calculateMotionPixels(motionPixels, coords.x, coords.y, pixelDiff);
}
}
return {
score: score,
motionBox: score > scoreThreshold ? motionBox : undefined,
motionPixels: motionPixels
};
}
最后,通过drawBoundingBoxes函数来绘制移动物体的框。该函数会检查当前帧中的目标检测结果,并根据移动物体的框来过滤结果。只有当目标检测结果在移动物体的框内时,才会绘制相应的框。
function drawBoundingBoxes(predictions, ctx) {
if (currentMotionBox != undefined) {
// Draw motionBox
for (var i = 0; i < predictions.length; i++) {
if (confidence < user_confidence || !isCornerInside(motion_x, motion_y, motion_width, motion_height, x, y, width, height)) {
continue;
}
}
}
}
通过以上步骤,可以在视频流中有效地检测移动物体。这种方法可以应用于各种场景,如安全监控、宠物监控等。通过调整像素差异阈值和得分阈值,可以优化检测效果,以适应不同的应用需求。