clear data
clc;
%disp('input video');
avi = aviread('C:\My Video\SampleVideo.avi');
video = {avi.cdata};
for a = 1:length(video)
imagesc(video{a});
axis image off
drawnow;
end;
%disp('output video');
tracking(video);
% 显示视频
%mov(avi);
[m,n]=size(avi);
% 设置图像帧数
NumFrames=1;
for k=1:NumFrames
% 提取图像第k帧
mov1=aviread('C:\My Video\SampleVideo.avi',k);
I1=frame2im(mov1);
I1=rgb2gray(I1);
% 提取图像第k+30帧
mov2=aviread('C:\My Video\SampleVideo.avi',k+30);
I2=frame2im(mov2);
I2=rgb2gray(I2);
% 提取图像第k+31帧
mov3=aviread('C:\My Video\SampleVideo.avi',k+31);
I3=frame2im(mov3);
I3=rgb2gray(I3);
end
% 求差分图像
I4=abs(I1-I2);
% 求差分图像
I5=abs(I2-I3);
% 求平均值
I=(I4+I5)/2;
%figure,imshow(I)
% 设定自变量i、j
for i=1:m
for j=1:n
% 设定阈值提取背景图像
if I(i,j)<10
B=I1;
else
B=0;
end
end
end
% 显示背景图像
%figure,imshow(B)
% 读取图像,提取第k1帧、第k1+25帧;
% 将两图像进行差分,得到帧间差分图像;
% 然后将第k帧图像与背景图像进行差分得到背景差分图像;
% 再对以上两种差分图像进行逻辑运算,运用数学形态学法进行开运算;
% 检测出运动目标。
NumFrames=15;
for k1=1:NumFrames
% 提取图像第k1帧
mov4=aviread('C:\My Video\SampleVideo.avi',k1);
I6=frame2im(mov4);
I6=rgb2gray(I6);
% 提取图像第k1+25帧
mov5=aviread('C:\My Video\SampleVideo.avi',k1+25);
I7=frame2im(mov5);
I7=rgb2gray(I7);
end
% 求差分图像
I8=abs(I6-I7);
% 转化成二值图像
bw1=im2bw(I8);
% 求差分图像
I9=abs(I7-B);
% 转化成二值图像
bw2=im2bw(I9);
% 逻辑'或'操作
bw=bw1|bw2;
% 用1*1的结构元素对图像进行开运算
se=strel('square',1);
f=imopen(bw,se);
% 检测出运动目标
%figure,imshow(f)
% 将获得的第k帧与背景图像差分得到一差分图像;
% 将获得的第k+1帧与背景图像差分又得到一差分图像;
% 再将两差分图像进行差分,如果其值大于某一阈值,则输出一个1信号;
% 否则输出一个0信号;
% 与背景图像差分
I6=abs(I6-B);
% 与背景图像差分
I7=abs(I7-B);
% 将以上两差分图像差分
I10=abs(I7-I6);
% 显示图像
[x,y]=size(avi);
% 设定阈值,大于则输出1信号;
% 否则输出0信号;
for w=1:x
for s=1:y
if I10(w,s)>0.3
t=1
else
t=0
end
end
end
%function MMM = mtest_new5_simple()
%读取前后两帧,计算残差数据,即是差分图像,把它再转换成二值图像
%对二值图像通过设定二值化门限(自适应),小于这个门限赋为黑色,大于赋为白色
%然后对二值图像进行一些相关的处理,比如开运算、去除阴影、去除空洞
%通过计算目标坐标开始画框,开始标识,最后显示每一帧,制成一个视频
stepframe =1;%帧处理的间隔
frameNO =10; %起始帧编号
framenum =72; %总的帧数
stepy = 8; %分块的尺寸
stepx = 8;
%sss = 'RMOV0009.AVI'
%MMM = moviein(framenum);
FLAG = 1; %中间图像输出控制开关
FLAGM =0;%去除阴影算法开启
FLAGR = 1;%中间结果是否输出
mtype =1;%mtype=1表示画框,type=0表示画十字
%测试时间
time_inint=0;
time_read = 0;
time_bi = 0;
time_back = 0;
time_check = 0;
time_filter = 0;
time_lock = 0;
% 读取2个参考帧
tic %starts a stopwatch timer
MF = aviread('C:\My Video\SampleVideo.avi',frameNO); % read a audio or video interleaves(AVI) file
X= frame2im(MF); %convert movie frame to indexed image
pic1 = rgb2gray(X); %change RGB image to gray image
pic1 = double(pic1);%convert to double precision
MF = aviread('C:\My Video\SampleVideo.avi',frameNO+1);
X= frame2im(MF);
pic2 = rgb2gray(X);
pic2 = double(pic2);
% 初始化alpha
alpha = 0.618;
num = 1;
time_inint = toc;% prints the elapsed time since tic was used.
for frame = frameNO+2:1+stepframe:framenum
time_read = 0;
time_bi = 0;
time_back = 0;
time_check = 0;
time_filter = 0;
time_lock = 0;
% 读取当前帧图像
indexframe = frame;
tic
MF = aviread('C:\My Video\SampleVideo.avi',indexframe);
pic = frame2im(MF);
curr = rgb2gray(pic);
curr = double(curr);
time_read = toc;
tic
% 背景自适应更新
if frame==frameNO+2 %如果当前帧等于起使帧之后的两帧,则用更新公式更新,其中已经初始化更新率为0.618
pred = alpha*pic1 + (1 - alpha)*pic2;
else
%分块更新背景
for jj = 1:M
for ii = 1:N
temp1 = pic1((jj-1)*stepy+1:jj*stepy,(ii-1)*stepx+1:ii*stepx);
temp2 = pic2((jj-1)*stepy+1:jj*stepy,(ii-1)*stepx+1:ii*stepx);
s = mmap(jj,ii);
if s==255
pred((jj-1)*stepy+1:jj*stepy,(ii-1)*stepx+1:ii*stepx) = (1-alpha)*temp2+alpha*temp1;
else
pred((jj-1)*stepy+1:jj*stepy,(ii-1)*stepx+1:ii*stepx) = (alpha)*temp2+(1-alpha)*temp1;
end
end
end
end
time_back = toc;
if FLAG
%figure,imshow(uint8(floor(pred+0.5)));
%title('背景');
end
tic
% 计算残差数据Error
Error = abs(curr - pred); %floor(0.5+abs(y - pred)),这个残差数据即是差分图像数据
% 交换存储空间
pic1 = pic2; % 更新之后把第二帧赋给第一帧
pic2 = curr; % 把当前帧赋给第二帧
% 计算残差的平均值
[a,b] = size(Error);
temp = sum(sum(Error));%残差的总和temp
m = temp/(a*b);%m是残差的平均值
% alpha的更新
alpha = exp(-2/m);
% 二值化,阈值自适应更新
T = 5*m; %二值化门限,其中m是残差的平均值,如果残差小于这个阈值则赋值为黑色,大于则赋值为白色
for i =1:a
for j = 1:b
if Error(i,j) < T
Error(i,j) = 0;
else
Error(i,j) = 255;
end
end
end
time_bi = toc;
if FLAG
ss = uint8(Error);%把这差分图像变换为uint8型
%figure,imshow(ss);
%title('二值化');
end
tic
%计算映射矩阵,如果残差的总和大于一定比率的分块面积时,则赋为白色
M = floor(a/stepy);%a是差分图像的行向量,stepy是分块矩阵的行值,M为行分块数值
N = floor(b/stepx);%b是差分图像的列向量,stepx是分块矩阵的列值,N为列分块数值
mmap = zeros(M,N);%初始化映射矩阵
for i = 1:M
for j =1:N
temp = sum(sum(Error((i-1)*stepy+1:i*stepy,(j-1)*stepx+1:j*stepx)));
if temp >255*stepx*stepy*0.05;
mmap(i,j) =255;
end
end
end
time_check = toc;
if FLAG %阈值分割的目的是为了后面对图像的处理做准备:对分割出来的图像进行相应的运算
%figure,imshow(mmap);
%title('映射矩阵图像(阈值分割)');
vv = Error;%把残差数据赋给vv,如果初始化映射矩阵为白色,则vv赋为白色,否则为黑色
for j = 1:M
for i = 1:N
if mmap(j,i) == 255
vv((j-1)*stepy+1:j*stepy,(i-1)*stepx+1:i*stepx) = 255;
else
vv((j-1)*stepy+1:j*stepy,(i-1)*stepx+1:i*stepx) = 0;
end
end
end
%figure,imshow(vv);
%title('阈值分割');
end
tic
%连通域检测,flag1表示上面,flag2表示左边
mcount = 1;%区域的编号值
marea = zeros(M,N); %块的区域编号矩阵,初始为0
for j =1:M
for i = 1:N
if mmap(j,i)==255 && i+j>2 %假定映射图像是白色而且行和列值大于2
if i==1 %如果是第一列,则把前一行的编号矩阵赋给flag2;
flag1 = marea(j-1,i);
flag2 = flag1;
elseif j ==1 %如果是第一行,则把前一列赋给flag1