SAD帧差法与模板匹配法实现行人跟踪

友人分享给我的一个,让我改改。结果贴在下面了

主函数:

clc;
clear all;
close all;

mov=VideoReader('test3.avi');    %读取视频文件
N=mov.NumFrames;         %读取视频长度
ThresholdTrackStep=10;            % 模板匹配搜索步长范围

%% 帧差法获取跟踪法模板
handle=figure('name','图像解算显示框','position',[100 100 800 600]);

for i=1:N
    frame=read(mov,i+1);
    Pframe=read(mov,i);   % 读取第一帧视频帧
    subplot(2,2,1);
    imshow(Pframe,[]);
    title(sprintf('the %d frame of %d in Avi ',i,N))   %画出前一帧
    [Xmin,Ymin,Xmax,Ymax]=FrameDiff(frame,Pframe);   %帧差法,输出运动目标的四个边界点
    subplot(2,2,2);
    imshow(Pframe,[]);       %画出当前帧 
     B=isempty([Xmin,Ymin,Xmax-Xmin,Ymax-Ymin]);  %判断[Xmin,Ymin,Xmax-Xmin,Ymax-Ymin]是否为空,如果为空对其进行赋值
       if    B==1;  Xmin=0; Ymin=0; Xmax=100; Ymax=2;
       end
   rectangle('position',[Xmin,Ymin,Xmax-Xmin,Ymax-Ymin],'edgecolor','g');    %画出跟踪框
   title(sprintf('the %d frame of %d of Difference ',i,N))                                     %画出前一帧
    % 用q键退出仿真
     if strcmpi(get(gcf,'CurrentCharacter'),'q') %按下q键停止帧差法,此时将当前帧捕获的运动目标作为检测模板
    %    Lastframe=read(mov,i);%读取截止帧
         z=rgb2gray(frame);   %截止帧灰度处理
         MatchMode=z(Ymin:Ymax,Xmin:Xmax);    %获取模板
         break;
     end
end
 %% 这是程序的结束
 set(handle, 'Visible', 'on');
 subplot(2,2,3);
 imshow(MatchMode);
 title('the Match Model');  %画出模板

 
%% 相关系数法模板匹配法
for j= i:(N-i)
     frame=read(mov,j);%读取视频帧
     [Xmin, Ymin, Xmax, Ymax, MatchMode]=SADTrack(Xmin,Ymin,Xmax,Ymax,frame,MatchMode,ThresholdTrackStep);   %相关系数匹配,输出边界点移动步长
    %  模板匹配后画出当前帧
     subplot(2,2,4);
     imshow(frame,[]);%画出当前帧
     rectangle('position',[Xmin,Ymin,Xmax-Xmin,Ymax-Ymin],'edgecolor','r');%画图
     title(sprintf('the Searching Result:  %d frame of %d  ',j,N))    
    
      %按下s键停止模板匹配
    if strcmpi(get(gcf,'CurrentCharacter'),'s') 
        break;
    end
end

子函数SADTrack:

function [NXmin, NYmin, NXmax,  NYmax, NewMatchMode]=SADTrack(PXmin,PYmin,PXmax,PYmax,frame,OldMatchMode,ThresholdTrackStep)
%  这个函数只供参考,不能直接作为作业使用,效果较差
x=frame;
[m,n]=size(x);
threshold=ThresholdTrackStep;
A=[-1;0;1;-1;1;-1;0;-1];
B=[-1;-1;-1;0;0;1;1;1];
dst=zeros(8,1);%搜索帧数
% 开始循环,这里的程序写不规范,大家要自己改
for q=1:8
%    maskXmin=PXmin;
%    maskYmin=PYmin;
%    maskXmax=PXmax;
%    maskYmax=PYmax;
   maskXmin=PXmin+A(q)*threshold;
   maskYmin=PYmin+B(q)*threshold;
   maskXmax=PXmax+A(q)*threshold;
   maskYmax=PYmax+B(q)*threshold;
if (maskYmin>8)&&(maskXmin>8)&&(maskXmax<=n)&&(maskYmax<=m)
     temp=x(maskYmin:maskYmax,maskXmin:maskXmax);                     %当前子图
%     dst(q)=sum(sum(abs(temp-OldMatchMode)));
    dst(q)=dst(q)+sum(sum(abs(temp-OldMatchMode)));
    %   dst(j)=corr2(temp,MatchMode);
   else
      dst(q)=100000000; %
end
end
 abs_min=min(abs(dst));
 MOV=find(abs(dst)==abs_min);
 track(1,1)=A(MOV)*threshold;
 track(1,2)=B(MOV)*threshold;
  NXmin=PXmin+track(1,1);
  NYmin=PYmin+track(1,2);
  NXmax=PXmax+track(1,1);
  NYmax=PYmax+track(1,2);              % 更新待寻的图像位置 
  
 % 更新匹配模板
%  NewMatchMode=OldMatchMode;  % 测试程序没有更新
  NewMatchMode=x(NYmin:NYmax,NXmin:NXmax); 

子函数FrameDiff

function [Xmin,Ymin,Xmax,Ymax]=FrameDiff(frame,Pframe)
    x=rgb2gray(frame);
    y=rgb2gray(Pframe); %前后两帧图像二值化
    x=medfilt2(x);
    y=medfilt2(y);%中值滤波去噪
    n=im2double(x);
    p=im2double(y);   %将图像转化为图像双精度
    c=n-p;            %检测帧差
    c=medfilt2(c);    %中值滤波
    t=50/256;         %设置帧差阈值
    c(abs(c)>=t)=255;
    c(abs(c)<t)=0;
    c=logical(c);     %将c转为逻辑阵
    [a,b]=find(c>0);
    Xmax=max(b);
    Xmin=min(b);
    Ymax=max(a);
    Ymin=min(a);      %找出边缘像素点
9HH@_SCHY_RL1VXFFMSWCW5.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容