您的位置:首页 > 编程语言 > MATLAB

运动目标识别系统Matlab仿真——附上程序

2017-12-02 16:43 585 查看
本人毕业设计做的是红外运动识别系统,通过Matlab做了仿真。其中视频资源来自优酷。毕设论文随后上传。以下是matlab代码

%.........题目:基于光流场算法的人的检测
%.........备注:需要调用计算视觉系统工具箱。
%.........     基本实现目标的跟踪,可以做出报警
%.........     结果图片储存
%.........程序员:青鸟绝迹
%.........时间:4月19日
clear all
%创建必要的视频处理对象
videofile = 'people_net.mp4';
%获取视频帧像素
info = VideoReader(videofile);
cols=info.Width;
rows=info.Height;
%创建视频系统对象,读取视频文件
hReader = vision.VideoFileReader(videofile, 'ImageColorSpace', 'RGB',...
'VideoOutputDataType', 'single');
hFlow = vision.OpticalFlow(  'OutputValue', 'Horizontal and vertical components in complex form', ...
'ReferenceFrameDelay', 3, 'Method','Horn-Schunck');
%创建两个均值对象,用于分析光流矢量
hMean1 = vision.Mean;
hMean2 = vision.Mean('RunningMean', true); %累计平均值,每次输入一个数据,计算所有历史输入的均值
%创建中值滤波对象,用来移除对象分割产生的斑点噪声
hFilter2 = vision.MedianFilter;
hFilter1 = vision.MedianFilter([3 3]);

%创建形态学闭运算,填充分割后的目标空洞
%hClose = vision.MorphologicalClose('Neighborhood', strel('line',20,90));
hClose = vision.MorphologicalClose('Neighborhood', strel('disk',15));%30正好,有点大
%创建跟踪对象(BLOB),用于从视频中分割目标
%hBlob = vision.BlobAnalysis( 'CentroidOutputPort', false, 'AreaOutputPort', true, ...
%    'BoundingBoxOutputPort', true, 'OutputDataType', 'double',  'MinimumBlobArea', 250,...
%    'MaximumBlobArea', 3600, 'MaximumCount', 50);
hBlob = vision.BlobAnalysis( 'CentroidOutputPort', false, 'AreaOutputPort', true, ...           %此参数为最佳无需改动
'BoundingBoxOutputPort', true,'PerimeterOutputPort',true, 'OutputDataType', 'double',  'MinimumBlobArea', 1000,...
'MaximumBlobArea', 20000, 'MaximumCount', 1);

%创建形态学腐蚀对象,移除不需要的对象
hErode = vision.MorphologicalErode('Neighborhood', strel('square',5));
%创建嵌入形状对象,狂出目标边界
hShape1 = vision.ShapeInserter( 'BorderColor', 'Custom',  'CustomBorderColor', [0 1 0]);
hShape2 = vision.ShapeInserter( 'Shape','Lines',  'BorderColor', 'Custom', ...
'CustomBorderColor', [255 255 0]);

%hText = vision.TextInserter( 'Text', '%4d','Location',  [1 1], 'Color', [1 1 1], 'FontSize', 12);

%创建视频播放对象,用来显示原始视频,运动矢量,分割结果,和最终结果
sz = get(0,'ScreenSize');
pos = [(sz(3)-4*(cols+75))/2, (sz(4)-rows)/2 cols+60 rows+80];
hVideo1 = vision.VideoPlayer('Name','Original Video','Position',pos);
pos(1) = pos(1)+cols+75;
hVideo2 = vision.VideoPlayer('Name','Motion Vector','Position',pos);
pos(1) = pos(1)+cols+75;
hVideo3 = vision.VideoPlayer('Name','Thresholded Video','Position',pos);
pos(1) = pos(1)+cols+75;
hVideo4 = vision.VideoPlayer('Name','Results Video','Position',pos);

%从视频中检测跟踪目标
%显示光流矢量的像素点
[xpos,ypos]=meshgrid(1:3:cols,1:3:rows);%每隔5行5列选择像素点
xpos=xpos(:);
ypos=ypos(:);
locs=sub2ind([rows,cols],ypos,xpos);
i = 0;                     %截图标志位
ii = 0;                    %提示窗标志位
j = 0;                     %图片指针
C_k = 0;                   %长宽比指针
S_m = 0;                   %形状分散度指针
%循环处理视频每一帧,直到文件结束
while ~isDone(hReader)
%暂停0.3s,为肉眼观察
pause(0.3);
%从视频文件读取视频帧数
frame  = step(hReader);
%把图像转换为灰度图像
gray_1 = rgb2gray(frame);
gray = step(hFilter1,gray_1);
%一、计算光流矢量,返回一个复数矩阵,分别代表每个像素点u和v
flow = step(hFlow, gray);
%每隔5行5列选择一个像素点,绘制它的光流图。放大20倍
%lines每行对应一条线,分别是第1和第2个点的x,y坐标
%lines = [xpos, ypos, xpos+20*real(flow(locs)), ypos+20*imag(flow(locs))];
lines = [xpos, ypos, xpos+20*real(flow(locs)), ypos+imag(flow(locs))];
%将光流场矢量添加到视频帧上
vector = step(hShape2, frame, lines);

%二、计算光流矢量幅值,因为光流是一个复数矩阵,所以要用到共轭相乘
magnitude = flow .* conj(flow);
%计算光流幅值平均值,表征速度阈值
threshold = 0.5 * step(hMean2, step(hMean1, magnitude));
%使用阈值分割提取运动对象,然后去掉噪声
%carobj = step(hFilter, magnitude >= threshold);
carobj_1 = im2bw(magnitude,threshold);
carobj = step(hFilter2,carobj_1);
%通过形态学腐蚀去掉背景,然后形态学关闭填补目标(BLOB)孔洞
%carobj = step(hClose, step(hErode, carobj));
%形态学腐蚀
carobj1 = step(hErode, carobj);
%闭运算填充
carobj2 = step(hClose, carobj1);

%三、统计估计目标(BLOB)的面积area和边框bbox[left,bottom,width,height]
[area, bbox,perimeter] = step(hBlob, carobj2);

%for j=1:4
%fprintf('%d',bbox(j))
%end

%从grow的位置开始统计
grow=0;
idx = bbox(:,1) > grow;

%% 计算目标中心坐标 即:矩形框的中心坐标
x  = bbox(:,1)+int32(bbox(:,3)/2);
y  = bbox(:,2)+int32(bbox(:,4)/2);

%% 对目标进行提取
infeed = 100;
%infeed=320;
%vertical = 160;
%bbox(:,1)
if  (x >= infeed & i == 0 & x<= (infeed+10))

i = i+1;
%perimeter
%area
%S = perimeter*perimeter/double(area);
%C = double(bbox(idx,4))/double(bbox(idx,3));
carobj_new1 = double(imcrop(gray,[bbox(idx,1),bbox(idx,2),bbox(idx,3)+1,bbox(idx,4)+1]));
imshow(carobj_new1);
end
%% 对目标进行识别
C = double(bbox(idx,4))/double(bbox(idx,3));
if area >0
S = perimeter*perimeter/double(area);
if S >= 50
S_m = S_m+1;
end
end

if (C >=1.4 & C<=4)
C_k = C_k+1;
if (C_k>=10 & S_m>=10 & ii==0)
errordlg('有人闯入','MATLAB warning');
ii = ii+1;
end
end
%%
%计算目标面积和边框面积的百分比
%ratio = zeros(length(idx), 1);
ratio = zeros(length(idx), 1);
ratio(idx) = single(area(idx,1))./single(bbox(idx,3).*bbox(idx,4));
%当面积大于5%认为是目标
%flag = ratio > 0.4;
flag = ratio > 0.3;
%统计数量
count = int32(sum(flag));
%bbox(~flag, :) = int32(-1);
%bbox(~flag, :) = int32(-1);
%给目标添加边框
%result = step(hShape1, frame, bbox);
result = step(hShape1, frame,bbox);
%result(grow:grow+1,:,:) = 1;

%result(1:15,1:30,:) = 0;
%result = step(hText, result, count);

%显示最终处理结果
%step(hVideo1, frame);             %原始视频
%step(hVideo1, gray_1);            %添加光流矢量
step(hVideo2, vector);            %阈值分割结果
step(hVideo3, result);            %带框目标
j = j+1;

end
release(hReader);


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: