⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sgmm.cpp

📁 动态场景中运动目标检测提取与跟踪 对新手很有用
💻 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 + -