混合高斯模型 opencv

本文介绍了混合高斯模型(GMM)在背景建模中的应用,探讨了GMM的历史、优缺点及其在OpenCV中的实现。针对GMM的局限性,文章列举了多种改进方法,如分块策略、模型个数自适应调整和融合帧间差分法。同时,提供了代码实现,并引用了相关研究文献作为参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、GMM发展历史及现状
背景建模方法有很多种,如中值法、均值法、卡尔曼滤波器模型、码本背景模型等,其中混合高斯模型是最经典的算法。GMM最早是由CHris Stauffer等在[1]中提出的,该方法是按照高斯分布对每个像素建立模型, 并通过基于回归滤波的在线 EM 近似方法对模型参数进行更新,它能鲁棒地克服光照变化、 树枝摇动等造成的影响,但该方法也存在一些问题:1)该方法对运动物体在场景中停止不动或者长时间停止时检测失效,而且带有初始学习速度慢,在线更新费时、计算量大;2)无法完整准确地检测大并且运动缓慢的运动目标,运动目标的像素点不集中,只能检测到运动目标的部分轮廓,无法提取出目标对象的完整区域;3)无法将背景显露区域与运动目标区域很好地区分开;4)当运动目标由静止缓慢转化为运动时,易将背景显露区检测为前景,出现“影子”现象。

二、GMM缺点及改进方法
针对上述问题,一些科学研究者又在GMM算法的基础上做了很多的改进:张、白等人[2]引入分块思想,把图像分为L*L块;黄、胡等人[3]也引入了分块的思想,但是他们的分块理念是以当前像素点的8邻域作为一块;华、刘[4]把GMM与改进的帧差法(相邻两帧图像对应像素点8邻域像素值相减之和)相结合,提高了计算效率;Suo等人[5]是将混合高斯模型中的模型个数采改进为自适应的;刘等人[6]融合帧间差分法,检测背景显露区域和运动区域,很好的解决了问题4。除此之外,还有基于纹理的混合高斯模。

三、GMM算法流程
这里写图片描述

这里写图片描述

四、代码实现
代码是下部分使用了下面网页的代码:http://blog.youkuaiyun.com/xw20084898/article/details/41826445自己在阅读的时候因为变量太多有些分不清,在参数更新中,和自己阅读的论文有些不同。注释部分是原作参数更新算法:

#include<opencv.hpp>
#include<highgui.h>
#include<cv.h>

using namespace cv;
using namespace std;

#define COMPONET 5   //混合高斯模型个数
#define ALPHA 0.03  //学习率
#define SD_INIT 6    //方差初始值
#define THRESHOLD 0.25   //前景所占比例
#define D 2.5    

int main()
{
    CvCapture *capture = cvCreateFileCapture("E:\\project2\\videos\\video.avi");

    IplImage *frame, *grayFrame, *foreground, *background;

    int *foreg, *backg, *rank_index;

    double *weight, *mean, *sigma, *u_diff, *rank;

    double p = ALPHA / (1 / (double)COMPONET);

    double rank_temp = 0;
    int rank_index_temp = 0;

    CvRNG state;  //随机生成状态器

    int match, height, width;

    frame = cvQueryFrame(capture);
    grayFrame = cvCreateImage(CvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);
    foreground = cvCreateImage(CvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);
    background = cvCreateImage(CvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);

    height = grayFrame->height;
    width = grayFrame->widthStep;

    foreg = (int*)malloc(sizeof(int)*width*height);
    backg = (int*)malloc(sizeof(int)*width*height);

    rank = (double*)malloc(sizeof(double) * 1 * COMPONET);    //优先级
    weight = (double*)malloc(sizeof(double)*width*height*COMPONET); //权重
    mean = (double *)malloc(sizeof(doub
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值