单高斯背景建模

来源:互联网 发布:windows asp.net 编辑:程序博客网 时间:2024/06/05 08:21

算法原理



Opencv实现

/*******************单高斯背景建模v1.0*************************************************2010.01.22****************************/#include <highgui.h>#include <cv.h>#include <math.h>#include <stdio.h>#include <stdlib.h>int main(int argc, char **argv){    //新建窗口    cvNamedWindow("origin", CV_WINDOW_AUTOSIZE);    cvNamedWindow("processing", CV_WINDOW_AUTOSIZE);    double alpha = 0.05;    //背景建模alpha值    double std_init = 20;    //初始标准差    double var_init = std_init * std_init;    //初始方差        double lamda = 2.5 * 1.2;    //背景更新参数char* fileName="E:\\研二上\\video\\highway.AVI";    //视频文件    CvCapture *capture = NULL;//     //读取视频文件//     if (argc == 1)//     {//         //从摄像头读入//         capture = cvCreateCameraCapture(0);//     }//     else if (argc == 2)//     {//         //从文件读入//         capture = cvCreateFileCapture(argv[1]);//     }//     else//     {//         //读入错误//         printf("input error\n");//         return -1;//     }capture = cvCreateFileCapture(fileName);    IplImage *frame = NULL;        //原始图像    IplImage *frame_u = NULL;    //期望图像    IplImage *frame_var = NULL;    //方差图像    IplImage *frame_std = NULL;    //标准差    CvScalar pixel = {0};        //像素原始值    CvScalar pixel_u = {0};        //像素期望    CvScalar pixel_var = {0};    //像素方差    CvScalar pixel_std = {0};    //像素标准差    //初始化frame_u, frame_var, frame_std    frame = cvQueryFrame(capture);    frame_u = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);    frame_var = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);    frame_std = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);    for (int y = 0; y < frame->height; ++y)    {        for (int x = 0; x < frame->width; ++x)        {            pixel = cvGet2D(frame, y, x);            pixel_u.val[0] = pixel.val[0];            pixel_u.val[1] = pixel.val[1];            pixel_u.val[2] = pixel.val[2];            pixel_std.val[0] = std_init;            pixel_std.val[1] = std_init;            pixel_std.val[2] = std_init;            pixel_var.val[0] = var_init;            pixel_var.val[1] = var_init;            pixel_var.val[2] = var_init;            cvSet2D(frame_u, y, x, pixel_u);            cvSet2D(frame_var, y, x, pixel_var);            cvSet2D(frame_std, y, x, pixel_std);        }    }    while (cvWaitKey(33) != 27)        //按ESC键退出, 帧率33ms    {        frame = cvQueryFrame(capture);        //视频结束退出        if (!frame)        {            break;        }        //单高斯背景更新        for (int y = 0; y < frame->height; ++y)        {            for (int x = 0; x < frame->width; ++x)            {                pixel = cvGet2D(frame, y, x);                pixel_u = cvGet2D(frame_u, y, x);                pixel_std = cvGet2D(frame_std, y, x);                pixel_var = cvGet2D(frame_var, y, x);                //|I-u| < lamda*std 时认为是背景, 进行更新                if (fabs(pixel.val[0] - pixel_u.val[0]) < lamda * pixel_std.val[0] &&                    fabs(pixel.val[1] - pixel_u.val[1]) < lamda * pixel_std.val[1] &&                    fabs(pixel.val[2] - pixel_u.val[2]) < lamda * pixel_std.val[2])                {                    //更新期望 u = (1-alpha)*u + alpha*I                    pixel_u.val[0] = (1 - alpha) * pixel_u.val[0] + alpha * pixel.val[0];                    pixel_u.val[1] = (1 - alpha) * pixel_u.val[1] + alpha * pixel.val[1];                    pixel_u.val[2] = (1 - alpha) * pixel_u.val[2] + alpha * pixel.val[2];                    //更新方差 var = (1-alpha)*var + alpha*(I-u)^2                    pixel_var.val[0] = (1 - alpha) * pixel_var.val[0] +                                    (pixel.val[0] - pixel_u.val[0]) * (pixel.val[0] - pixel_u.val[0]);                    pixel_var.val[1] = (1 - alpha) * pixel_var.val[1] +                                    (pixel.val[1] - pixel_u.val[1]) * (pixel.val[1] - pixel_u.val[1]);                    pixel_var.val[2] = (1 - alpha) * pixel_var.val[2] +                                    (pixel.val[2] - pixel_u.val[2]) * (pixel.val[2] - pixel_u.val[2]);                    //更新标准差                    pixel_std.val[0] = sqrt(pixel_var.val[0]);                    pixel_std.val[1] = sqrt(pixel_var.val[1]);                    pixel_std.val[2] = sqrt(pixel_var.val[2]);                    //写入矩阵                    cvSet2D(frame_u, y, x, pixel_u);                    cvSet2D(frame_var, y, x, pixel_var);                    cvSet2D(frame_std, y, x, pixel_std);                }            }        }        //显示结果        cvShowImage("origin", frame);        cvShowImage("processing", frame_u);    }    //释放内存    cvReleaseCapture(&capture);    cvReleaseImage(&frame);    cvReleaseImage(&frame_u);    cvReleaseImage(&frame_var);    cvReleaseImage(&frame_std);    cvDestroyWindow("origin");    cvDestroyWindow("processing");    return 0;}

matlab实现

close all;clear all;mov=aviread('E:\研二上\video\highway.AVI'); %读入fnum=size(mov,2); %读取电影的祯数,mov为1*tempalpah=0.005;std_init=20;var_init=std_init*std_init;lamda=2.5*2.5;frame=uint8(ones(304,400,3));frame_u=frame;frame_var=frame;frame_std=frame;% frame=imread('D:\Code\Data\00011\1.bmp');frame=mov(1).cdata(:,:,:);frame_u=frame;frame_var=var_init*frame_var;frame_std=std_init*frame_std;for index=2:fnum%     fileName=strcat('D:\Code\Data\00011\',int2str(index),'.','bmp'); %将每祯转成jpg的图片%     frame=imread(fileName);    frame=mov(index).cdata(:,:,:);    [x,y,z]=size(frame);    for i=1:x        for j=1:y            frame_rgb=frame(i,j,:);            frame_u_rgb=frame_u(i,j,:);            frame_std_rgb=frame_std(i,j,:);            frame_var_rgb=frame_var(i,j,:);            if company_rgb(frame_rgb,frame_u_rgb,lamda,frame_std_rgb)                   frame_u_rgb=(1-alpah).*frame_u_rgb+alpah.*frame_var_rgb;                   frame_var_rgb=(1-alpah).*frame_var_rgb+alpah.*(frame_rgb-frame_u_rgb).^2;                                                  frame_std_rgb=sqrt(double(frame_var_rgb));                               frame_u(i,j,:)= frame_u_rgb;                   frame_std(i,j,:)=frame_std_rgb;                   frame_var(i,j,:)=frame_var_rgb;                               end        end    end       subplot(2,1,1);    imshow(frame);    title('src');    subplot(2,1,2);    imshow(frame_u);    title('result');        pause(0.01);end

function [ output_args ] = company_rgb( frame_rgb,frame_u_rgb,lamda,frame_std_rgb )%UNTITLED2 Summary of this function goes here%   Detailed explanation goes here    var_r=abs(frame_rgb(1)-frame_u_rgb(1));    var_g=abs(frame_rgb(2)-frame_u_rgb(2));    var_b=abs(frame_rgb(3)-frame_u_rgb(3));    if var_r<lamda*frame_std_rgb(1) && var_g<lamda*frame_std_rgb(2) && var_b<lamda*frame_std_rgb(3)        output_args=1;    else        output_args=0;    endend