精华内容
下载资源
问答
  • OpenCV混合高斯背景建模

    千次阅读 2016-07-26 18:49:22
    本文主要内容是一个混合高斯背景建模[1]的OpenCV例子。

    本文主要内容是一个混合高斯背景建模[1]的OpenCV例子。
    想要了解MOG原理可以参考混合高斯背景建模原理及实现

    OpenCV的MOG例子代码如下:

    #include "stdafx.h"
    #include <cv.h>
    #include <highgui.h>
    #include <math.h>
    #include <time.h>
    #include <iostream>
    #include <fstream>
    #include <Windows.h>  
    #include <opencv2/opencv.hpp> 
    
    using namespace cv;  
    using namespace std;
    
    bool pause = false;//是否暂停
    int frameNum = 0;
    
    int main()
    {
        uchar key = false;//用来设置暂停
    
        VideoCapture video("test2.avi"); 
        //Mat frame,mask,thresholdImage,output;
        Mat frame,mask;
        video>>frame;
        //bgSubtractor(history,nmixtures,backgroundRatio,noiseSigma)  
        BackgroundSubtractorMOG bgSubtractor(5,2,0.75,false);
    
        while(true){
            video>>frame;
            ++frameNum;
            //bgSubtractor(当前帧,二值图,学习率);
            bgSubtractor(frame,mask,0.01);
            imshow("frame",frame);
            imshow("mask",mask);
            waitKey(20);
    
            //按键P切换暂停和播放
            key = cvWaitKey(1);
            if(key == 'p') pause = true;
            while(pause)
                if(cvWaitKey(0)=='p')
                    pause = false;  
        }
    
        return 0;
    }

    构造函数可以使用默认构造函数或带形参的构造函数,调用的接口只有重载操作符():

    //! the default constructor
    CV_WRAP BackgroundSubtractorMOG();
    //! the full constructor that takes the length of the history, the number of gaussian mixtures, the background ratio parameter and the noise strength
    CV_WRAP BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio, double noiseSigma=0);
    //! the destructor
    virtual ~BackgroundSubtractorMOG();
    //! the update operator
    virtual void operator()(InputArray image, OutputArray fgmask, double learningRate=0);

    函数调用所涉及到的参数得根据实际应用场景进行调整,下面几张图只是简单的前景检测结果:
    1
    2
    3
    4

    参考资料:

    [1] KaewTraKulPong, Pakorn, and Richard Bowden. “An improved adaptive background mixture model for real-time tracking with shadow detection.” Video-Based Surveillance Systems. Springer US, 2002. 135-144. 引用次数:1228

    展开全文
  • 有哪位大神懂得透彻一点的吗,能指点一下吗
  • ##opencv混合高斯背景建模的实现 环境 ubuntu18.04 opencv 3.2.0 cmake 3.10.2 代码 #include <iostream> #include <opencv/cv.hpp> #include <cstdlib> #include <fstream> using ...

    环境

    ubuntu18.04
    opencv 3.2.0
    cmake 3.10.2
    

    代码

    #include <iostream>
    #include <opencv/cv.hpp>
    #include <cstdlib>
    #include <fstream>
    using namespace std;
    using namespace cv;
    
    #define		HISTORY_NUMBER		20
    int main(int argc, char **argv)
    {
        VideoCapture cap(argv[1]);
        Mat img;
        Mat back,fore,shadow;
        Ptr<BackgroundSubtractorMOG2> model = createBackgroundSubtractorMOG2();
        model->setHistory(HISTORY_NUMBER);  //背景建模使用的帧数
        model->setVarThreshold(64);			//前景阈值
        model->setNMixtures(5);
        model->setBackgroundRatio(0.5);
        model->setDetectShadows(0);			//关闭阴影检测
    
    	//循环到第500帧左右即可实现准确分离前景和背景
        while(1)
        {
            cap >> img;
            if (img.empty())
                break;
            model->apply(img,fore,0.005);
            model->getBackgroundImage(back);
            medianBlur(fore,fore,5);		//噪声消除
            imshow("back",back);
            imshow("fore",fore);
            imshow("img",img);
            waitKey(40);
        }
    
    	return 0;
    }
    

    结果展示

    全景图

    在这里插入图片描述

    背景图

    在这里插入图片描述

    前景二值图

    在这里插入图片描述

    展开全文
  • OpenCV高斯混合背景建模

    万次阅读 多人点赞 2014-04-14 17:40:45
    OpenCV中实现了两个版本的高斯混合背景/前景分割方法(Gaussian Mixture-based Background/Foreground Segmentation Algorithm)[1-2],调用接口很明朗,效果也很好。 BackgroundSubtractorMOG 使用示例 int ...

    OpenCV中实现了两个版本的高斯混合背景/前景分割方法(Gaussian Mixture-based Background/Foreground Segmentation Algorithm)[1-2],调用接口很明朗,效果也很好。

    BackgroundSubtractorMOG 使用示例

     

    int main(){
    	VideoCapture video("1.avi");
    	Mat frame,mask,thresholdImage, output;
    	video>>frame;
    	BackgroundSubtractorMOG bgSubtractor(20,10,0.5,false);
    	while(true){
    		video>>frame;
    		++frameNum;
    		bgSubtractor(frame,mask,0.001);
    		imshow("mask",mask);
    		waitKey(10);
    	}
    	return 0;
    }

    构造函数可以使用默认构造函数或带形参的构造函数:

     

    BackgroundSubtractorMOG::BackgroundSubtractorMOG()
    BackgroundSubtractorMOG::BackgroundSubtractorMOG(int history, int nmixtures, 
    double backgroundRatio, double noiseSigma=0)

     

    其中history为使用历史帧的数目,nmixtures为混合高斯数量,backgroundRatio为背景比例,noiseSigma为噪声权重。

     

    而调用的接口只有重载操作符():

     

    void BackgroundSubtractorMOG::operator()(InputArray image, OutputArray fgmask, double learningRate=0)

    其中image为当前帧图像,fgmask为输出的前景mask,learningRate为背景学习速率。

     

    以下是使用BackgroundSubtractorMOG进行前景/背景检测的一个截图。

    BackgroundSubtractorMOG2 使用示例

     

    int main(){
    	VideoCapture video("1.avi");
    	Mat frame,mask,thresholdImage, output;
    	//video>>frame;
    	BackgroundSubtractorMOG2 bgSubtractor(20,16,true);
    	
    	while(true){
    		video>>frame;
    		++frameNum;
    		bgSubtractor(frame,mask,0.001);
    		cout<<frameNum<<endl;
    		//imshow("mask",mask);
    		//waitKey(10);
    	}
    	return 0;
    }

     

     

     

    同样的,构造函数可以使用默认构造函数和带形参的构造函数

     

    BackgroundSubtractorMOG2::BackgroundSubtractorMOG2()
    BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(int history, 
    float varThreshold, bool bShadowDetection=true )

     

    history同上,varThreshold表示马氏平方距离上使用的来判断是否为背景的阈值(此值不影响背景更新速率),bShadowDetection表示是否使用阴影检测(如果开启阴影检测,则mask中使用127表示阴影)。

     

    使用重载操作符()调用每帧检测函数:

     

    void BackgroundSubtractorMOG2::operator()(InputArray image, OutputArray fgmask, double learningRate=-1)

    参数意义同BackgroundSubtractorMOG中的operator()函数。

     

    同时BackgroundSubtractorMOG2提供了getBackgroundImage()函数用以返回背景图像:

     

    void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage)

     

    另外OpenCV的refman中说新建对象以后还有其他和模型油有关的参数可以修改,不过比较坑的是opencv把这个这些函数参数声明为protected,同时没有提供访问接口,所以要修改的话还是要自己修改源文件提供访问接口。

     

    protected:
        Size frameSize;
        int frameType;
        Mat bgmodel;
        Mat bgmodelUsedModes;//keep track of number of modes per pixel
        int nframes;
        int history;
        int nmixtures;
        //! here it is the maximum allowed number of mixture components.
        //! Actual number is determined dynamically per pixel
        double varThreshold;
        // threshold on the squared Mahalanobis distance to decide if it is well described
        // by the background model or not. Related to Cthr from the paper.
        // This does not influence the update of the background. A typical value could be 4 sigma
        // and that is varThreshold=4*4=16; Corresponds to Tb in the paper.
        /
        // less important parameters - things you might change but be carefull
        
        float backgroundRatio;
        // corresponds to fTB=1-cf from the paper
        // TB - threshold when the component becomes significant enough to be included into
        // the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0.
        // For alpha=0.001 it means that the mode should exist for approximately 105 frames before
        // it is considered foreground
        // float noiseSigma;
        float varThresholdGen;
        //correspondts to Tg - threshold on the squared Mahalan. dist. to decide
        //when a sample is close to the existing components. If it is not close
        //to any a new component will be generated. I use 3 sigma => Tg=3*3=9.
        //Smaller Tg leads to more generated components and higher Tg might make
        //lead to small number of components but they can grow too large
        float fVarInit;
        float fVarMin;
        float fVarMax;
        //initial variance  for the newly generated components.
        //It will will influence the speed of adaptation. A good guess should be made.
        //A simple way is to estimate the typical standard deviation from the images.
        //I used here 10 as a reasonable value
        // min and max can be used to further control the variance
        float fCT;//CT - complexity reduction prior
        //this is related to the number of samples needed to accept that a component
        //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get
        //the standard Stauffer&Grimson algorithm (maybe not exact but very similar)
        //shadow detection parameters
        bool bShadowDetection;//default 1 - do shadow detection
        unsigned char nShadowDetection;//do shadow detection - insert this value as the detection result - 127 default value
        float fTau;
        // Tau - shadow threshold. The shadow is detected if the pixel is darker
        //version of the background. Tau is a threshold on how much darker the shadow can be.
        //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow
        //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.

     

    以下是使用BackgroundSubtractorMOG2检测的前景和背景:

    参考文献:

    [1] KaewTraKulPong, Pakorn, and Richard Bowden. "An improved adaptive background mixture model for real-time tracking with shadow detection." Video-Based Surveillance Systems. Springer US, 2002. 135-144.
    [2] Zivkovic, Zoran. "Improved adaptive Gaussian mixture model for background subtraction." Pattern Recognition, 2004. ICPR 2004. Proceedings of the 17th International Conference on. Vol. 2. IEEE, 2004.

     

     

     

    (转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)

     

     

     

    展开全文
  • 混合高斯背景建模——opencv

    千次阅读 2016-09-03 12:11:37
    混合高斯背景建模原理: 代码:#include<opencv2/highgui.hpp> #include<opencv2/core.hpp> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { CvCapture*capture = ...

    混合高斯背景建模原理:
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

    代码:

    #include<opencv2/highgui.hpp>
    #include<opencv2/core.hpp>
    #include<opencv2/opencv.hpp>
    using namespace std;
    using namespace cv;
    int main()
    {
        CvCapture*capture = cvCreateFileCapture("C:\\Users\\aoe\\Desktop\\avi\\walk.avi");//读取视频
        IplImage*mframe = cvQueryFrame(capture);//读取视频中的一帧
    
        int height = mframe->height;
        int width = mframe->width;
        int C = 4;//number of gaussian components
        int M = 4;//number of background components
        int std_init = 6;//initial standard deviation
        double D = 2.5;
        double T = 0.7;
        double alpha = 0.01;
        double p = alpha / (1 / C);
        double thresh = 0.25;
        int min_index = 0;
        int*rank_ind=0;
        int i, j,k,m;
        int rand_temp=0;
        int rank_ind_temp = 0;
        CvRNG state;
        IplImage*current = cvCreateImage(cvSize(mframe->width, mframe->height), IPL_DEPTH_8U, 1);
        IplImage*test = cvCreateImage(cvSize(mframe->width, mframe->height), IPL_DEPTH_8U, 1);
        IplImage*frg = cvCreateImage(cvSize(mframe->width, mframe->height), IPL_DEPTH_8U, 1);
    
        double*mean = (double*)malloc(sizeof(double)*width*height*C);//pixelmeans
        double*std = (double*)malloc(sizeof(double)*width*height*C);//pixel standard deviations
        double*w = (double*)malloc(sizeof(double)*width*height*C);//权值
        double*u_diff = (double*)malloc(sizeof(double)*width*height*C);//存放像素值与每一个单高斯模式的均值的差值
        int*bg_bw = (int*)malloc(sizeof(int)*width*height);
        double*rank = (double*)malloc(sizeof(double) * 1 * C);
    
        //初始化
        for (i = 0; i < height; i++)//对于每一个像素
        {
            for (j = 0; j < width; j++)
            {
                for (k = 0; k < C; k++)//对于每一个单高斯模型,初始化它的均值,标准差,权值
                {
                    mean[i*width*C + j*C + k] = cvRandReal(&state) * 255;//产生0-255之间的随机数
                    w[i*width*C + j*C + k] = (double)1 / C;//每一个单高斯模型的权值系数
                    std[i*width*C + j*C + k] = std_init;
                }
            }
        }
    
        while (1)
        {
            rank_ind = (int*)malloc(sizeof(int)*C);
    
            cvCvtColor(mframe, current, CV_RGB2GRAY);//灰度化
    
            //对于每一个像素,分别计算它和每一个单高斯模型的均值的差值
            for (i = 0; i < height; i++)//对于每一个像素
            {
                for (j = 0; j < width; j++)
                {
                    for (k = 0; k < C; k++)
                    {
                        u_diff[i*width*C + j*C + k] = abs((uchar)current->imageData[i*width + j] - mean[i*width*C + j*C + k]);
    
                    }
                }
            }
    
            for (i = 0; i < height; i++)
            {
                for (j = 0; j < width; j++)
                {
                    int match = 0;
                    double temp = 0;
                    double single_temp = 0;
                    //遍历所有的单高斯模式,如果此像素满足任一单高斯模式,则匹配;如果此像素不满足任何的单高斯模式,则不匹配
                    for (k = 0; k < C; k++)
                    {
                        if (abs(u_diff[i*width*C + j*C + k]) < D*std[i*width*C + j*C + k])//如果像素匹配某单个高斯模式,则对其权值、均值和标准差进行更新
                        {
                            match = 1;
                            w[i*width*C + j*C + k] += alpha*(1 - w[i*width*C + j*C + k]);//更新权值
                            p = alpha / w[i*width*C + j*C + k];
                            mean[i*width*C + j*C + k] = (1 - p)*mean[i*width*C + j*C + k] + p*(uchar)current->imageData[i*width + j];//更新均值
                            std[i*width*C + j*C + k] = sqrt((1 - p)*(std[i*width*C + j*C + k] * std[i*width*C + j*C + k]) + p*(pow((uchar)current->imageData[i*width + j] - mean[i*width*C + j*C + k], 2)));//更新标准差
    
                        }
                        else
                        {
                            w[i*width*C + j*C + k] = (1 - alpha)*w[i*width*C + j*C + k];//如果像素不符合某单个高斯模型,则将此单高斯模型的权值降低
                        }               
                    }
    
                    if (match == 1)//如果和任一单高斯模式匹配,则将权值归一化
                    {
                        for (k = 0; k < C; k++)
                        {
                            temp += w[i*width*C + j*C + k];//计算四个单高斯模式权值的和
                        }
                        for (k = 0; k < C; k++)
                        {
                            w[i*width*C + j*C + k] = w[i*width*C + j*C + k] / temp;//权值归一化,使得所有权值和为1
                        }
                    }
                    else//如果和所有单高斯模式都不匹配,则寻找权值最小的高斯模式并删除,然后增加一个新的高斯模式
                    {
                        single_temp = w[i*width*C + j*C];
                        for (k = 0; k < C; k++)
                        {
                            if (w[i*width*C + j*C + k] < single_temp)
                            {
                                min_index = k;//寻找权值最小的高斯模式
                                single_temp = w[i*width*C + j*C + k];
                            }
    
                        }
                        mean[i*width*C + j*C + min_index] = (uchar)current->imageData[i*width + j];//建立一个新的高斯模式,均值为当前像素值
                        std[i*width*C + j*C + min_index] = std_init;//标准差为初始值
    
                        for (k = 0; k < C; k++)
                        {
                            temp += w[i*width*C + j*C + k];//计算四个单高斯模式权值的和
                        }
                        for (k = 0; k < C; k++)
                        {
                            w[i*width*C + j*C + k] = w[i*width*C + j*C + k] / temp;//权值归一化,使得所有权值和为1
                        }
    
                    }
    
                    for (k = 0; k < C; k++)//计算每个单高斯模式的重要性
                    {
                        rank[k] = w[i*width*C + j*C + k] / std[i*width*C + j*C + k];
                        rank_ind[k] = k;
                    }
    
                    for (k = 1; k<C; k++)//对重要性排序
                    {
                        for (m = 0; m<k; m++)
                        {
                            if (rank[k] > rank[m])
                            {
                                //swap max values  
                                rand_temp = rank[m];
                                rank[m] = rank[k];
                                rank[k] = rand_temp;
                                //swap max index values  
                                rank_ind_temp = rank_ind[m];
                                rank_ind[m] = rank_ind[k];
                                rank_ind[k] = rank_ind_temp;
                            }
                        }
                    }
    
                    bg_bw[i*width + j] = 0;
                    for (k = 0; k < C; k++)//如果前几个单高斯模式的重要性之和大于T,则将这前几个单高斯模式认为为背景模型
                    {
                        temp += w[i*width*C + j*C + rank_ind[k]];
                        bg_bw[i*width + j] += mean[i*width*C + j*C + rank_ind[k]] * w[i*width*C + j*C + rank_ind[k]];
                        if (temp >= T)
                        {
                            M = k;
                            break;
                        }
                    }
    
                    test->imageData[i*width + j] = (uchar)bg_bw[i*width + j];//背景图像
    
                    match = 0; k = 0;
                    while ((match == 0) && (k <= M))//如果某像素不符合背景模型中任一单高斯模型,则此像素为前景像素
                    {
                        if (abs(u_diff[i*width*C + j*C + rank_ind[k]]) <= D*std[i*width*C + j*C + rank_ind[k]])
                            {
                                frg->imageData[i*width + j] = 0;
                                match = 1;
                            }
                        else
                            frg->imageData[i*width + j] = (uchar)current->imageData[i*width + j];
    
                        k += 1;
    
                    }
    
    
                }
            }
            mframe = cvQueryFrame(capture);
            if (mframe == NULL)
                return -1;
            cvNamedWindow("frg");
            cvShowImage("frg", frg);
            cvNamedWindow("back");
            cvShowImage("back", test);
            char s = cvWaitKey(33);
            //if (s == 27)
            //  break;
            free(rank_ind);
    
        }
        cvWaitKey();
        return 0;
    }
    

    参考:
    http://blog.csdn.net/xw20084898/article/details/41826445

    展开全文
  • 混合高斯背景建模

    2014-06-04 09:51:21
    混合高斯背景建模,使用opencv,CS2012编写
  • 运动检测通常用于分析视频序列中的移动目标,如车辆和行人检测,其中所...常用的背景建模方法有混合高斯背景建模、KNN模型,下面分别给出各自在OpenCV下的代码实现,至于原理,目前我是没打算介绍,有兴趣的可以去...
  • 本例的开发环境是vs2008,用的是基于opencv的开发工具包,可以实现效果较好的前景提取技术 本例的开发环境是vs2008,用的是基于opencv的开发工具包,可以实现效果较好的前景提取技术
  • 引用地址:... GMM是网上到处可见且用得最多的背景建模算法,论文上很多相关概率公式,又看了很多博客对于GMM的解释,直到现在还总是觉得很难理解其中的真谛,从各方面整...
  • 实现了混合高斯背景建模的代码,建立工程后配置opencv库运行
  • 原理大家自行上网搜索吧,OpenCV提供了类BackgroundSubtractorMOG2实现混合高斯背景建模。 代码如下: 代码中用到的视频下载链接:https://pan.baidu.com/s/1mhLS0ZY 密码:bcc2 图像处理开发资料、图像处理开发...
  • 混合高斯模型的基本原理: 图像运动估计是计算机视觉中重要的部分,如何准确的在背景中提取出我们想要的目标是识别的关键。 运动物体的检测分为两种情况:第一种是摄像头静止,目标在运动,背景也相对静止。例如大...
  • 提取监控视频中的车辆,以便于数出车辆数目。。。。。。。。。。。
  • 混合高斯背景建模原理及实现

    万次阅读 多人点赞 2014-05-19 19:23:11
    本次介绍混合高斯背景建模算法,还是老样子,首先介绍理论部分,然后给出代码,最后实验贴图。 一、理论 混合高斯背景建模是基于像素样本统计信息的背景表示方法,利用像素在较长时间内大量样本值的概率密度...
  • 一般情况下这种视频流检测是较复杂的场景,比如交通监控,或者各种监控摄像头,场景比较复杂,因此需要构建背景图像,然后去检测场景中每一帧动态变化的前景部分,GMM高斯模型是建模的一种方法,关于高斯建模的介绍...
  • matlab 混合高斯背景建模的实现

    千次阅读 2020-02-26 15:09:56
    %根据opencv源代码改编 输入...%-------混合高斯背景建模 参数 ----------------- gauss_n = 3; %每个像素点高斯背景模型数量 a = 0.005; %学习速率 alpha vt = 2.5^2; %方差阈值 2.5*2.5倍的方差VarThreshold bgr ...
  • 用python编写的,结合了混合高斯背景建模和轮廓算法的camshift目标跟踪算法
  • 一般情况下这种视频流检测是较复杂的场景,比如交通监控,或者各种监控摄像头,场景比较复杂,因此需要构建背景图像,然后去检测场景中每一帧动态变化的前景部分,GMM高斯模型是建模的一种方法,关于高斯建模的介绍...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,158
精华内容 463
关键字:

opencv混合高斯背景建模