混合高斯模型

混合高斯模型

混合高斯模型使用K(基本為3到5個)個高斯模型來表征圖像中各個像素點的特徵,在新一幀圖像獲得後更新混合高斯模型,用當前圖像中的每個像素點與混合高斯模型匹配,如果成功則判定該點為背景點, 否則為前景點。通觀整個高斯模型,他主要是由方差和均值兩個參數決定,對均值和方差的學習,採取不同的學習機制,將直接影響到模型的穩定性、精確性和收斂性。

基本介紹

  • 中文名:混合高斯模型
  • 用途:表征圖像中各個像素點的特徵
  • 原理:使用K(基本3到5個)個高斯模型
  • 主要參數:方差和均值
概念介紹,背景模型,

概念介紹

高斯模型就是用高斯機率密度函式(常態分配曲線)精確地量化事物,將一個事物分解為若干的基於高斯機率密度函式(常態分配曲線)形成的模型。對圖像背景建立高斯模型的原理及過程:圖像灰度直方圖反映的是圖像中某個灰度值出現的頻次,也可以以為是圖像灰度機率密度的估計。

背景模型

單分布高斯背景模型認為,對一個背景圖像,特定像素亮度的分布滿足高斯分布,即對背景圖像B,(x,y)點的亮度滿足:
IB(x,y) ~ N(u,d)
這樣我們的背景模型的每個象素屬性包括兩個參數:平均值u 和 方差d。
對於一幅給定的圖像G,如果 Exp(-(IG(x,y)-u(x,y))^2/(2*d^2)) > T,認為(x,y)是背景點,反之是前景點。
同時,隨著時間的變化,背景圖像也會發生緩慢的變化,這時我們要不斷更新每個像素點的參數
u(t+1,x,y) = a*u(t,x,y) + (1-a)*I(x,y)
這裡,a稱為更新參數,表示背景變化的速度,一般情況下,我們不更新d(實驗中發現更不更新d,效果變化不大)。
高斯混合模型是用於背景提取的方法,OpenCV的cvaux中cvbgfg_gaussmix.cpp檔案根據文獻An improved adaptive background mixture model for real-time tracking with shadow中提供的方法編寫了高斯混合模型函式。其中定義了CvGaussBGModel類用於存放高斯混合模型的各個參數。我用OpenCV使用高斯混合模型函式分以下幾步:
1。需要用到icvUpdateGaussianBGModel,icvReleaseGaussianBGModel兩個函式,但是源程式中將這兩個函式定義為內部函式,需要做一些修改,首先將cvbgfg_gaussmix.cpp中前面兩個函式的聲明static void CV_CDECL icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
static int CV_CDECL icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );兩行代碼注釋掉。然後在cvbgfg_gaussmix.cpp中間部分兩個函式的定義部分,函式頭static int和static void改成CV_IMPL int 和CV_IMPL void。最後在cvaux.h檔案中CVAPI(CvBGStatModel*) cvCreateGaussianBGModel( IplImage* first_frame,
CvGaussBGStatModelParams* parameters CV_DEFAULT(NULL));這句後面加上以下兩句CVAPI(void) icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
CVAPI(int) icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );
程式修改完畢,點rebuild all,全部重新編譯。
2。在程式初始化部分定義高斯混合模型參數CvGaussBGModel* bg_model=NULL;在讀取第一幀圖像(背景圖像)時,進行高斯背景建模bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(image, 0);image可以是灰度圖象也可以是彩色圖像。接下來再讀取當前幀時,更新高斯模型
regioncount=icvUpdateGaussianBGModel(currframe, bg_model );regioncount的含義我不確定,我理解是代表背景中不同顏色區域的個數,這個參數我沒有用到,它只是icvUpdateGaussianBGModel函式的返回值。
3。現在bg_model已經保存了經過高斯混合模型分類後的結果,bg_model->background保存了背景圖像,bg_model->foreground保存了前景圖像。
#include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <cvaux.h>//必須引此頭檔案
int main( int argc, char** argv )
{
IplImage* pFrame = NULL;
IplImage* pFrImg = NULL;
IplImage* pBkImg = NULL;
CvCapture* pCapture = NULL;
int nFrmNum = 0;
cvNamedWindow("video", 1);
cvNamedWindow("background",1);
cvNamedWindow("foreground",1);
cvMoveWindow("video", 30, 0);
cvMoveWindow("background", 360, 0);
cvMoveWindow("foreground", 690, 0);
if( argc > 2 )
{
fprintf(stderr, "Usage: bkgrd [video_file_name]\n");
return -1;
}
//打開視頻檔案
if(argc == 2)
if( !(pCapture = cvCaptureFromFile(argv[1])))
{
fprintf(stderr, "Can not open video file %s\n", argv[1]);
return -2;
}
//打開攝像頭
if (argc == 1)
if( !(pCapture = cvCaptureFromCAM(-1)))
{
fprintf(stderr, "Can not open camera.\n");
return -2;
}
//初始化高斯混合模型參數
CvGaussBGModel* bg_model=NULL;
while(pFrame = cvQueryFrame( pCapture ))
{
nFrmNum++;
if(nFrmNum == 1)
{
pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);
pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
//高斯背景建模,pFrame可以是多通道圖像也可以是單通道圖像
//cvCreateGaussianBGModel函式返回值為CvBGStatModel*,
//需要強制轉換成CvGaussBGModel*
bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame, 0);
}
else
{
//更新高斯模型
cvUpdateBGStatModel(pFrame, (CvBGStatModel *)bg_model );
//pFrImg為前景圖像,只能為單通道
//pBkImg為背景圖像,可以為單通道或與pFrame通道數相同
cvCopy(bg_model->foreground,pFrImg,0);
cvCopy(bg_model->background,pBkImg,0);
//把圖像正過來
pBkImg->origin=1;
pFrImg->origin=1;
cvShowImage("video", pFrame);
cvShowImage("background", pBkImg);
cvShowImage("foreground", pFrImg);
if( cvWaitKey(2) >= 0 )
break;
}
}
//釋放高斯模型參數占用記憶體
cvReleaseBGStatModel((CvBGStatModel**)&bg_model);
cvDestroyWindow("video");
cvDestroyWindow("background");
cvDestroyWindow("foreground");
cvReleaseImage(&pFrImg);
cvReleaseImage(&pBkImg);
cvReleaseCapture(&pCapture);
return 0;
}

相關詞條

熱門詞條

聯絡我們