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

📄 backgroundsubtraction.c

📁 for the TI dm6446 platformBackground subtraction moduleMaintain a background model, which can distin
💻 C
📖 第 1 页 / 共 3 页
字号:
void ABS_InitBackGround(BYTE *lpBack)
{
	BYTE *p = lpBack;
	INT** pmd = g_lpaABSModel;
	USHORT *ptw = g_iaABSTotalWeight;

	INT i;

	for(i=0; i<g_iABSPixelNum; i++)
	{
		Pixel_InitModel(*(p), pmd, ptw);
		p ++;
		pmd += K_MODELS;
		ptw ++;
	}
}

/** Estimate the constancy of the scene, how long has a pixel been the same color.
* @param previmg pointer to the buffer of previous frame
* @param curimg pointer to the buffer of current frame
* @param constimg  the period that each pixel is not changed
* @return void
* @author Gengyu Ma
*/
// modified to use difference image
void ABS_ComputeConstancy(signed char* diffimg, BYTE* constimg)
{
	BYTE* consadd = constimg;
	int diff;
	
	INT i;
	for (i=0; i<g_iABSPixelNum; i++)
	{
		diff = EMA_ABS(*(diffimg++));
		if (diff<24) 
		{
			if (*consadd<200) (*consadd)++;
		}
		else
			*consadd = 0;
		consadd ++;
	}
}
/* old code
void ABS_ComputeConstancy(BYTE* previmg, BYTE* curimg, BYTE* constimg)
{
	BYTE* prevadd = previmg;
	BYTE* curadd = curimg;
	BYTE* consadd = constimg;
	BYTE diff;

	INT i;
	for (i=0; i<g_iABSPixelNum; i++)
	{
		diff = (*prevadd>*curadd)? *prevadd-*curadd : *curadd-*prevadd;
		if (diff<24) 
		{
			if (*consadd<200) (*consadd)++;
		}
		else
			*consadd = 0;
		
		prevadd ++;
		curadd ++;
		consadd ++;
	}
}
*/


/** Verify Theft pixels by using the constancy image
* @param labelimg the address of label data, store each pixel's type
* @param constimg the period that each pixel has been still
* @param labelimg  some theft pixels are changed to FG
* @return void
* @author Gengyu Ma
*/
void ABS_VerifyTheftByConstancy(BYTE* labelimg, BYTE* constimg)
{
	BYTE* labadd = labelimg;
	BYTE* consadd = constimg;

	INT i;

	for (i=0; i<g_iABSPixelNum; i++)
	{
		if ((*labadd)==THEFTPIXEL && (*consadd)<64)
			(*labadd) = BACKGROUND;
		labadd ++;
		consadd ++;
	}
}

/** only update model, without comparison
* @param g pixel color
* @param lpmodel MoG model
* @param totalweight sum up weight of each model
* @param updatefactor how fast the model is updated
* @param lpmodel  MoG model
* @author Gengyu Ma
*/
void Pixel_ModelUpdate(BYTE g, INT** lpmodel, USHORT* totalweight, INT updatefactor)
{
	BYTE i, match;
	INT dist2, v, pixel;
	INT* pmMatch;
	
	pixel = g;
	pixel = pixel << 4;

	// see if the current pixel matches any of the models
	for (match=0; match<K_MODELS; match++)
	{
		// calculate the vector, v = (X - u)
		v = pixel - lpmodel[match][0];

		// calculate the squared distance, d = |v|^2
		dist2 = abs(v);

		// see if X is close enough to this model
		if ((dist2<<3) < SigmaM8 * lpmodel[match][1]) break;
	}

	if (match<K_MODELS)
	{
		// we matched an existing model
		pmMatch = lpmodel[match];
		if (pmMatch[3]<1024) pmMatch[3] += updatefactor;

		// now we need to update the models
		// update the weights (we normalize later)
		pmMatch[2] += updatefactor;
		(*totalweight) += updatefactor;
		if ( (*totalweight) > 2048 )
		{
			(*totalweight) = 0;
			for (i=0; i<K_MODELS; i++)
			{
				lpmodel[i][2] = lpmodel[i][2] >> 1;
				(*totalweight) += lpmodel[i][2];
			}
		}

		// update the parameters for the matched model
		// first we update the mean
		pmMatch[0] = ((pmMatch[0]<<10) - pmMatch[0] + pixel + 512) >> 10;

		// and then we update the variance
		if ( !( pmMatch[1]<=128 && dist2<pmMatch[1] ) 
			&& !( pmMatch[1]>=2048 && dist2>pmMatch[1]) )
		{
			pmMatch[1] = ((pmMatch[1]<<10) - (pmMatch[1]<<3) + (dist2<<3) + 512) >> 10;
		}

		// re-sort the models, only update necessary one
		Pixel_UpdateSortByKey(lpmodel, match);
	}
	else
	{
		// we didn't match anything
		pmMatch = lpmodel[K_MODELS-1];    

		// replace least probable model with the current data
		(*totalweight) = (*totalweight) - pmMatch[2] + InitialWeight;
		pmMatch[2] = InitialWeight;
		pmMatch[0] = pixel;
		pmMatch[1] = InitialVariance << 4;
	}
}

/** Compare new pixel with background model and update the model
* @param g pixel color
* @param lpmodel MoG model
* @param totalweight sum up weight of each model
* @param updatefactor how fast the model is updated
* @param senstivity control the sensitivity by adjusting the matching range
* @param lpdiff  save the difference to the Pixel_Diffs
* @param lpmodel  MoG model
* @return pixel type
* @author Gengyu Ma
*/
INT Pixel_Compare_Update(BYTE g, INT** lpmodel, USHORT* totalweight, INT updatefactor, BYTE* lpdiff, BYTE senstivity)
{
	BYTE i, match;
	BYTE cat;
	USHORT bgThr, weightSum;
	INT pixel, dist2, realdist;
	INT* pmMatch;

	pixel = g; pixel = pixel << 4;

	// find which models account for the bg by summing the
	//  model's weights until we exceed <bgThr>
	weightSum = 0;
	bgThr = ((*totalweight) * bgT) >> 4;
	// the leading a fews are both theft and background
	i=0;
	for (i=0; i<3; i++)
	{
		weightSum += lpmodel[i][2];
		if (lpmodel[i][3]<1024) lpmodel[i][3] += updatefactor;
		if (weightSum > bgThr) break;
	}
	// the middle severals are background, but not theft
	// the other models are foreground
	for (i++; i<K_MODELS; i++)
		lpmodel[i][3] = 0;

	(*lpdiff) = 255;		// min difference to background model

	// see if the current pixel matches any of the models
	for(match=0; match<K_MODELS; match++)
	{
		// calculate the vector, v = (X - u)
		// calculate the squared distance, d = |v|^2
		dist2 = EMA_DIFF(pixel, lpmodel[match][0]);

		// find min dist
		realdist = (dist2>>3);
		realdist = EMA_MIN(255, realdist);
		if ((*lpdiff)>realdist && lpmodel[match][3]>THEFT_DURARION) 
			*lpdiff = (BYTE)realdist;

		// see if X is close enough to this model
		if ( (dist2<<3) < lpmodel[match][1]*senstivity*SigmaM8 )
			break;
	}

	if (match<K_MODELS)
	{
		// we matched an existing model
		pmMatch = lpmodel[match];

		// determine if the matched model is part of the bg or fg
		if (pmMatch[3]==0) 
			cat = FOREPIXEL;						// foreground
		else if (pmMatch[3]<THEFT_DURARION) 
			cat = THEFTPIXEL;						// background
		else 
			cat = BACKGROUND;						// theft

		// now that we've classified, we need to update the models
		// update the weights (we normalize later)
		pmMatch[2] += updatefactor;
		(*totalweight) += updatefactor;
		if ( (*totalweight) > 2048 )
		{
			(*totalweight) = 0;
			for (i=0; i<K_MODELS; i++)
			{
				lpmodel[i][2] = lpmodel[i][2] >> 1;
				(*totalweight) += lpmodel[i][2];
			}
		}

		// update the parameters for the matched model
		// first we update the mean
		pmMatch[0] = ((pmMatch[0]<<7) - pmMatch[0] + pixel + 64) >> 7;

		// and then we update the variance
		if ( !( pmMatch[1]<=128 && dist2<pmMatch[1] ) 
			&& !( pmMatch[1]>=2048 && dist2>pmMatch[1]) )
		{
			pmMatch[1] = ((pmMatch[1]<<7) - (pmMatch[1]) + (dist2) + 64) >> 7;
		}

		// re-sort the models, only update necessary one
		Pixel_UpdateSortByKey(lpmodel, match);
	}
	else
	{
		// we didn't match anything
		pmMatch = lpmodel[K_MODELS-1];

		// replace least probable model with the current data
		(*totalweight) = (*totalweight) - pmMatch[2] + InitialWeight;
		pmMatch[0] = pixel;
		pmMatch[1] = InitialVariance << 4;
		pmMatch[2] = InitialWeight;
		pmMatch[3] = 0;

		// we assume the 'new' model is foreground
		cat = FOREPIXEL;
	}   

	return cat;
}

/** Compare new pixel with background model and update the model
* @param g pixel color
* @param lpmodel MoG model
* @param totalweight sum up weight of each model
* @param updatefactor how fast the model is updated
* @param senstivity control the sensitivity by adjusting the matching range
* @param lpdiff  save the difference to the Pixel_Diffs
* @param lpmodel  MoG model
* @return pixel type
* @author Gengyu Ma
*/
INT Pixel_Compare(BYTE g, INT** lpmodel, USHORT* totalweight, BYTE senstivity)
{
	BYTE i, match;
	BYTE cat;
	USHORT bgThr, weightSum;
	INT pixel, dist2;
	INT* pmMatch;

	pixel = g; pixel = pixel << 4;

	// find which models account for the bg by summing the
	//  model's weights until we exceed <bgThr>
	weightSum = 0;
	bgThr = ((*totalweight) * bgT) >> 4;
	// the leading a fews are both theft and background
	i=0;
	for (i=0; i<3; i++)
	{
		weightSum += lpmodel[i][2];
		if (weightSum > bgThr) break;
	}

	// see if the current pixel matches any of the models
	for(match=0; match<K_MODELS; match++)
	{
		// calculate the vector, v = (X - u)
		// calculate the squared distance, d = |v|^2
		dist2 = EMA_DIFF(pixel, lpmodel[match][0]);

		// see if X is close enough to this model
		if ( (dist2<<3) < lpmodel[match][1]*senstivity*SigmaM8 )
			break;
	}

	if (match<K_MODELS)
	{
		// we matched an existing model
		pmMatch = lpmodel[match];

		// determine if the matched model is part of the bg or fg
		if (pmMatch[3]==0) 
			cat = FOREPIXEL;						// foreground
		else if (pmMatch[3]<THEFT_DURARION) 
			cat = THEFTPIXEL;						// background
		else 
			cat = BACKGROUND;						// theft
	}
	else
		cat = FOREPIXEL;

	return cat;
}

/** Sort the gaussians in a pixel by order
* @param lpmodel MoG model
* @param mi the gaussian whose weight is changed
* @param lpmodel  MoG model
* @return void
* @author Gengyu Ma
*/
void Pixel_UpdateSortByKey(INT** lpmodel, BYTE mi)
{
	CHAR i;
	INT mikey, key;
	INT *pm = lpmodel[mi];

	mikey = (lpmodel[mi][2]<<4);// / (lpmodel[mi][1]>>4);

	for (i=mi-1; i>=0; i--)
	{
		key = (lpmodel[i][2]<<4);// / (lpmodel[i][1]>>4);
		if (key<mikey)
			lpmodel[i+1] = lpmodel[i];
		else break;
	}
	lpmodel[i+1] = pm;
}

/** Initialize pixel color model
* @param g pixel color
* @param lpmodel MoG model
* @param totalweight sum up weight of each model
* @param lpmodel  MoG model
* @author Gengyu Ma
*/
void Pixel_InitModel(BYTE g, INT** lpmodel, USHORT* totalweight)
{
	BYTE i;

	// init model 0
	lpmodel[0][0] = ((USHORT)g) << 4;			// average	
	lpmodel[0][1] = InitialVariance << 4;		// var
	lpmodel[0][2] = 1024 - K_MODELS*32;			// weight
	lpmodel[0][3] = 1024;						// duration

	// init other models
	for (i=1; i<K_MODELS; i++)
	{
		lpmodel[i][0] = 0x7FFFFF;
		lpmodel[i][1] =  InitialVariance << 4;
		lpmodel[i][2] = 32;
		lpmodel[i][3] = 0;
	}
	(*totalweight) = 1024;
}


#ifdef    __cplusplus
}   // extern "C" {
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -