算法原理
原理,
,将所有帧的像素点相加,取平均作为背景的估计,其中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... "); 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 ",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; }