MATLAB基于背景差分法和卡尔曼滤波的运动目标检测和跟踪:1、对视频序列中的运动目标进行检测与跟踪

发布时间:2026/6/17 3:45:24

MATLAB基于背景差分法和卡尔曼滤波的运动目标检测和跟踪:1、对视频序列中的运动目标进行检测与跟踪 MATLAB基于背景差分法和卡尔曼滤波的运动目标检测和跟踪1、对视频序列中的运动目标进行检测与跟踪动目标检测部分采用背景差分法跟踪部分采用卡尔曼滤波检测结果用红色外接矩形框表示跟踪结果用绿色矩形框表示 2、采用平均背景法更新背景图像 3、代码部分附详细解释 内附有做实验的视频在运动目标检测和跟踪这个坑里折腾过的人大概都绕不开背景差分和卡尔曼滤波这两个经典方法。今天就用MATLAB来实现一个简单的系统把检测和跟踪串起来顺便聊聊代码里那些有意思的细节。先说说整体思路我们用一个视频序列先通过背景差分找出运动目标的位置再用卡尔曼滤波器去预测和更新目标的位置形成跟踪轨迹。检测框用红色跟踪预测框用绿色这样就能直观看到两者的区别。第一步初始化与背景建模我们采用平均背景法来建立初始背景模型。简单说就是取视频开头若干帧的平均值作为背景。videoReader VideoReader(test_video.mp4); numTrainingFrames 50; % 用前50帧训练背景 frameCount 0; background zeros(videoReader.Height, videoReader.Width, double); while frameCount numTrainingFrames frame readFrame(videoReader); background background double(rgb2gray(frame)); frameCount frameCount 1; end background background / numTrainingFrames;这里有个小细节rgb2gray转换后直接用了double类型累加避免uint8累加溢出。背景模型更新我们后面再说。第二步目标检测与连通域处理对于每一帧我们计算当前帧与背景的差值二值化后找到运动区域。currentFrame rgb2gray(readFrame(videoReader)); diffFrame abs(double(currentFrame) - background); binaryMask diffFrame 25; % 阈值需要根据视频调整 % 形态学处理去掉小噪声 binaryMask imopen(binaryMask, strel(disk, 3)); binaryMask imclose(binaryMask, strel(rectangle, [15, 15])); % 找连通区域 stats regionprops(binaryMask, BoundingBox, Area); areas [stats.Area]; validIdx areas 500; % 面积太小的忽略 boxes cat(1, stats(validIdx).BoundingBox);阈值选择是个经验活25这个值对室内监控视频还行室外可能得调。形态学开运算去椒盐噪声闭运算填小空洞这些都是常规操作。regionprops返回的边界框直接就是[x,y,width,height]格式方便后面画框。第三步卡尔曼滤波跟踪MATLAB基于背景差分法和卡尔曼滤波的运动目标检测和跟踪1、对视频序列中的运动目标进行检测与跟踪动目标检测部分采用背景差分法跟踪部分采用卡尔曼滤波检测结果用红色外接矩形框表示跟踪结果用绿色矩形框表示 2、采用平均背景法更新背景图像 3、代码部分附详细解释 内附有做实验的视频这里我们用一个简单的卡尔曼滤波器来跟踪目标中心点。假设目标匀速运动状态向量取[x, y, vx, vy]。% 初始化卡尔曼滤波器 kalmanFilter configureKalmanFilter(ConstantVelocity, ... [100, 100], [50, 50], [25, 25], 10); % 预测步骤 predictedPos predict(kalmanFilter); % 如果有检测到目标就用检测结果更新 if ~isempty(boxes) centroid [boxes(1,1)boxes(1,3)/2, boxes(1,2)boxes(1,4)/2]; correctedPos correct(kalmanFilter, centroid); else % 没检测到就只用预测值 correctedPos predictedPos; endconfigureKalmanFilter这个函数挺省事把初始位置、误差协方差、过程噪声、观测噪声都打包设置了。注意这里只处理了第一个检测目标boxes(1,:)实际多个目标需要多个滤波器实例。第四步背景更新背景不能一成不变光照变化、场景改动都会影响。我们采用简单的滑动平均法alpha 0.01; % 更新速率 background background * (1-alpha) double(currentFrame) * alpha;alpha控制更新快慢值越小背景变化越慢但可能跟不上突然的光照变化。这个更新策略虽然简单但对于缓慢变化的场景够用了。最后把结果可视化imshow(currentFrame); hold on; % 画检测框红色 for i 1:size(boxes,1) rectangle(Position, boxes(i,:), EdgeColor, r, LineWidth, 2); end % 画跟踪框绿色以修正后的位置为中心 trackBox [correctedPos(1)-50, correctedPos(2)-50, 100, 100]; rectangle(Position, trackBox, EdgeColor, g, LineWidth, 2); hold off;这里跟踪框大小固定为100x100实际可以根据目标大小动态调整。红框和绿框的对比能明显看出卡尔曼滤波的平滑效果——检测框可能会跳但跟踪框通常更稳定。整个流程跑下来你会发现背景差分在静态背景下效果不错但遇到树叶晃动、光照闪烁就容易误检。卡尔曼滤波则提供了一种“惯性”即使偶尔没检测到目标它也能根据之前的运动趋势继续跟一段。代码里还有很多可以打磨的地方比如多个目标的匹配策略、背景模型改用高斯混合模型、卡尔曼滤波的状态维度增加加速度等等。但这个简单的版本已经勾勒出了运动目标检测跟踪的基本骨架剩下的就是根据具体场景往上添肉了。实验用的视频建议选背景相对静止、目标运动明显的片段这样效果最容易出来。阈值、形态学参数、卡尔曼噪声参数都需要根据视频微调没有一套参数能通吃所有场景——这大概就是计算机视觉工程的日常吧。

相关新闻