📄 sgmm.cpp
字号:
// GMM.cpp: implementation of the GMM class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "sGM.h"
#include "sGMM.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
const unsigned int TH = 10000, TM = 10000;
const int TT=10000;
const float T = (float)0.6;
sGMM::sGMM()
// : T(0.5)
{
m_ptr = NULL;
}
void sGMM::Init(BYTE num, BYTE size, float *mean)
{
m_num = num;
m_ptr = new sGM*[num];
ASSERT(m_ptr != NULL);
if(m_ptr != NULL)
{
m_ptr[0] = new sGM;//不再初始化为相同分布
ASSERT(m_ptr[0] != NULL);
m_ptr[0]->Init(size, mean);
for(int i=0; i<size; i++)
{
mean[i] = -100;
}
for(i=1; i<num; i++)
{
m_ptr[i] = new sGM;
ASSERT(m_ptr[i] != NULL);
m_ptr[i]->Init(size, mean);
}
}
}
sGMM::~sGMM()
{
if(m_ptr != NULL)
{
for(int i=0; i<m_num; i++)
{
delete m_ptr[i];
}
delete []m_ptr;
}
}
BOOL sGMM::Process(float *value)
{
//对当前像素进行一系列处理,是运动目标像素返回true,否则返回false
//确定是否有匹配
//有: 是否背景,生成运动目标图像
// 更新所有的weight和匹配模型的mean,variance
// 对模型排序,确定新的背景模型
//没有:更新最后一个模型
int i, match = -1;
float dist, minDist = 1000000.0;
for(i=0; i<m_num; i++)
{
if(m_ptr[i]->IsValid(value, dist) && dist < minDist)
{
minDist = dist;
match = i;
}
}
if(match == -1)//没有匹配
{
dist = (float)(m_ptr[m_num-1]->m_weight - 0.1) / (m_num - 1);
m_ptr[m_num-1]->Init(value, (float)0.1);
m_ptr[m_num-1]->match=true;
for(i=0; i<m_num-1; i++)
{
m_ptr[i]->m_weight += dist;
}
return true;
}
else//有匹配
{
//更新模型参数
for(i=0; i<m_num; i++)
{
if(i == match)//匹配的模型
{
m_ptr[i]->Update(value, minDist);
m_ptr[i]->match=true;
}
else//其它模型
{
m_ptr[i]->Update();
}
}
//模型按weight/variance排序
sGM *temp;
for(i=match; i>0; i--)
{
if(m_ptr[i]->m_weight/m_ptr[i]->m_variance > m_ptr[i-1]->m_weight/m_ptr[i-1]->m_variance)
//if(m_ptr[i]->m_weight > m_ptr[i-1]->m_weight)
{
temp = m_ptr[i];
m_ptr[i] = m_ptr[i-1];
m_ptr[i-1] = temp;
match --;//注意matc的h变化
}
else
{
break;//其它顺序肯定不变,可跳出
}
}
//确定新的背景模型
float wsum=0.0;
for(i=0; i<m_num; i++)
{
wsum += m_ptr[i]->m_weight;
if(!m_ptr[i]->m_background)//false->true
{
if(i == match)
{
if(m_ptr[i]->m_time == 0)
{
m_ptr[i]->m_time =GetTickCount();
}
else if(GetTickCount() - m_ptr[i]->m_time > TH)
{
m_ptr[i]->m_background = true;
m_ptr[i]->m_time &= 0;
}
}
}
else//true->true
{
m_ptr[i]->m_time &= 0;
}
if(wsum > T)
{
break;
}
}
for(i++; i<m_num; i++)
{
if(m_ptr[i]->m_background)//true->false
{
if(i != match)
{
if(m_ptr[i]->m_time == 0)
{
m_ptr[i]->m_time =GetTickCount();
}
else if(GetTickCount()- m_ptr[i]->m_time > TM)
{
m_ptr[i]->m_background = false;
m_ptr[i]->m_time &= 0;
}
}
}
else//false->false
{
m_ptr[i]->m_time &= 0;
}
}
return !m_ptr[match]->m_background;
}
}
BOOL sGMM::Process(float *value,int frameNUM)
{
//对当前像素进行一系列处理,是运动目标像素返回true,否则返回false
//确定是否有匹配
//有: 是否背景,生成运动目标图像
// 更新所有的weight和匹配模型的mean,variance
// 对模型排序,确定新的背景模型
//没有:更新最后一个模型
int i, match = -1;
float dist, minDist = 1000000.0;
for(i=0; i<m_num; i++)
{
if(m_ptr[i]->IsValid(value, dist) && dist < minDist)
{
minDist = dist;
match = i;
}
}
if(match == -1)//没有匹配
{
dist = (float)(m_ptr[m_num-1]->m_weight - 0.1) / (m_num - 1);
m_ptr[m_num-1]->Init(value, (float)0.1);
m_ptr[m_num-1]->match=true;
m_ptr[m_num-1]->m_background=true;
m_ptr[m_num-1]->m_time=frameNUM;
for(i=0; i<m_num-1; i++)
{
m_ptr[i]->m_weight += dist;
}
return true;
}
else//有匹配
{
//更新模型参数
for(i=0; i<m_num; i++)
{
if(i == match)//匹配的模型
{
if(!m_ptr[i]->m_background)
{
if(frameNUM-m_ptr[i]->m_time==0)
{
m_ptr[i]->match=true;
m_ptr[i]->m_time=frameNUM;
}
else if(frameNUM-m_ptr[i]->m_time>TT)
{
m_ptr[i]->Update(value, minDist);
m_ptr[i]->match=true;
m_ptr[i]->m_time=0;
}
}
else
{
m_ptr[i]->Update(value, minDist);
m_ptr[i]->match=true;
m_ptr[i]->m_background=false;
m_ptr[i]->m_time=0;
}
}
else//其它模型
{
if(!m_ptr[i]->m_background)
{
if(frameNUM-m_ptr[i]->m_time>TT)
{
m_ptr[i]->Update();
}
}
else
{
m_ptr[i]->Update();
m_ptr[i]->m_background=false;
m_ptr[i]->m_time=0;
}
}
}
//模型按weight/variance排序
sGM *temp;
for(i=match; i>0; i--)
{
if(m_ptr[i]->m_weight/m_ptr[i]->m_variance > m_ptr[i-1]->m_weight/m_ptr[i-1]->m_variance)
//if(m_ptr[i]->m_weight > m_ptr[i-1]->m_weight)
{
temp = m_ptr[i];
m_ptr[i] = m_ptr[i-1];
m_ptr[i-1] = temp;
match --;//注意matc的h变化
}
else
{
break;//其它顺序肯定不变,可跳出
}
}
//确定新的背景模型
float wsum=0.0;
for(i=0; i<m_num; i++)
{
wsum += m_ptr[i]->m_weight;
// if(!m_ptr[i]->m_background)//false->true
// {
// if(frameNUM - m_ptr[i]->m_time > TT)//TH)
// {
// m_ptr[i]->m_background = true;
// m_ptr[i]->m_time &= 0;
// }
// }
// else//true->true
// {
m_ptr[i]->m_time &= 0;
m_ptr[i]->m_background = true;
/* }*/
if(wsum > T)
{
break;
}
}
for(i++; i<m_num; i++)
{
if(m_ptr[i]->m_background)//true->false
{
m_ptr[i]->m_time &= 0;
}
else//false->false
{
if(frameNUM - m_ptr[i]->m_time > TT)//TH)
{
m_ptr[i]->m_background = true;
m_ptr[i]->m_time &= 0;
}
}
}
return !m_ptr[match]->m_background;
}
}
BOOL sGMM::Process_No_Update(float *value)
{
int i, match = -1;
float dist, minDist = 1000000.0;
for(i=0; i<m_num; i++)
{
if(m_ptr[i]->IsValid(value, dist) && dist < minDist)
{
minDist = dist;
match = i;
}
}
if(match == -1)//没有匹配
{
return true;
}
else//有匹配
{
return !m_ptr[match]->m_background;
}
}
void sGMM::Init_Process(float *value)
{
int i, match = -1;
float dist, minDist = 1000000.0;
for(i=0; i<m_num; i++)
{
if(m_ptr[i]->IsValid(value, dist) && dist < minDist)
{
minDist = dist;
match = i;
}
}
if(match == -1)//没有匹配
{
m_ptr[m_num-1]->Init(value, 1.0);
return;
}
else//有匹配
{
//更新模型参数
m_ptr[match]->Init_Update(value, minDist);
//模型按weight/variance排序
sGM *temp;
for(i=match; i>0; i--)
{
if(m_ptr[i]->m_weight/m_ptr[i]->m_variance > m_ptr[i-1]->m_weight/m_ptr[i-1]->m_variance)
{
temp = m_ptr[i];
m_ptr[i] = m_ptr[i-1];
m_ptr[i-1] = temp;
}
else
{
break;//其它顺序肯定不变,可跳出
}
}
}
}
void sGMM::Norm(void)
{
int i;
float sum = 0.0;
float sum_fore=0.0;
for(i=0; i<m_num; i++)
{
sum += m_ptr[i]->m_weight;
sum_fore+=m_ptr[i]->m_wfore;
}
for(i=0; i<m_num; i++)
{
m_ptr[i]->m_weight = m_ptr[i]->m_weight / sum;
m_ptr[i]->m_wfore = m_ptr[i]->m_wfore / sum_fore;
//m_ptr[i]->m_variance = (m_ptr[i]->m_variance < 5.0 ? 5.0 : m_ptr[i]->m_variance);//限制方差的最小值
}
//确定新的背景模型
float wsum=0.0;
for(i=0; i<m_num; i++)
{
wsum += m_ptr[i]->m_weight;
m_ptr[i]->m_background = true;
if(wsum > T)
{
break;
}
}
for(i++; i<m_num; i++)
{
m_ptr[i]->m_background = false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -