📄 msfeature.c
字号:
imgWeight = cvClone(gWeightImg);
imgBuffer = cvClone(gWeightImg);
imgTmp = cvClone(gWeightImg);
for (featIdx=0;featIdx<FEATNUM;featIdx++){//for each feature
if (featIdx == gMaxFeatIdx[0]) continue;
//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\\code\\imgWeight.bmp", imgWeight);
//mask out obj hole + Gaussian twice
//smooth with Gaussian
cvSmooth(imgWeight, imgBuffer, CV_GAUSSIAN, convWidth, convHeight,0);
//cvSaveImage("c:\\CTracker\\code\\imgBuffer_conv.bmp", imgBuffer);
//get peak location;
cvMinMaxLoc(imgBuffer, NULL, &maxVal, NULL, &peak, NULL);
//mask out peak neighbor area
cvAnd(imgWeight, imgObjMask, imgBuffer, NULL);
//cvSaveImage("c:\\CTracker\\code\\imgBuffer_And.bmp", imgBuffer);
cvSmooth(imgBuffer, imgBuffer, CV_GAUSSIAN, convWidth, convHeight,0);
//cvSaveImage("c:\\CTracker\\code\\imgBuffer_conv2.bmp", imgBuffer);
//get second peak location;
cvMinMaxLoc(imgBuffer, NULL, &maxVal2, NULL, &secondPeak, imgObjMask);
peakDiff = (int)fn_Abs(maxVal - maxVal2);
if (peakDiff > maxPeakDiff){
maxPeakDiff = peakDiff;
maxPeakDiffIdx = featIdx;
//get weight image for display purpose
cvCopy(imgWeight, imgTmp,NULL);
//cvSaveImage("c:\\CTracker\\code\\gWeightImg_out.bmp", gWeightImg);
}
}//end for loop
//record weight image
cvCopy(imgTmp, gWeightImg, NULL);
//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);
cvRelease(&imgTmp);
//reset Roi
cvResetImageROI(imgInput);
cvResetImageROI(imgObjMask);
cvResetImageROI(gRatioImg);
cvResetImageROI(gWeightImg);
}//end block of PeakDiff
}
///////////////////////////////////////////////////////////////////////////////
void feat_TrackNextFrame(IplImage* inImg, RECT inStartBox, TkResult *outResult)
//track one frame
{
int row, col;
CvScalar pixel;
double ratio;
double feat;
int featbin;
int i;
double dnewx, dnewy; //new subpixel x,y after meanshift
int newx, newy;
int featIdx;
int ratioIdx;
double maxscore;
int xstart, ystart;
int halfwid, halfhgt;
double candx[3], candy[3];
int numOfFeat; //feat number used in tracking
//cvSaveImage("img0002.bmp", inImg);
RECT bgBox;
//get outter bg bounding box
{
int boxHalfWid, boxHalfHgt;
int dmax;
float boxRatio = gBoxRatio;
boxHalfWid = (int)fn_Round((inStartBox.right - inStartBox.left)/2);
boxHalfHgt = (int)fn_Round((inStartBox.bottom - inStartBox.top)/2);
dmax = max(boxHalfWid, boxHalfHgt);
bgBox.left = inStartBox.left - (int)fn_Round(dmax*boxRatio);
bgBox.right = inStartBox.right + (int)fn_Round(dmax*boxRatio);
bgBox.top = inStartBox.top - (int)fn_Round(dmax*boxRatio);
bgBox.bottom = inStartBox.bottom + (int)fn_Round(dmax*boxRatio);
utl_RectCheckBound(&bgBox,inImg->width, inImg->height);
}
//loop over top 3 featus
numOfFeat=gNumOfFeat;
//numOfFeat=1;
cvSetZero(gRatioImg);
cvSetZero(gWeightImg);
for(i=0;i<numOfFeat;i++){
// i = 1; //second max
featIdx = gMaxFeatIdx[i]; //max feature index in featlist;
maxscore = gMaxFeatScore[i]; //max feature ratio score
ratioIdx = i; //log ratio index;
//get ratio image
for(col=bgBox.left;col<bgBox.right;col++){
for(row=bgBox.top;row<bgBox.bottom;row++){
pixel = cvGet2D(inImg, 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[ratioIdx][featbin];
//set ratio image for meanshift purpose
pixel.val[0] = ratio;
cvSet2D(gRatioImg, row, col, pixel);
}
}
//utl_WriteImage(gRatioImg, "ratioimg.txt");
//meanshift ratio image
xstart = (int)fn_Round(((double)inStartBox.left+inStartBox.right)/2);
ystart = (int)fn_Round(((double)inStartBox.top+inStartBox.bottom)/2);
halfwid = (int)fn_Round(((double)inStartBox.right - inStartBox.left)/2);
halfhgt = (int)fn_Round(((double)inStartBox.bottom - inStartBox.top)/2);
meanshift(gRatioImg, xstart, ystart, halfwid, halfhgt, 1.0, &dnewx, &dnewy);
candx[i] = dnewx;
candy[i] = dnewy;
//get weight image by normalizing ratio image
if (i==0)//first feature
{
double minratio, maxratio;
double scale, shift;
CvRect roi;
roi.x = bgBox.left;
roi.y = bgBox.top;
roi.width = bgBox.right-bgBox.left;
roi.height = bgBox.bottom-bgBox.top;
cvSetImageROI(gRatioImg, roi);
cvSetImageROI(gWeightImg, roi);
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, gWeightImg, scale, shift);
cvResetImageROI(gRatioImg);
cvResetImageROI(gWeightImg);
}
}
//get median from candidate x,y
newx = (int)fn_median(candx, numOfFeat);
newy = (int)fn_median(candy, numOfFeat);
//return tracking result
{
RECT targetBox;
int boxWidth, boxHeight;
int boxHalfWidth, boxHalfHeight;
float score;
float fgRatio;
//get input box dimension
boxWidth = inStartBox.right-inStartBox.left;
boxHeight = inStartBox.bottom-inStartBox.top;
boxHalfWidth = boxWidth/2;
boxHalfHeight = boxHeight/2;
//get target rect
targetBox.left = (long)(newx - boxHalfWidth);
targetBox.right = targetBox.left + boxWidth;
targetBox.top = (long)(newy - boxHalfHeight);
targetBox.bottom = targetBox.top + boxHeight;
targetBox.left = max(targetBox.left,0);
targetBox.top = max(targetBox.top,0);
targetBox.right = max(targetBox.right,1);
targetBox.bottom = max(targetBox.bottom,1);
targetBox.right = min(targetBox.right,inImg->width-1);
targetBox.bottom = min(targetBox.bottom,inImg->height-1);
targetBox.left = min(targetBox.left,inImg->width-2);
targetBox.top = min(targetBox.top,inImg->height-2);
//get occlusion score
fgRatio = feat_CountFGPixel(gWeightImg, targetBox);
score = fgRatio/ gMaskFgRatio;
score = min(1, score);
//get FG object mask image
{
CvRect roi;
cvSetZero(gImgFgMask);
cvSetZero(gImgObjMask);
roi.x = targetBox.left;
roi.y = targetBox.top;
roi.width = targetBox.right-targetBox.left;
roi.height = targetBox.bottom-targetBox.top;
cvSetImageROI(gWeightImg, roi);
cvSetImageROI(gImgFgMask, roi);
cvSetImageROI(inImg, roi);
cvSetImageROI(gImgObjMask, roi);
cvThreshold(gWeightImg, gImgFgMask, 0, 255, CV_THRESH_BINARY);
cvCopy(inImg, gImgObjMask, gImgFgMask);
cvResetImageROI(gWeightImg);
cvResetImageROI(gImgFgMask);
cvResetImageROI(inImg);
cvResetImageROI(gImgObjMask);
}
outResult->FGMask = gImgFgMask;
outResult->ObjMask = gImgObjMask;
//return tracker result
outResult->targetBox = targetBox;
outResult->FGImage = gWeightImg;
outResult->score = score;
outResult->occlusion = (score<0.6? TRUE:FALSE);
}
}
///////////////////////////////////////////////////////////////////////////////
void feat_TrackNextFrame_Adapt(IplImage* inImg, RECT inStartBox, TkResult *outResult)
//track one frame
{
//search target on this frame
feat_TrackNextFrame(inImg, inStartBox, outResult);
//count number of frames tracked
gFrameCount = (++gFrameCount)%gSelectFreq;
//reselect features for adaptive tracking
if (gFrameCount==0){
feat_ReselectFeature(inImg, outResult->targetBox, gWeightImg);
}
}
///////////////////////////////////////////////////////////////////////////////
void feat_TrackNextFrame_PeakDiff(IplImage* inImg, RECT inStartBox, TkResult *outResult)
//track one frame
{
int row, col;
CvScalar pixel;
double ratio;
double feat;
int featbin;
int i;
double dnewx, dnewy; //new subpixel x,y after meanshift
int newx, newy;
int featIdx;
int ratioIdx;
double maxscore;
int xstart, ystart;
int halfwid, halfhgt;
double candx[3], candy[3];
int numOfFeat; //feat number used in tracking
//cvSaveImage("img0002.bmp", inImg);
RECT bgBox;
//get outter bg bounding box
{
int boxHalfWid, boxHalfHgt;
int dmax;
float boxRatio = gBoxRatio;
boxHalfWid = (int)fn_Round((inStartBox.right - inStartBox.left)/2);
boxHalfHgt = (int)fn_Round((inStartBox.bottom - inStartBox.top)/2);
dmax = max(boxHalfWid, boxHalfHgt);
bgBox.left = inStartBox.left - (int)fn_Round(dmax*boxRatio);
bgBox.right = inStartBox.right + (int)fn_Round(dmax*boxRatio);
bgBox.top = inStartBox.top - (int)fn_Round(dmax*boxRatio);
bgBox.bottom = inStartBox.bottom + (int)fn_Round(dmax*boxRatio);
utl_RectCheckBound(&bgBox,inImg->width, inImg->height);
}
//loop over max PeakDiff featus
numOfFeat=1;
cvSetZero(gRatioImg);
cvSetZero(gWeightImg);
for(i=0;i<numOfFeat;i++){
// i = 1; //second max
featIdx = gMaxFeatIdx[i]; //max feature index in featlist;
maxscore = gMaxFeatScore[i]; //max feature ratio score
ratioIdx = i; //log ratio index;
//get ratio image
for(col=bgBox.left;col<bgBox.right;col++){
for(row=bgBox.top;row<bgBox.bottom;row++){
pixel = cvGet2D(inImg, 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[ratioIdx][featbin];
//set ratio image for meanshift purpose
pixel.val[0] = ratio;
cvSet2D(gRatioImg, row, col, pixel);
}
}
//utl_WriteImage(gRatioImg, "ratioimg.txt");
//meanshift ratio image
xstart = (int)fn_Round(((double)inStartBox.left+inStartBox.right)/2);
ystart = (int)fn_Round(((double)inStartBox.top+inStartBox.bottom)/2);
halfwid = (int)fn_Round(((double)inStartBox.right - inStartBox.left)/2);
halfhgt = (int)fn_Round(((double)inStartBox.bottom - inStartBox.top)/2);
meanshift(gRatioImg, xstart, ystart, halfwid, halfhgt, 1.0, &dnewx, &dnewy);
candx[i] = dnewx;
candy[i] = dnewy;
//get weight image by normalizing ratio image
if (i==0)//first feature
{
double minratio, maxratio;
double scale, shift;
CvRect roi;
roi.x = bgBox.left;
roi.y = bgBox.top;
roi.width = bgBox.right-bgBox.left;
roi.height = bgBox.bottom-bgBox.top;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -