matlab帧差法图像识别

帧间差分法是对时间上连续的两帧图像进行差分运算,得到差分图像。

做帧差:采集前一帧图像,第二帧图像,先对其进行灰度化处理。然后前后做差,将差分后的图像二值化后进行边缘检测

matlab帧差法图像识别_第1张图片

如图所示运动的球体被识别(黄框),上图为原视频,下图为识别结果。

附代码:

主函数(帧差及图像处理)

clc;
clear;

pathname='C:\Users\Administrator\Desktop\work\data\';%二值化图像路径
videopath='C:\Users\Administrator\Desktop\work\video\';%视频帧路径
videoObj = VideoReader('sample.avi');%读视频文件 
nframes = get(videoObj, 'NumFrames');%获取视频文件帧个数 
lenth=nframes-2;%处理后帧数
level=0.1;%二值化阈值

for k = 1 : lenth 
    currentFrame1 = read(videoObj, k);%读取第i帧
    currentFrame2 = read(videoObj, k+1); 
    grayFrame1 = rgb2gray(currentFrame1);%灰度化 
    grayFrame2 = rgb2gray(currentFrame2);
    difgrayFrame= grayFrame2 - grayFrame1;%邻帧差 
    k1=num2str(k);
    filename=[k1,'.jpg'];
    imwrite(currentFrame1,[videopath,filename]);
    bw=im2bw(difgrayFrame,level);%二值化
    se = strel('disk',20);%构造闭运算算子
    closeBW=imclose(bw,se);%闭运算 
    imwrite(closeBW,[pathname,filename]);% 将每步处理后的图像到某个目录下
    [xMax,xMin,yMax,yMin]=draw([pathname,filename]);
    data = imread([videopath, filename]);
    pt=[xMin,yMin];
    wSize=[xMax-xMin,yMax-yMin];
    des = drawRect(data,pt,wSize,5 );
    subplot(2,1,1)
    imshow(data)
    subplot(2,1,2)
    imshow(des)
    imwrite(des,[videopath,filename]);
end

cd(videopath); %读取所有的jpg图片
allnames = struct2cell(dir('*.jpg'));
[difgrayFrame,len]=size(allnames);
aviobj = VideoWriter('C:\Users\Administrator\Desktop\work\save_video2.avi');%视频存储位置
aviobj.FrameRate = 25; %设置帧率

open(aviobj) %制作视频
for i = 1:lenth
     name = [num2str(i),'.jpg'];
     frame = imread(name);
     writeVideo(aviobj,frame);
end
close(aviobj)

求方框

function[xMax,xMin,yMax,yMin]=draw(c)
img =  imread(c);
imgTh = im2uint8(img);

 angle = 0; 
 imgRotated = double(imrotate(imgTh,angle,'bicubic','loose')); 
 [row, col] = size(imgRotated);

    %%%判断最小外接矩形的边界
    for i = 1 : row
        if sum(imgRotated(i, :)) > col
            break;
        end
    end
    yMinTest = i;

    for i = row : -1 : 1
        if sum(imgRotated(i, :)) > col
            break;
        end
    end
    yMaxTest = i;

    for i = 1 : col
        if sum(imgRotated(:, i)) > row
            break;
        end
    end
    xMinTest = i;

    for i = col : -1 : 1
        if sum(imgRotated(:, i)) > row
            break;
        end
    end
    xMaxTest = i;
    %%%判断最小外接矩形的边界
    

    if angle == 0 || nowSize < typicalSize
        xMin = xMinTest;
        yMin = yMinTest;
        xMax = xMaxTest;
        yMax = yMaxTest;
end

画方框

function [ dest ] = drawRect( src, pt, wSize,  lineSize, color )

%----------------------------------------------------------------------
%输入:
% src:        原始图像,可以为灰度图,可为彩色图
% pt:         左上角坐标   [x1, y1]
% wSize:   框的大小      [wx, wy]
% lineSize: 线的宽度
% color:     线的颜色      [r,  g,  b] 
%----------------------------------------------------------------------
%输出:
% dest:           画好了的图像
%----------------------------------------------------------------------


 
 
%判断输入参数个数
if nargin < 5
    color = [255 255 0];
end
 
if nargin < 4
    lineSize = 1;
end
 
if nargin < 3
    disp('输入参数不够 !!!');
    return;
end
 
 
 
 
 
%判断框的边界问题
[yA, xA, z] = size(src);
x1 = pt(1);
y1 = pt(2);
wx = wSize(1);
wy = wSize(2);
if  x1>xA || ...
        y1>yA||...
        (x1+wx)>xA||...
        (y1+wy)>yA
 
    disp('画的框将超过图像 !!!');
    return;
end
 
%如果是单通道的灰度图,转成3通道的图像
if 1==z
    dest(:, : ,1) = src;
    dest(:, : ,2) = src;
    dest(:, : ,3) = src;
else
    dest = src;
end
 
%开始画框图
for c = 1 : 3                 %3个通道,r,g,b分别画
    for dl = 1 : lineSize   %线的宽度,线条是向外面扩展的
        d = dl - 1;


            dest(  y1-d ,            (x1-d):(x1+wx+d) ,  c  ) =  color(c); %上方线条
            dest(  y1+wy+d ,    (x1-d):(x1+wx+d) ,  c  ) =  color(c); %下方线条
            dest(  (y1-d):(y1+wy+d) ,   x1-d ,           c  ) =  color(c); %左方线条
            dest(  (y1-d):(y1+wy+d) ,   x1+wx+d ,    c  ) =  color(c); %左方线条

    end    
end %主循环尾
 
 
end %函数尾

实例视频与结果

sample

save_video2

你可能感兴趣的:(matlab,图像处理)