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 );