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

📄 backgroundsubtraction.c

📁 for the TI dm6446 platformBackground subtraction moduleMaintain a background model, which can distin
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
* @file BackgroundSubtraction.cpp
* @author Gengyu Ma
* @brief 
* Background subtraction related functions are implemented here.
*/

#include "backgroundSubtraction.h"
#include "blobDetection_CC.h"

#include <stdlib.h>		// for malloc/ free

//////////////////////////////////////////////////////////////////////////
// parameters for shadow detection
//////////////////////////////////////////////////////////////////////////

/** edge with smaller gradient than this is not evaluated */
BYTE SHADOW_MAXGRAD  =	24;
/** sharpness bigger than this is considered as object border */
BYTE SHADOW_MAXSHARP =	36;
/** if difference is bigger than this, it can not be shadow */
BYTE SHADOW_MAXDIFF	 =  128;

/** scene type */
BYTE g_ABSSceneType = GENERAL_SCN;

//////////////////////////////////////////////////////////////////////////
// parameters for blob detection
//////////////////////////////////////////////////////////////////////////
/** minimum reported blob size */
USHORT MIN_BLOB_SIZE	=	70;
/** blobs smaller than this is considered as noise */
USHORT MAX_NOISE_SIZE	=	16;	

//////////////////////////////////////////////////////////////////////
// Global viables for saving models
//////////////////////////////////////////////////////////////////////////
/** number of pixels in one image */
INT		g_iABSPixelNum		= 0;
/** address of scene model */
INT*	g_iaABSPixels		= NULL;
/** the sorted scene model, stored by the pointer of each model */
INT**	g_lpaABSModel		= NULL;
/** the address that point to the total weight of each pixel */
USHORT*	g_iaABSTotalWeight	= NULL;

//////////////////////////////////////////////////////////////////////////
// General Image information
//////////////////////////////////////////////////////////////////////////
/** image information
 * image width, image height, and number of byte at each line */
USHORT g_iImageWidth, g_iImageHeight, g_iImageWStep;
/** index of current frame in a video */
USHORT g_iFrameNum = 0;

//////////////////////////////////////////////////////////////////////////
// parameters at pixel level
//////////////////////////////////////////////////////////////////////////

/** the learning rate for weights (0.0 -> 1.0)
 * 1/1024 = 2^-10 */
USHORT alpha = 1024;				

/** minimum portion of data accounted for by background (0.0 -> 1.0)
 *  11 / 16 */
USHORT bgT = 11;					

/** initial weight should be pretty low
 * 32 << 10 */
USHORT InitialWeight = 32;			

/** initial variance, should be rather high */
USHORT InitialVariance = 12;

/** a vector within <SigmaFactor> standard deviations of a model
 * Sigma = 15 / 8 */
INT SigmaM8 = 15;

/** after how long, the foreground is merged into background */
USHORT THEFT_DURARION = 100;

#ifdef    __cplusplus
extern "C" {
#endif

/** 
* @param input input image
* @param output output image
* @return void
* @author Gengyu Ma
*/
void smoothByMedian(BYTE* input, BYTE *output) 
{
	USHORT x,y;
	USHORT r1,r2,r3;
	USHORT w = g_iImageWidth;
	USHORT h = g_iImageHeight;
	USHORT wstep = g_iImageWStep;
	BYTE* srcadd = input;
	BYTE* dstadd = output;
	BYTE p0,p1,p2,p3,p4,p5,p6,p7,p8;
	BYTE *src0,*src1,*src2;
	BYTE *dst; 
	BYTE t;
	
	for (y=0; y<h; y++)
	{
		src0 = srcadd + wstep*(y-1);
		src1 = src0 + wstep;
		src2 = src1 + wstep;
		if (y==0) src0 = src1;
		else if (y==h-1) src2 = src1;
		dst = dstadd + wstep*y;
		for (x=0; x<w; x++)
		{
			if (src1[x]<16) 
			{
				dst[x] = src1[x];
				continue;
			}
			r1 = x==0 ? 0:x-1;
			r2 = x;
			r3 = x==w-1 ? x:x+1;
			p0 = src0[r1]; p1 = src0[r2]; p2 = src0[r3];
			p3 = src1[r1]; p4 = src1[r2]; p5 = src1[r3];
			p6 = src2[r1]; p7 = src2[r2]; p8 = src2[r3];
            MINMAXSWAP(p1, p2); MINMAXSWAP(p4, p5);
            MINMAXSWAP(p7, p8); MINMAXSWAP(p0, p1);
            MINMAXSWAP(p3, p4); MINMAXSWAP(p6, p7);
            MINMAXSWAP(p1, p2); MINMAXSWAP(p4, p5);
            MINMAXSWAP(p7, p8); MINMAXSWAP(p0, p3);
            MINMAXSWAP(p5, p8); MINMAXSWAP(p4, p7);
            MINMAXSWAP(p3, p6); MINMAXSWAP(p1, p4);
            MINMAXSWAP(p2, p5); MINMAXSWAP(p4, p7);
            MINMAXSWAP(p4, p2); MINMAXSWAP(p6, p4);
            MINMAXSWAP(p4, p2);
            dst[x] = p4;
		}
	}
}

/** 
* @param input input image
* @param output output image
* @return void
* @author Gengyu Ma
*/
void smoothByMedian_Binary(BYTE* input, BYTE *output) 
{
	LONG pi;
	BYTE v1;
	BYTE *src0,*src1,*src2;
	BYTE *dst; 

	memset(output, 0, g_iABSPixelNum);
	
	src0 = input; 
	src1 = src0 + g_iImageWStep; 
	src2 = src1 + g_iImageWStep;
	dst = output + g_iImageWStep;
	for (pi=g_iImageWStep; pi<g_iABSPixelNum-g_iImageWStep; pi++)
	{
		if (src1[0]!=BACKGROUND)
		{
			v1 = 0;
			if (src0[-1]) ++ v1;
			if (src0[0])  ++ v1;
			if (src0[1])  ++ v1;
			if (src1[-1]) ++ v1;
			if (src1[0])  ++ v1;
			if (src1[1])  ++ v1;
			if (src2[-1]) ++ v1;
			if (src2[0])  ++ v1;
			if (src2[1])  ++ v1;
			if (v1>=6) *dst = *src1;
		}
		++ src0; ++ src1; ++ src2;
		++ dst;
	}
}

/** 
* @param input input image
* @param output output image
* @return void
* @author Gengyu Ma
*/
void smoothUp(BYTE* input, BYTE *output) 
{
	USHORT x,y;
	USHORT w = g_iImageWidth;
	USHORT h = g_iImageHeight;
	USHORT wstep = g_iImageWStep;
	BYTE* srcadd = input;
	BYTE* dstadd = output;
	USHORT sum = 0;
	BYTE *src0,*src1,*src2;
	BYTE *dst; 
	USHORT r1,r2,r3;
	
	for (y=0; y<h; y++)
	{
		src0 = srcadd + wstep*(y-1);
		src1 = src0 + wstep;
		src2 = src1 + wstep;
		if (y==0) src0 = src1;
		else if (y==h-1) src2 = src1;
		dst = dstadd + wstep*y;
		for (x=0; x<w; x++)
		{
			if (src1[x]>150) 
			{
				dst[x] = src1[x];
				continue;
			}
			r1 = x==0 ? 0:x-1;
			r2 = x;
			r3 = x==w-1 ? x:x+1;
			sum = src0[r1]; sum += src0[r2]; sum += src0[r3];
			sum += src1[r1]; sum += src1[r2]; sum += src1[r3];
			sum += src2[r1]; sum += src2[r2]; sum += src2[r3];
            dst[x] = (BYTE)((sum+5)/9);
		}
	}
}

/** 
* @param input input image
* @param output output image
* @return void
* @author Gengyu Ma
*/
void smoothDown(BYTE* input, BYTE *output) 
{
	USHORT x,y;
	USHORT w = g_iImageWidth;
	USHORT h = g_iImageHeight;
	USHORT wstep = g_iImageWStep;
	USHORT sum = 0;
	BYTE* srcadd = input;
	BYTE* dstadd = output;
	BYTE *src0,*src1,*src2;
	BYTE *dst;
	USHORT r1,r2,r3;
	
	for (y=0; y<h; y++)
	{
		src0 = srcadd + wstep*(y-1);
		src1 = src0 + wstep;
		src2 = src1 + wstep;
		if (y==0) src0 = src1;
		else if (y==h-1) src2 = src1;
		dst = dstadd + wstep*y;
		for (x=0; x<w; x++)
		{
			if (src1[x]<16) 
			{
				dst[x] = src1[x];
				continue;
			}
			r1 = x==0 ? 0:x-1;
			r2 = x;
			r3 = x==w-1 ? x:x+1;
			sum = src0[r1]; sum += src0[r2]; sum += src0[r3];
			sum += src1[r1]; sum += src1[r2]; sum += src1[r3];
			sum += src2[r1]; sum += src2[r2]; sum += src2[r3];
            dst[x] = (BYTE)((sum+5)/9);
		}
	}
}


/** Allocate memory for ABS
* @param w width of input image
* @param h height of input image
* @return void
* @author Gengyu Ma
*/
void ABS_Create(USHORT w, USHORT h)
{
	INT p;

	g_iImageHeight = h;
	g_iImageWidth = w;
	g_iImageWStep = (w-1)/4 * 4 + 4;

	ABS_Release();

	g_iABSPixelNum = w * h;
	g_iaABSPixels = (INT*)malloc(g_iABSPixelNum*K_MODELS*PMSIZE*4);
	g_lpaABSModel = (INT**)malloc(g_iABSPixelNum*K_MODELS*4);
	g_iaABSTotalWeight = (USHORT*)malloc(g_iABSPixelNum*sizeof(USHORT));
	for (p=0; p<g_iABSPixelNum*K_MODELS; p++)
		g_lpaABSModel[p] = g_iaABSPixels + p*PMSIZE;

	// set parameters
	ABS_SetParameters(SCENE_DEFAULT, 0);
}

/** Set system parameters according to scene type
* @param para scene parameter
* @param value the value of specified parameter
* @return void
* @author Gengyu Ma
*/
void ABS_SetParameters(Scene_Parameter para, INT value)
{
	// when scene was set to different type, the duration is reduced.
	// thus can smooth the change of scene type
	static INT duration_dark = 16;
	static INT duration_near = 16;
	INT oldvalue;
	
	switch(para) {
	case SCENE_BRIGHT_OR_DARK: 
		oldvalue = (g_ABSSceneType & 1) > 0;
		if (value==oldvalue) { duration_dark = 16; return; }
		else if (duration_dark-- > 0) return;
		g_ABSSceneType = g_ABSSceneType ^ 1;
		duration_dark = 16;
		break;
	case SCENE_FAR_OR_NEAR: 
		oldvalue = (g_ABSSceneType & 2) > 0;
		if (value==oldvalue) { duration_near = 16; return; }
		else if (duration_near-- > 0) return;
		g_ABSSceneType = g_ABSSceneType ^ 2;
		duration_near = 16;
		break;
	case SCENE_BLOB_SIZE:
		if (value>400 && MIN_BLOB_SIZE<90) 
			MIN_BLOB_SIZE++;
		else if (value<32 && MIN_BLOB_SIZE>60) 
			MIN_BLOB_SIZE-=2;
		return;
	case SCENE_DEFAULT:
		g_ABSSceneType = GENERAL_SCN;
	}

	if (g_ABSSceneType==GENERAL_SCN)
	{
		SHADOW_MAXDIFF = 128;
		SHADOW_MAXGRAD = 16;
		SHADOW_MAXSHARP= 32;
		SigmaM8 = 18;
	}
	if (g_ABSSceneType & CLOSE_SCN)
	{
		SHADOW_MAXDIFF = 136;
		SHADOW_MAXGRAD = 20;
		SHADOW_MAXSHARP= 36;
		SigmaM8 = 20;
	}
	if (g_ABSSceneType & DARK_SCN)
	{
		SHADOW_MAXDIFF = 8;
		SHADOW_MAXGRAD = 12;
		SHADOW_MAXSHARP= 4;
		SigmaM8 = 12;
	}
}

/** Set system parameters according to scene type
* @param void
* @return void
* @author Gengyu Ma
*/
void ABS_Release()
{
	if (g_iaABSPixels) free(g_iaABSPixels);
	g_iaABSPixels = NULL;
	if (g_lpaABSModel) free(g_lpaABSModel);
	g_lpaABSModel = NULL;
	if (g_iaABSTotalWeight) free(g_iaABSTotalWeight);
	g_iaABSTotalWeight = NULL;
}

/** 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
*/
void ABS_BackgroundModeling(BYTE *lpimg, BYTE updatefactor)
{
	BYTE *p = lpimg;
	INT **pmd = g_lpaABSModel;
	USHORT *ptw = g_iaABSTotalWeight;

	INT i;
	for (i=0; i<g_iABSPixelNum; i++)
	{
		Pixel_ModelUpdate(*p, pmd, ptw, updatefactor);

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


/** Evaluate the gradient at every pixel in the background model
* @param edgeimg The gradient of each pixel in the background model
* @return void
* @author Gengyu Ma
*/
void ABS_SceneAnalyze(BYTE* edgeimg)
{
	USHORT x,y;
	BYTE* edgeadd;
	INT** pmd, **pmdadj;
	USHORT v1,v2, grad, ming, maxg;

⌨️ 快捷键说明

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