📄 msfeature.c
字号:
convWidth = ((int)((inTargetBox.right - inTargetBox.left)/2))*2+1;
convHeight = ((int)((inTargetBox.bottom - inTargetBox.top)/2))*2+1;
imgWeight = cvClone(gWeightImg);
imgBuffer = cvClone(gWeightImg);
for (featIdx=0;featIdx<FEATNUM;featIdx++){//for each feature
//get ratio image
cvSetZero(gRatioImg);
for(col=0;col<roi.width;col++){
for(row=0;row<roi.height;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 = logRatio[featIdx][featbin];
//set weight image
pixel.val[0] = ratio;
cvSet2D(gRatioImg, row, col, pixel);
}
}
//get weight image by normalizing ratio image
cvSetZero(imgWeight);
cvMinMaxLoc(gRatioImg, &minratio, &maxratio, NULL, NULL, 0);
shift = 0;
if (maxratio<=minratio){
scale = 1;
}
else{
//scale = 255.0/(maxratio-minratio);
//shift = -minratio*scale;
scale = 255.0/(fn_Abs(maxratio));
}
cvConvertScale(gRatioImg, imgWeight, scale, shift);
//cvSaveImage("c:\\CTracker\\imgWeight.bmp", imgWeight);
//mask out obj hole + Gaussian twice
//smooth with Gaussian
cvSmooth(imgWeight, imgBuffer, CV_GAUSSIAN, convWidth, convHeight,0);
//cvSaveImage("c:\\CTracker\\imgBuffer_conv.bmp", imgBuffer);
//get peak location;
//cvMinMaxLoc(imgBuffer, NULL, &maxVal, NULL, &peak, NULL);
maxVal = cvGetReal2D(imgBuffer, objCenter.y, objCenter.x);
//if (abs(peak.x-objCenter.x)>convWidth/2 || abs(peak.y-objCenter.y)>convHeight/2) continue;
//mask out peak neighbor area
cvAnd(imgWeight, imgObjMask, imgBuffer, NULL);
//cvSaveImage("c:\\CTracker\\imgBuffer_And.bmp", imgBuffer);
cvSmooth(imgBuffer, imgBuffer, CV_GAUSSIAN, convWidth, convHeight,0);
//cvSaveImage("c:\\CTracker\\imgBuffer_conv2.bmp", imgBuffer);
//get second peak location;
cvMinMaxLoc(imgBuffer, NULL, &maxVal2, NULL, &secondPeak, imgObjMask);
peakDiff = (int)(maxVal - maxVal2);
if (peakDiff > maxPeakDiff){
maxPeakDiff = peakDiff;
maxPeakDiffIdx = featIdx;
//get weight image for display purpose
cvCopy(imgWeight, gWeightImg,NULL);
//cvSaveImage("c:\\CTracker\\gWeightImg_out.bmp", gWeightImg);
}
}//end for loop
//record results into global variables for tracking purpose
gMaxFeatIdx[0] = maxPeakDiffIdx;
gPeakDiff = maxPeakDiff;
//record the logratio of max score feature
for(j=0;j<BINNUM;j++){//for each histogram bin
gMaxFeatRatio[0][j] = logRatio[maxPeakDiffIdx][j];
}
//release memory
cvRelease(&imgWeight);
cvRelease(&imgBuffer);
//reset Roi
cvResetImageROI(imgInput);
cvResetImageROI(imgObjMask);
cvResetImageROI(gRatioImg);
cvResetImageROI(gWeightImg);
}//end block of PeakDiff
}
///////////////////////////////////////////////////////////////////////////////
void feat_ReselectFeature(IplImage* imgInput, RECT inTargetBox, IplImage* imgFgMask)
//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;
//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(imgFgMask, row,col)>20){
//if(1){
//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]++;
}
}
}
}
//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;
Pobj[i][j] = (gPobjFirst[i][j]+Pobj[i][j])/2;
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
}
///////////////////////////////////////////////////////////////////////////////
void feat_ReselectFeature_PeakDiff(IplImage* imgInput, RECT inTargetBox, IplImage* imgObjMask)
//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;
//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)>20){
//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]++;
}
}
}
}
//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, secondPeak;
double maxVal, maxVal2;
int convWidth, convHeight;
double minratio, maxratio;
double scale;
double shift;
CvRect roi;
int peakDiff, maxPeakDiff;
IplImage *imgWeight;
IplImage *imgBuffer;
IplImage *imgTmp;
roi.x = bgBox.left;
roi.y = bgBox.top;
roi.width = bgBox.right-bgBox.left;
roi.height = bgBox.bottom-bgBox.top;
cvSetImageROI(imgInput, roi);
cvSetImageROI(gRatioImg, roi);
cvSetImageROI(gWeightImg, roi);
cvSetImageROI(imgObjMask, roi);
cvNot(imgObjMask, imgObjMask);
//loop through featurelist to get maximum peak diff
maxPeakDiff = 0;
maxPeakDiffIdx = 0;
convWidth = ((int)((inTargetBox.right - inTargetBox.left)/2))*2+1;
convHeight = ((int)((inTargetBox.bottom - inTargetBox.top)/2))*2+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -