Image processing 基于matlab的视频背景提取与更新

Image processing 基于matlab的视频背景提取与更新,image-processing,computer-vision,matlab,Image Processing,Computer Vision,Matlab,我有一段关于交通现场的视频。现在,我想计算道路区域上车辆面积的百分比(或背景区域上前景区域的百分比)。第一步是背景提取。我已经阅读了许多关于它的文献和科学文章,其中一篇建议使用以下公式的平均值过滤器: 这是文章的链接。结果非常好,这正是我想要的 我遵循他的公式,试着写我的代码。但它不起作用!谁能帮我,给我一些建议。 这是我的代码: clc; % Clear the command window. close all; % Close all figures (except those

我有一段关于交通现场的视频。现在,我想计算道路区域上车辆面积的百分比(或背景区域上前景区域的百分比)。第一步是背景提取。我已经阅读了许多关于它的文献和科学文章,其中一篇建议使用以下公式的平均值过滤器:

这是文章的链接。结果非常好,这正是我想要的

我遵循他的公式,试着写我的代码。但它不起作用!谁能帮我,给我一些建议。 这是我的代码:

clc;    % Clear the command window.
close all;  % Close all figures (except those of imtool.)

imtool close all;  % Close all imtool figures.
clear;  % Erase all existing variables.
workspace;  % Make sure the workspace panel is showing.
fontSize = 14;
%input video;
step = 10;
vob = VideoReader('NKKN.avi');
frame = vob.read(inf);
vidHeight = vob.Height;
vidWidth = vob.Width;
nFrames = vob.NumberOfFrames;
%%% First-iteration background frame
background_frame = double(frame*0);
redbackground_frame = background_frame(:,:,1);
greenbackground_frame = background_frame(:,:,2);
bluebackground_frame = background_frame(:,:,3);
%calculate background
i = 0;
for k = 1:10 %get background from 10 frame (J=10)
    thisframe = double(read(vob, k));
    %background_frame = background_frame + thisframe;
    redbackground_frame = redbackground_frame + thisframe(:,:,1);
    greenbackground_frame = greenbackground_frame + thisframe(:,:,2);
    bluebackground_frame = bluebackground_frame + thisframe(:,:,3);
    i=i+1;
    disp(i);
end

A = redbackground_frame/i;
B = greenbackground_frame/i;
C = bluebackground_frame/i;
background = cat(3,A,B,C);
imshow(background);

您可以保留
B
帧的缓冲区,以便动态估计背景

buff = NaN( [vidHeight, vidWidth, 3, B] ); % allocate room for buffer

% process the video
for fi = 1:nFrames
    % read current frame
    thisframe = double(read(vob, k)) / 255; % convert to [0..1] range 

    % update background model
    buff(:, :, :, mod( fi, B ) + 1 ) = thisframe;
    background_L1 = nanmedian( buff, 4 ); % I think this is better than `mean` - try it!
    background_L2 = nanmean( buff, 4 );

    % do whatever processing you need with fi-th frame 
    % and the current background mode...
    % ...
end
请注意,如果
fi
B
(即,您处理的帧少于
B
帧),则背景模型不稳定。我使用
NaN
s作为缓冲区的默认值,并且在估计backgound模型时忽略这些值——这就是为什么我使用and而不是简单的
中值
均值

vob = VideoReader('NKKN.avi');
frame = vob.read(inf);
vidHeight = vob.Height;
vidWidth = vob.Width;
nFrames = vob.NumberOfFrames;
%allocate room for buffer of 20 frames
buff = NaN( [vidHeight, vidWidth, 3, 20] ); % allocate room for buffer
for fi = 1:20:nFrames
disp(fi);
% read current frame
thisframe = double(read(vob, fi)) / 255; % convert to [0..1] range 
% update background model
buff(:, :, :, mod( fi, 10 ) + 1 ) = thisframe;
background_L1 = nanmedian( buff, 4 );
background_L2 = nanmean( buff, 4 );



hImage = subplot(2, 2, 1);
image(thisframe);
caption = sprintf('thisframe');
title(caption, 'FontSize', fontSize);
drawnow; % Force it to refresh the window.

subplot(2,2,2);
imshow(background_L2);
title('background-L2');

subplot(2,2,3);
imshow(background_L1);
title('background-L1');

结束

这里有一个非常简单的解决方案,您可以在此基础上进行构建。首先,您需要一个没有交通的场景的背景图像样本。我们称之为“bg”

以下是伪代码中的一种简单方法:

      load in background image 'bg'
      set threshold upper value
      set threshold lower value
      loop until done for each frame
      {
        subtract 'bg' image from your first frame
        if pixel value of foreground > than threshold upper value
        {
          set foreground pixel value to 'nan'
        }
        if pixel value of foreground < than threshold lower value
        {
          set foreground pixel value to 'nan'
        }
        if pixel value of foreground == 0
        {
          set foreground pixel value to 'nan'
        }
      }
加载背景图像“bg”
设置阈值上限值
设置阈值下限值
循环直到每帧完成
{
从第一帧中减去“bg”图像
如果前景的像素值>阈值上限值
{
将前景像素值设置为“nan”
}
如果前景像素值<阈值下限值
{
将前景像素值设置为“nan”
}
如果前景的像素值==0
{
将前景像素值设置为“nan”
}
}
这将包含前景图像,以仅显示您感兴趣的场景部分。注意:通过使用立体相机给你深度感知,这个过程可以大大增强。但是,您应该能够在此代码的基础上删除图像中不需要的部分。

这实际上是基于和答案的。我没有使用,不推荐使用。我还采纳了user3725204的建议,因为不需要读取所有帧

function backGrnd = getBackGrnd(filename, nTest, method)
    tic
    if nargin < 2, nTest = 20; end
    if nargin < 3, method = 'median'; end
    v = VideoReader(filename);
    nChannel = size(readFrame(v), 3);
    tTest = linspace(0, v.Duration-1/v.FrameRate , nTest);
    %allocate room for buffer
    buff = NaN([v.Height, v.Width, nChannel, nTest]);
    for fi = 1:nTest
        v.CurrentTime =tTest(fi);
        % read current frame and update model
        buff(:, :, :, mod(fi, nTest) + 1) = readFrame(v);
    end
    switch lower(method)
        case 'median'
            backGrnd = nanmedian(buff, 4);
        case 'mean'
            backGrnd = nanmean(buff, 4);
    end
    toc
end

提取此视频的背景


关于“不工作”,你必须更具体一点:你有没有发现任何错误?输出
background
是否完全关闭?如果您不告诉我们问题出在哪里,我们如何帮助您解决问题?顺便说一句,如果您的时间窗口(即链接公式中的
j
)不太大,您可能会使用
平均值
中值
(L1与L2正则化,对异常值更稳健)获得更好的结果。您好,我已经得到了视频的前景,现在我想计算我检测到的每个物体的速度。但我不知道如何将与同一物体相对应的检测关联起来,我找到了这个例子,这正是我想要的,但它们使用计算机视觉工具箱,我可以理解它是如何工作的。你能更清楚地告诉我吗?或者你能给我一个这样的代码,但不能使用计算机视觉工具箱。对不起,谢,我不知道。你的回答很有帮助。我接受了,但我没有足够的声誉来为你投票。这是我上面问题的链接。你能帮助我吗?谢谢你的帮助,谢。对不起,我问得不清楚。我的代码没有错误。但结果并不像我预期的那样。运行我的代码后,我的最终背景是白色的。我尝试了你的背景更新代码,但它没有生成背景。你的代码的结果是:像第f帧一样的背景,像第f帧一样的背景。这是你的代码的结果:这是我期望的结果:这是我的代码的结果:
subplot(221); imshow(uint8(TrafficVisionLab.getBackGrnd('traffic.avi', 10, 'mean')));
subplot(222); imshow(uint8(TrafficVisionLab.getBackGrnd('traffic.avi', 10, 'median')));
subplot(223); imshow(uint8(TrafficVisionLab.getBackGrnd('traffic.avi', 50, 'mean')));
subplot(224); imshow(uint8(TrafficVisionLab.getBackGrnd('traffic.avi', 50, 'median')));
clear all
close all
reader = VideoReader('C:\Users\Ali Sahzil\Desktop\Media.wmv'); // your video file location
vid = {};
while hasFrame(reader)
    vid{end+1} = im2single(readFrame(reader));
end

bg = mean( cat(4, vid{:}), 4);

x =bg;
imshow( bg );