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

📄 msfeature.c

📁 学习跟踪的好程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////// 
// File:	Msfeature.c
// Desc:	Log(obj/bg) Feature MeanShift Tracker
// Author:	Xuhui Zhou  @ Carnegie Mellon University
// Date:	8/31/2003
///////////////////////////////////////////////////////////////////////////////
#include "Msfeature.h"
#include <search.h>

#define FEATNUM 49				//overall feature number
#define BINNUM  32				//histogram bin number

//global variable for initialization
int		gFeatlist[FEATNUM][5];		//store feature combination list
char	gFeatlabels[FEATNUM][10];	//string label of the feature list
double  gPobjFirst[FEATNUM][BINNUM];//Obj histogram on first frame
double  gMaxFeatRatio[3][BINNUM];	//selected 3 most ratio features
double	gMaxFeatScore[3];			//scores for max ratio features
int		gMaxFeatIdx[3];				//index for max ratio features
int		gSelectFreq=10;

//global vars for tracking
float	gBoxRatio = 1.0;			//ratio between forground and background bounding box	
int		gFrameCount=0;
int		gNumOfFeat=3;		//feat number used in tracking
int		gPeakDiff;			//peak difference

IplImage	*gRatioImg;			//logratio image for meanshift purpose
IplImage	*gWeightImg;			//weight image in meanshift process	
IplImage	*gImgFgMask;
IplImage	*gImgObjMask;

float	gMaskFgRatio;

int compare( const void *arg1, const void *arg2 ); //function used for qsort
///////////////////////////////////////////////////////////////////////////////
void feat_TrackInit(IplImage* imgInput, IplImage* imgObjMask, RECT inTargetBox)
//init tracker
{	
	RECT	bgBox;
	int		row,col;
	CvScalar pixel;
	int		boxHalfWid, boxHalfHgt;	
	int		dmax;	
	int		i,j;
	double  feat;
	int		featbin;
	long	histObj[FEATNUM][BINNUM], histBg[FEATNUM][BINNUM];
	double  Pobj[FEATNUM][BINNUM], Pbg[FEATNUM][BINNUM], Ptotal[FEATNUM][BINNUM];
	double  logRatio[FEATNUM][BINNUM]; 
	long	countObj, countBg;
	float	boxRatio = gBoxRatio;			//ratio between forground and background bounding box	

	//cvSaveImage("img0001.bmp", imgInput);	
	gFrameCount =0;

	gRatioImg = cvCreateImage(cvSize(imgInput->width, imgInput->height),BINNUM,1);
	gWeightImg = cvCreateImage(cvSize(imgInput->width, imgInput->height),8,1);
	gImgFgMask = cvCreateImage(cvGetSize(imgInput), 8, 1);
	gImgObjMask = cvCreateImage(cvGetSize(imgInput), 8, 3);

	//generate FEATNUM feature combination list
	gencolorfeatures();

	//get outter bg bounding box 
	boxHalfWid = (int)fn_Round((inTargetBox.right - inTargetBox.left)/2);
	boxHalfHgt = (int)fn_Round((inTargetBox.bottom - inTargetBox.top)/2);
	dmax = max(boxHalfWid, boxHalfHgt);

	bgBox.left = inTargetBox.left - (int)fn_Round(dmax*boxRatio);
	bgBox.right = inTargetBox.right + (int)fn_Round(dmax*boxRatio);
	bgBox.top = inTargetBox.top - (int)fn_Round(dmax*boxRatio);
	bgBox.bottom = inTargetBox.bottom + (int)fn_Round(dmax*boxRatio);
	utl_RectCheckBound(&bgBox,imgInput->width, imgInput->height);

	//compcolorfeatures for foreground and background
	countObj = 0;
	countBg = 0;
	for(i=0;i<FEATNUM;i++){
		for(j=0;j<BINNUM;j++){	
			histObj[i][j] = 0;
			histBg[i][j] = 0;
		}
	}

	for(col=bgBox.left+1;col<=bgBox.right;col++){
		for(row=bgBox.top+1;row<=bgBox.bottom;row++){
			pixel = cvGet2D(imgInput, row, col); //pixel value is in order of B,G,R
			//judge obj or background			
			//if (col>inTargetBox.left && col<=inTargetBox.right && row>inTargetBox.top && row<=inTargetBox.bottom){
			//	if (cvGetReal2D(imgObjMask, row,col)>0){
			if (col>inTargetBox.left && col<=inTargetBox.right && row>inTargetBox.top && row<=inTargetBox.bottom && cvGetReal2D(imgObjMask, row,col)>0)
			{
				//obj pixel
				countObj++;
				//calculate feature for feature list
				for(i=0;i<FEATNUM;i++){
					feat = (int)floor((gFeatlist[i][0]*pixel.val[2]+gFeatlist[i][1]*pixel.val[1]+gFeatlist[i][2]*pixel.val[0]+gFeatlist[i][3])/gFeatlist[i][4]);
					featbin = (int)floor(feat/8);
					//object histogram
					histObj[i][featbin]++;
				}			
			}
			else{
				//background pixel
				countBg++;
				//calculate feature for feature list
				for(i=0;i<FEATNUM;i++){
					feat = (gFeatlist[i][0]*pixel.val[2]+gFeatlist[i][1]*pixel.val[1]+gFeatlist[i][2]*pixel.val[0]+gFeatlist[i][3])/gFeatlist[i][4];
					featbin = (int)floor(feat/8);
					//background histogram
					histBg[i][featbin]++;
				}
			}			
		}
	}
	
	//get Fg pixel count
	gMaskFgRatio = (float)countObj/((inTargetBox.right-inTargetBox.left)*(inTargetBox.bottom-inTargetBox.top));

	//normalize histogram and calculate log ratio
	{
		double  x[FEATNUM][BINNUM]; //logRatio
		double  xx[FEATNUM][BINNUM]; //logRatio^2
		double  Ex_obj[FEATNUM], Exx_obj[FEATNUM];
		double  Ex_bg[FEATNUM], Exx_bg[FEATNUM];
		double  Ex_tot[FEATNUM], Exx_tot[FEATNUM];
		double  var_obj[FEATNUM], var_bg[FEATNUM], var_within[FEATNUM], var_between[FEATNUM];
		double  score[FEATNUM], score_sort[FEATNUM];
		double	maxscore, maxscore2, maxscore3;
		int		maxscoreIdx, maxscore2Idx, maxscore3Idx;	//index of max score feature		
		double	*tmp;
		int		num=FEATNUM;

		for (i=0;i<FEATNUM;i++){//for each feature
			Ex_obj[i] = 0;
			Exx_obj[i] = 0;
			Ex_bg[i] = 0;
			Exx_bg[i] = 0;
			Ex_tot[i] = 0;
			Exx_tot[i] = 0;						
			for(j=0;j<BINNUM;j++){//for each histogram bin
				Pobj[i][j] = (double)histObj[i][j]/countObj;
				gPobjFirst[i][j] = Pobj[i][j]; //record the histogram of first frame into global array
				Pbg[i][j] = (double)histBg[i][j]/countBg;
				Ptotal[i][j] = (Pobj[i][j] + Pbg[i][j])/2;				
				logRatio[i][j] =  max(-7, min(7,log((Pobj[i][j]+0.001)/(Pbg[i][j]+0.001))));
				x[i][j] = logRatio[i][j];
				xx[i][j] = x[i][j]*x[i][j];
				Ex_obj[i] = Ex_obj[i] + x[i][j]*Pobj[i][j];
				Exx_obj[i] = Exx_obj[i] + xx[i][j]*Pobj[i][j];
				Ex_bg[i] = Ex_bg[i] + x[i][j]*Pbg[i][j];
				Exx_bg[i] = Exx_bg[i] + xx[i][j]*Pbg[i][j];
				Ex_tot[i] = Ex_tot[i] + x[i][j]*Ptotal[i][j];
				Exx_tot[i] = Exx_tot[i] + xx[i][j]*Ptotal[i][j];
			}
		}

		//calculate variation score and find max feature index
		maxscoreIdx = 0;
		for (i=0;i<FEATNUM;i++){
			var_obj[i] = Exx_obj[i] - Ex_obj[i]*Ex_obj[i];
			var_bg[i] = Exx_bg[i] - Ex_bg[i]*Ex_bg[i];
			var_between[i] = Exx_tot[i] - Ex_tot[i]*Ex_tot[i];
			var_within[i] = (var_obj[i] + var_bg[i])/2;
			score[i] = var_between[i] / max(var_within[i], 1e-6);
			score_sort[i] = score[i];
			if (i==0){
				maxscore = score[i];
				maxscoreIdx = i;
			}			
			else{			
				if(score[i]>maxscore){
					maxscore = score[i];
					maxscoreIdx = i;
				}
			}
		}		

		//get the second max score
		qsort(score_sort, (size_t)FEATNUM, sizeof(double), compare);
		maxscore2 = score_sort[47];	
		maxscore3 = score_sort[46];
		tmp = _lfind(&maxscore2, score, &num, sizeof(double), compare);
		maxscore2Idx = tmp-score;	
		tmp = _lfind(&maxscore3, score, &num, sizeof(double), compare);
		maxscore3Idx = tmp-score;
	
		//record results into global variables for tracking purpose
		gMaxFeatIdx[0] = maxscoreIdx;
		gMaxFeatIdx[1] = maxscore2Idx;
		gMaxFeatIdx[2] = maxscore3Idx;
		gMaxFeatScore[0] = maxscore;
		gMaxFeatScore[1] = maxscore2;
		gMaxFeatScore[2] = maxscore3;

		//record the logratio of max score feature
		for(j=0;j<BINNUM;j++){//for each histogram bin
			gMaxFeatRatio[0][j] = logRatio[maxscoreIdx][j];
			gMaxFeatRatio[1][j] = logRatio[maxscore2Idx][j];
			gMaxFeatRatio[2][j] = logRatio[maxscore3Idx][j];
		}		
	}//end block

	//get weight image for display purpose
	{
		int featIdx;
		double maxRatio;
		double ratio;		

		featIdx  = gMaxFeatIdx[0];		//max feature index in featlist;
		maxRatio = gMaxFeatScore[0];	//max feature ratio score		
		
		//get ratio image
		cvSetZero(gWeightImg);
		for(col=bgBox.left;col<bgBox.right;col++){
			for(row=bgBox.top;row<bgBox.bottom;row++){
				pixel = cvGet2D(imgInput, row, col); //pixel value is in order of B,G,R
				//calculate feature 
				feat = (gFeatlist[featIdx][0]*pixel.val[2]+gFeatlist[featIdx][1]*pixel.val[1]+gFeatlist[featIdx][2]*pixel.val[0]+gFeatlist[featIdx][3])/gFeatlist[featIdx][4];
				featbin = (int)floor(feat/8);
				ratio = gMaxFeatRatio[0][featbin];
				//set weight image
				pixel.val[0] = (int)(255*ratio/maxRatio);
				cvSet2D(gWeightImg, row, col, pixel);
			}	
		}
		//cvSaveImage("c:\\CTracker\\gWeightImg.bmp", gWeightImg);
	}
}

///////////////////////////////////////////////////////////////////////////////
void feat_TrackInit_PeakDiff(IplImage* imgInput, IplImage* imgObjMask, RECT inTargetBox)
//init tracker
{	
	RECT	bgBox;
	int		row,col;
	CvScalar pixel;
	int		boxHalfWid, boxHalfHgt;	
	int		dmax;	
	int		i,j;
	double  feat;
	int		featbin;
	long	histObj[FEATNUM][BINNUM], histBg[FEATNUM][BINNUM];
	double  Pobj[FEATNUM][BINNUM], Pbg[FEATNUM][BINNUM];
	//double	Ptotal[FEATNUM][BINNUM];
	double  logRatio[FEATNUM][BINNUM]; 
	long	countObj, countBg;
	float	boxRatio = gBoxRatio;			//ratio between forground and background bounding box		

	//cvSaveImage("img0001.bmp", imgInput);	
	gFrameCount =0;

	gRatioImg = cvCreateImage(cvSize(imgInput->width, imgInput->height),32,1); //float image
	gWeightImg = cvCreateImage(cvSize(imgInput->width, imgInput->height),8,1);
	gImgFgMask = cvCreateImage(cvGetSize(imgInput), 8, 1);
	gImgObjMask = cvCreateImage(cvGetSize(imgInput), 8, 3);

	//generate FEATNUM feature combination list
	gencolorfeatures();

	//get outter bg bounding box 
	boxHalfWid = (int)fn_Round((inTargetBox.right - inTargetBox.left)/2);
	boxHalfHgt = (int)fn_Round((inTargetBox.bottom - inTargetBox.top)/2);
	dmax = max(boxHalfWid, boxHalfHgt);

	bgBox.left = inTargetBox.left - (int)fn_Round(dmax*boxRatio);
	bgBox.right = inTargetBox.right + (int)fn_Round(dmax*boxRatio);
	bgBox.top = inTargetBox.top - (int)fn_Round(dmax*boxRatio);
	bgBox.bottom = inTargetBox.bottom + (int)fn_Round(dmax*boxRatio);
	utl_RectCheckBound(&bgBox,imgInput->width, imgInput->height);

	//compcolorfeatures for foreground and background
	countObj = 0;
	countBg = 0;
	for(i=0;i<FEATNUM;i++){
		for(j=0;j<BINNUM;j++){	
			histObj[i][j] = 0;
			histBg[i][j] = 0;
		}
	}

	for(col=bgBox.left+1;col<=bgBox.right;col++){
		for(row=bgBox.top+1;row<=bgBox.bottom;row++){
			pixel = cvGet2D(imgInput, row, col); //pixel value is in order of B,G,R
			//judge obj or background			
			//if (col>inTargetBox.left && col<=inTargetBox.right && row>inTargetBox.top && row<=inTargetBox.bottom){
			//	if (cvGetReal2D(imgObjMask, row,col)>0){
			if (col>inTargetBox.left && col<=inTargetBox.right && row>inTargetBox.top && row<=inTargetBox.bottom && cvGetReal2D(imgObjMask, row,col)>0)
			{
				//obj pixel
				countObj++;
				//calculate feature for feature list
				for(i=0;i<FEATNUM;i++){
					feat = (int)floor((gFeatlist[i][0]*pixel.val[2]+gFeatlist[i][1]*pixel.val[1]+gFeatlist[i][2]*pixel.val[0]+gFeatlist[i][3])/gFeatlist[i][4]);
					featbin = (int)floor(feat/8);
					//object histogram
					histObj[i][featbin]++;
				}				
			}
			else{
				//background pixel
				countBg++;
				//calculate feature for feature list
				for(i=0;i<FEATNUM;i++){
					feat = (gFeatlist[i][0]*pixel.val[2]+gFeatlist[i][1]*pixel.val[1]+gFeatlist[i][2]*pixel.val[0]+gFeatlist[i][3])/gFeatlist[i][4];
					featbin = (int)floor(feat/8);
					//background histogram
					histBg[i][featbin]++;
				}
			}			
		}
	}

	//get Fg pixel count
	gMaskFgRatio = (float)countObj/((inTargetBox.right-inTargetBox.left)*(inTargetBox.bottom-inTargetBox.top));

	//normalize histogram and calculate log ratio	
	for (i=0;i<FEATNUM;i++){//for each feature
		for(j=0;j<BINNUM;j++){//for each histogram bin
			Pobj[i][j] = (double)histObj[i][j]/countObj;
			gPobjFirst[i][j] = Pobj[i][j]; //record the histogram of first frame into global array
			Pbg[i][j] = (double)histBg[i][j]/countBg;
			logRatio[i][j] =  max(-7, min(7,log((Pobj[i][j]+0.001)/(Pbg[i][j]+0.001))));
		}
	}	

	//get max peak diff index 
	{
		int featIdx;	
		int maxPeakDiffIdx;
		double ratio;
//		CvPoint	peak;
		CvPoint secondPeak;
		double maxVal, maxVal2;
		int		convWidth, convHeight;
		double minratio, maxratio;			
		double scale;
		double shift;
		CvRect roi;
		int	 peakDiff, maxPeakDiff;
		IplImage *imgWeight;
		IplImage *imgBuffer;
		POINT	objCenter;
		
		roi.x = bgBox.left;
		roi.y = bgBox.top;
		roi.width = bgBox.right-bgBox.left;
		roi.height = bgBox.bottom-bgBox.top;
		cvSetZero(gWeightImg);
		cvSetImageROI(imgInput, roi);
		cvSetImageROI(gRatioImg, roi);
		cvSetImageROI(gWeightImg, roi);
		cvSetImageROI(imgObjMask, roi);		
		cvNot(imgObjMask, imgObjMask);

		//get obj center
		objCenter.x = roi.width/2;
		objCenter.y = roi.height/2;

		//loop through featurelist to get maximum peak diff
		maxPeakDiff = 0;
		maxPeakDiffIdx = 0;

⌨️ 快捷键说明

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