记录自己写的简单的背景差分目标检测(不知道是不是完整的步骤)

过程

1.第一帧作为背景帧(假定第一帧不含运动目标),并将其转换成灰度图像;

clc;clear;
I = VideoReader("片头.mp4") ;
Key_65=read(I,65);%读取第65帧作为背景帧
Key_65=rgb2gray(Key_65);
imshow(Key_65);%背景帧灰度图像

运行结果在这里插入图片描述

  1. 取出当前帧(例子中的视频共808帧,取第400帧为当前帧);计算当前帧与背景帧之差,得到差分图像;对差分图像进行二值化;
Key_100=read(I,100);%取出第100帧为当前帧
k_65=im2double(Key_65);
k_100=im2double(Key_100);
Subtraction=k_100-k_65;
thresh=graythresh(Subtraction);%确定二值化阈值
Subtraction_2=im2bw(Subtraction,thresh);
figure(1)
subplot(221);imshow(Key_65);title("背景帧");
subplot(222);imshow(Key_100);title("当前帧");
subplot(223);imshow(Subtraction);title("差分图像");
subplot(224);imshow(Subtraction_2);title("差分图像的二值化图像");

运行结果
在这里插入图片描述

3.对二值化后的图像的各个连通区域作标记
(这里有两种方法,一种)

tic
labeltmp = bwconncomp(Subtraction_2);
label1 = zeros(size(Subtraction_2));
for k = 1:labeltmp.NumObjects
label1(labeltmp.PixelIdxList{k}) = k; 
end
t1 = toc;
figure;
imagesc(label1),title('标记'),xlabel(t1);
disp(label1tmp.NumObjects)% 连通区域的面积

运行结果
在这里插入图片描述
(另一种是用bwlable函数)

4.计算各个区域的面积;保留面积大于某个阈值的区域(例子中取阈值为800像素);以半径为5像素的圆形结构元素对连续作3次膨胀、腐蚀操作,得到运动目标

label1tmp=bwlabel(Subtraction_2);
a=100;%阈值取100
stats = regionprops(label1tmp,'Area')%计算面积大小
area = cat(1,stats.Area);
index = find(area>100); %求面积大于阈值100连通域的索引
img = ismember(label1tmp,index); %获取连通域图
se=strel('disk',5); % 生成圆形结构元素 半径为5
img_e=imerode(img,se,3);
img_d=imdilate(img,se,3);
figure;
subplot(131);imshow(img);title("面积大于阈值100连通域图像");
subplot(132);imshow(img_e);title("半径为5圆型结构腐蚀三次图");
subplot(133);imshow(img_d);title("半径为5圆型结构膨胀三次图");

这里就是bwlable函数(matlab自带的函数)标记的。
运行结果
在这里插入图片描述

总结

  1. 可能是视频背景也是快速运动的导致想提取的字体目标没有提取处理
  2. 差分算法哪里可能效果不是很好
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐