算法原理
原理,
,将所有帧的像素点相加,取平均作为背景的估计,其中N是当前所在帧,不是所有帧。
Matlab实现
mov=aviread('highway.AVI'); %读入
fnum=size(mov,2) ; %读取电影的祯数,mov为1*temp
[x,y,z]=size(mov(1).cdata(:,:,:));
frame_src=zeros(x,y,z); %原始图像
frame_all=zeros(x,y,z);
frame_avg=zeros(x,y,z); %平均图像
frame_src_avg=zeros(x,y,z); %原始图像减平均图像
frame_src_avg_all=zeros(x,y,z);
frame_result=zeros(x,y,z);
for i=1:fnum
frame_src=mov(i).cdata(:,:,:);
frame_src=double(frame_src);
frame_all=frame_all+frame_src;
frame_avg=frame_all/i;
% frame_src_avg=sqrt(frame_src.^2-frame_avg.^2);
% frame_src_avg_all=frame_src_avg_all+frame_src_avg;
% frame_result=frame_src_avg/i;
subplot(2,2,1);
frame_src=uint8(frame_src);
imshow(frame_src);
title('原始图像');
subplot(2,2,2);
frame_avg=uint8(frame_avg);
imshow(frame_avg);
title('背景');
% frame_src_gray=rgb2gray(frame_src);
% frame_avg_gray=rgb2gray(frame_avg);
% f=frame_src_gray-frame_avg_gray;
% subplot(2,2,3);
% imshow(f);
pause(0.1);
end
实现效果
Opencv实现
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <stdio.h>
#include<math.h>
#define image_width 320
#define image_height 240
int main(int argc,char** argv)
{
int i;
double alpha=0.0,beta=0.0;
CvCapture* capture=cvCaptureFromAVI("E:\\研二上\\video\\highway.AVI");
if(!capture)
{
printf("Could not initialize...\n");
return -1;
}
IplImage* img=cvQueryFrame(capture);
IplImage* background=cvCreateImage(cvSize(img->width,img->height),img->depth,3);
IplImage* advbackground=cvCreateImage(cvSize(img->width,img->height),img->depth,3);
int index=0;
cvNamedWindow("video",1);
cvNamedWindow("back",1);
cvNamedWindow("advback",1);
CvMat* Mat_src=cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat_dst=cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat_dst1=cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat_tmp1=cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat_tmp2=cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat1 = cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat2 = cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat3 = cvCreateMat(img->height,img->width,CV_32FC3);
CvMat* Mat4 = cvCreateMat(img->height,img->width,CV_32FC3);
cvSetZero(Mat_dst);
cvSetZero(Mat2);
cvSetZero(Mat3);
while(img=cvQueryFrame(capture))
{
index++;
printf("index%d\n",index);
cvShowImage("video",img);
cvConvert(img,Mat_src); //转换成32位浮点型
cvAdd(Mat_src,Mat_dst,Mat_dst);
for(i=0;i<(Mat_dst1->rows*Mat_dst1->cols*3);i++)
{
Mat_dst1->data.fl[i]=Mat_dst->data.fl[i]/index;
}
for(i=0;i<(Mat1->rows*Mat1->cols*3);i++)
{
Mat1->data.fl[i] = sqrt(pow(Mat_src->data.fl[i],2.0f)-pow(Mat_dst1->data.fl[i],2.0f));
}
cvAdd(Mat1,Mat2,Mat2);
for(i=0;i<(Mat3->height*Mat3->width*3);i++)
{
Mat3->data.fl[i] = Mat2->data.fl[i]/index; //残影部分
}
for(i=0;i<(Mat4->height*Mat4->width*3);i++)
{
Mat4->data.fl[i] =abs(Mat_dst1->data.fl[i]-Mat3->data.fl[i]); //改进后的阵列
}
cvConvert(Mat1,advbackground);
cvShowImage("advback",advbackground);
cvConvert(Mat_dst1,background);
cvShowImage("back",background);
cvWaitKey(50);
}
cvDestroyWindow("video");
cvReleaseCapture( &capture );
return 0;
}