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

📄 backgroundsubtraction.c

📁 for the TI dm6446 platformBackground subtraction moduleMaintain a background model, which can distin
💻 C
📖 第 1 页 / 共 3 页
字号:
	LONG avgval = 0;

	memset(edgeimg, 1, g_iABSPixelNum);
	
	for (y=1; y<g_iImageHeight-1; y++)
	{
		edgeadd = edgeimg + g_iImageWStep*y;
		pmd = g_lpaABSModel + g_iImageWidth*K_MODELS*y;
		for (x=1; x<g_iImageWidth-1; x++)
		{
			v1 = pmd[0][0];
			avgval += v1;
			// left
			pmdadj = pmd-K_MODELS;
			v2 = pmdadj[0][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = grad;
			v2 = pmdadj[1][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = EMA_MIN(grad, ming);
			maxg = ming;

			// right
			pmdadj = pmd + K_MODELS;
			v2 = pmdadj[0][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = grad;
			v2 = pmdadj[1][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = EMA_MIN(grad, ming);
			maxg = EMA_MAX(maxg, ming);

			// top
			pmdadj = pmd - K_MODELS*g_iImageWidth;
			v2 = pmdadj[0][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = grad;
			v2 = pmdadj[1][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = EMA_MIN(grad, ming);
			maxg = EMA_MAX(maxg, ming);

			//bottom
			pmdadj = pmd - K_MODELS*g_iImageWidth;
			v2 = pmdadj[0][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = grad;
			v2 = pmdadj[1][0];
			grad = (v1>v2)? v1-v2 : v2-v1;
			ming = EMA_MIN(grad, ming);
			maxg = EMA_MAX(maxg, ming);

			*edgeadd = ((maxg+48)>>7)+1;

			edgeadd ++;
			pmd += K_MODELS;
		}
	}

	avgval /= (g_iImageWidth-2)*(g_iImageHeight-2);
	if (avgval<THR_DARK)
		ABS_SetParameters(SCENE_BRIGHT_OR_DARK, 1);
	else 
		ABS_SetParameters(SCENE_BRIGHT_OR_DARK, 0);
}

/** Compare new image with background model
* @param lpimg a new frame in the sequence
* @param lpdiff  the difference between current input and saved model.
* @param lplabel  an image stores the type of each pixel. FG,BG,THEFT,SHADOW,etc
* @return void
* @author Gengyu Ma
*/
void ABS_ExtractForeground(BYTE *lpimg, BYTE* lplabel, BYTE* lpdiff, INT updatefactor)
{
	//ptrs
	BYTE *p = lpimg;
	INT **pmd = g_lpaABSModel;			// poINTer to the model of one pixel
	USHORT *ptw = g_iaABSTotalWeight;		// poINTer to the total weight of one pixel
	BYTE *pdiff = lpdiff;				// poINTer to the difference of one pixel
	BYTE *fg = lplabel;

	BYTE lastp;
	SHORT x,y;

	static BYTE ti;
	ti = (ti+1)%2;

	for (y=0; y<g_iImageHeight; y++)
	{
		if (y%2==ti)	// 0 2 4 6 8
		{
			lastp = 1;
			
			for (x=0; x<=g_iImageWidth-2; x+=2)
			{
				*fg = Pixel_Compare_Update(*p, pmd, ptw, updatefactor, pdiff, 1);
				if (*fg!=BACKGROUND)
				{
					if (lastp==0)
						*(fg-1) = Pixel_Compare_Update(*(p-1), pmd-K_MODELS, (ptw-1), updatefactor, pdiff-1, 1);
					*(fg+1) = Pixel_Compare_Update(*(p+1), pmd+K_MODELS, (ptw+1), updatefactor, pdiff+1, 1);
					lastp = 1;
				}
				else
				{
					*(fg+1) = BACKGROUND;
					*(pdiff+1) = *pdiff;
					lastp = 0;
				}
				p += 2;
				pdiff += 2;
				fg += 2;
				
				pmd += K_MODELS<<1;
				ptw += 2;
			}
		}
		else			// 1 3 5 7 9
		{
			lastp = 0;

			p ++;
			pmd += K_MODELS;
			ptw ++;
			*pdiff = 0; pdiff ++;
			*fg = 0; fg ++;
			lastp = 0;
			
			for (x=1; x<=g_iImageWidth-3; x+=2)
			{
				*fg = Pixel_Compare_Update(*p, pmd, ptw, updatefactor, pdiff, 1);
				if (*fg!=BACKGROUND)
				{
					if (lastp==0)
						*(fg-1) = Pixel_Compare_Update(*(p-1), pmd-K_MODELS, (ptw-1), updatefactor, pdiff-1, 1);
					*(fg+1) = Pixel_Compare_Update(*(p+1), pmd+K_MODELS, (ptw+1), updatefactor, pdiff+1, 1);
					lastp = 1;
				}
				else
				{
					*(fg+1) = BACKGROUND;
					*(pdiff+1) = *pdiff;
					lastp = 0;
				}
				p += 2;
				pdiff += 2;
				fg += 2;
				
				pmd += K_MODELS<<1;
				ptw += 2;
			}
			*fg = Pixel_Compare_Update(*p, pmd, ptw, updatefactor, pdiff, 1);
			if (*fg!=BACKGROUND)
			{
				if (lastp==0)
					*(fg-1) = Pixel_Compare_Update(*(p-1), pmd-K_MODELS, (ptw-1), updatefactor, pdiff-1, 1);
			}
			p ++;
			pdiff ++;
			fg ++;
			
			pmd += K_MODELS;
			ptw ++;
		}
	}
}

/** Compute the sharpness of the difference image. Result will be used in shadow removal
* @param lpdiff the difference between current input and saved model.
* @param lpsharpness  the sharpness of the difference image
* @return void
* @author Gengyu Ma
*/
void ABS_Sharpness(BYTE* lpdiff, BYTE* lpsharpness)
{
	USHORT w = g_iImageWidth;
	USHORT h = g_iImageHeight;

	BYTE* diffaddr = lpdiff + w + w + w;
	BYTE* sharpaddr = lpsharpness + w + w + w;

	USHORT y,x;
	USHORT v1, v2, v3, v4, v5;			// 5 positions to calculate sharpness
	USHORT lg1, lg2, lg3, lg;			// 3 candidate large gradients and the final value
	USHORT sg1, sg2, sg3, sg;			// large gradient and small gradient
	INT hsharp, vsharp, sharp;

	memset(lpsharpness, 0, g_iImageWStep*g_iImageHeight);

	for (y=3; y<=h-4; y++)
	{
		for (x=3; x<=w-4; x++)
		{
			// verify if the difference is big
			if (diffaddr[x]<24) continue;
			if (diffaddr[x]>SHADOW_MAXDIFF)
			{
				sharpaddr[x] = 255;
				continue;
			}

			vsharp = hsharp = 0;
			// vertical
			v1 = (UINT)diffaddr[x-w-w-w-1] + (UINT)diffaddr[x-w-w-w] + (UINT)diffaddr[x-w-w-w+1];
			v2 = (UINT)diffaddr[x-w-1] + (UINT)diffaddr[x-w] + (UINT)diffaddr[x-w+1];
			v3 = (UINT)diffaddr[x-1] + (UINT)diffaddr[x] + (UINT)diffaddr[x+1];
			v4 = (UINT)diffaddr[x+w-1] + (UINT)diffaddr[x+w] + (UINT)diffaddr[x+w+1];
			v5 = (UINT)diffaddr[x+w+w+w-1] + (UINT)diffaddr[x+w+w+w] + (UINT)diffaddr[x+w+w+w+1];
			lg1 = abs(v3-v1); lg2 = abs(v5-v3); lg3 = abs(v5-v1);
			lg = EMA_MAX(lg1, lg2); lg = EMA_MAX(lg, lg3);
			sg1 = abs(v3-v2); sg2 = abs(v4-v3); sg3 = abs(v4-v2);
			sg = EMA_MAX(sg1, sg2); sg = EMA_MIN(sg, sg3);
			if (sg>SHADOW_MAXGRAD<<3)
				{ vsharp = 255; continue; }
			else if (lg>=sg && sg>SHADOW_MAXGRAD)
				vsharp = (sg<<4) / ((lg+16)>>3);
			// horizontal
			v1 = (UINT)diffaddr[x-w-3] + (UINT)diffaddr[x-3] + (UINT)diffaddr[x+w-3];
			v2 = (UINT)diffaddr[x-w-1] + (UINT)diffaddr[x-1] + (UINT)diffaddr[x+w-1];
			v3 = (UINT)diffaddr[x-w] + (UINT)diffaddr[x] + (UINT)diffaddr[x+w];
			v4 = (UINT)diffaddr[x-w+1] + (UINT)diffaddr[x+1] + (UINT)diffaddr[x+w+1];
			v5 = (UINT)diffaddr[x-w+3] + (UINT)diffaddr[x+3] + (UINT)diffaddr[x+w+3];
			lg1 = abs(v3-v1); lg2 = abs(v5-v3); lg3 = abs(v5-v1);
			lg = EMA_MAX(lg1, lg2); lg = EMA_MAX(lg, lg3); 
			sg1 = abs(v3-v2); sg2 = abs(v4-v3); sg3 = abs(v4-v2);
			sg = EMA_MAX(sg1, sg2); sg = EMA_MIN(sg, sg3);
			if (sg>SHADOW_MAXGRAD<<3)
				{ hsharp = 255; continue; }
			if (lg>=sg && sg>SHADOW_MAXGRAD)
				hsharp = (sg<<4) / ((lg+16)>>3);

			sharp = vsharp + hsharp;
			sharp = EMA_MIN(sharp, 255);
			sharpaddr[x] = (BYTE)sharp;
		}
		diffaddr += w;
		sharpaddr += w;
	}
}

/** When potential camera shift occured, call this function to verify each FG pixel in this verification, the threshold used to classify pixel types depends on the background gradient
* @param lpimg a new frame in the sequence
* @param lplabel only FG pixels are processed
* @param lpgrad using background gradeint to set the threshold for model comparison
* @param lpdiff  the difference between current input and saved model.
* @param lplabel  updated label image
* @return void
* @author Gengyu Ma
*/
void ABS_ExtractWithMask(BYTE *lpimg, BYTE* lplabel, BYTE* lpgrad)
{
	//ptrs
	BYTE *p = lpimg;
	INT **pmd = g_lpaABSModel;			// pointer to the model of one pixel
	USHORT *ptw = g_iaABSTotalWeight;	// pointer to the total weight of one pixel
	BYTE *grad = lpgrad;				// gradient in the background model
	BYTE *fg = lplabel;

	INT i;

	for (i=0; i<g_iABSPixelNum; i++)
	{
		if (*grad>1 && (*fg==FOREPIXEL||*fg==THEFTPIXEL))
			*fg = Pixel_Compare(*p, pmd, ptw, *grad);

		p ++;
		fg ++;
		grad ++;
		
		pmd += K_MODELS;
		ptw ++;
	}
}

/** Get model information for visualization
* @param sort the nth gaussian model to be loaded
* @param lpbgimg  the center of the nth model
* @param lpweightimg  the weight of the nth model
* @return void
* @author Gengyu Ma
*/
void ABS_GetBackGround(INT sort, BYTE *lpbgimg, BYTE* lpweightimg)
{
	INT pi;

	BYTE* iaddr = lpbgimg;
	BYTE* waddr = lpweightimg;

	for (pi=0; pi<g_iABSPixelNum; pi++)
	{
		if (lpweightimg)
		{
			waddr[0] = (BYTE)((float)g_lpaABSModel[pi*K_MODELS+sort][2]*255 / g_iaABSTotalWeight[pi]);
			waddr ++;
		}
		if (lpbgimg)
		{
			iaddr[0] = (BYTE)(g_lpaABSModel[pi*K_MODELS+sort][0] >> 4);
			iaddr ++;
		}
	}
}

/** Set some of the FG pixels to SHADOW, according to difference image and sharpness image
* @param lplabel the address of label data, store each pixel's type
* @param lpdiff the difference between current input and saved model.
* @param lpsharp	the address of label data, store each pixel's type
* @param lplabel  Some pixels are SHADOW after the procedure
* @return void
* @author Gengyu Ma
*/
void ABS_RemoveShadow(BYTE* lplabel, BYTE* lpdiff, BYTE* lpsharp)
{
	USHORT x, y, xs, xe, y2;

	// horizontal scan
	BYTE* labeladdr = lplabel + g_iImageWidth*3;
	BYTE* diffaddr = lpdiff + g_iImageWidth*3;
	BYTE* sharpaddr = lpsharp + g_iImageWidth*3;
	BYTE* sharpaddr2, *labeladdr2, *diffaddr2;

	for (y=3; y<g_iImageHeight-3; y++)
	{
		for (x=3; x<g_iImageWidth-3; x++)
		{
			if (labeladdr[x]==BACKGROUND)
			{
				// forward scan
				xe = x+1;
				while (xe<g_iImageWidth-1 && labeladdr[xe]==BACKGROUND) xe++;
				if (xe-x<32 && x>3 && xe<g_iImageWidth-3)	// too short background is not considered
					goto gap_end_h;
				while (xe<g_iImageWidth-1 && sharpaddr[xe]<SHADOW_MAXSHARP+4)
				{
					if (labeladdr[xe]==FOREPIXEL)
						labeladdr[xe] = SHADOW;
					xe ++;
				}

				// backward scan
				xs = x-1;
				while (xs>0 && sharpaddr[xs]<SHADOW_MAXSHARP+4 && labeladdr[xs]==FOREPIXEL)
				{
					labeladdr[xs] = SHADOW;
					xs--;
				}
gap_end_h:
				x = xe;
			}
		}
		labeladdr += g_iImageWidth;
		diffaddr += g_iImageWidth;
		sharpaddr += g_iImageWidth;
	}

	// vertical scan
	for (x=3; x<g_iImageWidth-3; x++)
	{
		labeladdr = lplabel + g_iImageWidth*3 + x;
		sharpaddr = lpsharp + g_iImageWidth*3 + x;
		diffaddr = lpdiff + g_iImageWidth*3 + x;
		for (y=3; y<g_iImageHeight-3; y++)
		{
			if (*labeladdr==BACKGROUND)
			{
				// forward scan
				sharpaddr2 = sharpaddr + g_iImageWidth;
				labeladdr2 = labeladdr + g_iImageWidth;
				diffaddr2 = diffaddr + g_iImageWidth;
				for (y2=y+1; y2<g_iImageHeight-1; y2++)
				{
					if (*labeladdr2==BACKGROUND) 
					{
						labeladdr2 += g_iImageWidth;
						sharpaddr2 += g_iImageWidth;
						diffaddr2 += g_iImageWidth;
						continue;
					}
					if (y>3 && y2-y<32) 
						goto gap_end_v;
					if (*sharpaddr2<SHADOW_MAXSHARP)
						*labeladdr2 = SHADOW;
					else
						break;
					sharpaddr2 += g_iImageWidth;
					labeladdr2 += g_iImageWidth;
					diffaddr2 += g_iImageWidth;
				}
gap_end_v:
				y = y2;
				labeladdr = labeladdr2;
				sharpaddr = sharpaddr2;
				diffaddr = diffaddr2;
			}
			else
			{
				labeladdr += g_iImageWidth;
				sharpaddr += g_iImageWidth;
				diffaddr += g_iImageWidth;
			}
		}
	}
}

/** Update the background model from an image
* @param lpimg the address of image data buffer
* @param updatefactor control the speed of update, bigger value means faster speed
* @return void
* @author Gengyu Ma
*/

⌨️ 快捷键说明

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