📄 msfeature.c
字号:
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_PeakDiff_Adapt(IplImage* inImg, RECT inStartBox, TkResult *outResult)
//track one frame with adaption
{
//track one frame
feat_TrackNextFrame_PeakDiff(inImg, inStartBox, outResult);
//count number of frames tracked
gFrameCount = (++gFrameCount)%gSelectFreq;
//reselect features for adaptive tracking
if (gFrameCount==0)
{
feat_ReselectFeature_PeakDiff(inImg, outResult->targetBox, outResult->FGImage);
}
}
///////////////////////////////////////////////////////////////////////////////
void meanshift(IplImage *imgInput, int xstart, int ystart, int hx, int hy, double eps, double *modex, double *modey)
//% example of mode-seeking using the mean-shift algorithm.
//% This simplified mean-shift routine works by sampling weights
//% within a rectangular window, computing the center of mass,
//% shifting the rectangle to that center of mass, and s on,
//% until convergence (rectangle moves less than epsilon).
//% Note, th algorithm converges to a local maximum. It must
//% be run multiple times all over the matrix to find all maxima,
//% if the global maximum is needed. Alternatively, you can find
//% clusters by keeping track of all the local maxima, and the
//% initialization points that led to those local maxima.
//%
//% function [modex, modey] = meanshift(im, xstart, ystart, hx, hy, eps)
//% im - 2D array containing a distribution or weights
//% xstart - col value of initial point
//% ystart - row value of initial point
//% hx - half width of rectanglar data window (determines your resolution)
//% hy - half height of data window
//% eps - less than this step size means convergence
//% output
//% modex - subpixel col value of mode
//% modey - subpixel row value of mode
{
double xcur = xstart;
double ycur = ystart;
double eps2 = eps*eps;
double dist2 = eps2+1;
int ntimes = 0;
double denom, sumx, sumy;
int dx, dy, col, row;
double incx, incy;
double pixelval;
//loop until shift dist below eps or times greater than threshold
while (dist2>eps2 && ntimes<30) {
//loop around target candidate window
denom = 0;
sumx = 0;
sumy = 0;
for(dx=-hx;dx<=hx;dx++){
for(dy=-hy;dy<=hy;dy++){
col = (int)fn_Round(dx+xcur);
row = (int)fn_Round(dy+ycur);
//judge if pixel is out of boundary
if (col<0 || col>=imgInput->width ||row<0||row>=imgInput->height){
continue;
}
pixelval = cvGetReal2D(imgInput, row, col);
denom = denom + fn_Abs(pixelval);
sumx = sumx + dx*pixelval;
sumy = sumy + dy*pixelval;
}
}
//if denom is zero, target out of boundary
if (denom==0){
*modex = xcur;
*modey = ycur;
return;
}
incx = sumx/denom;
incy = sumy/denom;
xcur = fn_Round(xcur+incx);
ycur = fn_Round(ycur+incy);
dist2 = incx*incx + incy*incy;
ntimes++;
}
//return result
*modex = xcur;
*modey = ycur;
}
///////////////////////////////////////////////////////////////////////////////
void feat_TrackCleanUp()
//clean tracker memory
{
cvReleaseImage(&gRatioImg);
cvReleaseImage(&gWeightImg);
cvReleaseImage(&gImgFgMask);
cvReleaseImage(&gImgObjMask);
}
///////////////////////////////////////////////////////////////////////////////
void gencolorfeatures()
//generate FEATNUM features list
//output: gFeatlist[FEATNUM][5] //global variable to store feature value
// gFeatlabels[FEATNUM][10] //glabal variable to store feature label
{
int r, g, b;
int featr, featg, featb;
int tmpr, tmpg, tmpb;
int i, j, k, idx; //loop index
int alphavals[5] = {0, 1, -1, 2, -2};
int minval, maxval, sumval;
int sumabs, sumneg;
int okflag;
int featNum;
// double denum;
// double uveclist[FEATNUM][3];
char strLabel[10];
char letters[3] = {'R','G', 'B'};
int first;
char strtmp[3];
int featlist[FEATNUM][5];
char featlabels[FEATNUM][10];
//get feature list
featNum = 0;
for(i=0;i<5;i++){
for(j=0;j<5;j++){
for(k=0;k<5;k++){
r = alphavals[i];
g = alphavals[j];
b = alphavals[k];
if (r*r+g*g+b*b>0){
minval = utl_Min3(r,g,b);
maxval = utl_Max3(r,g,b);
sumval = r+g+b;
if (abs(minval) > abs(maxval)){
r = -r;
g = -g;
b = -b;
}
else if(sumval<0){
r = -r;
g = -g;
b = -b;
}
okflag = 1;
//test if this feature parallel with exist features
for (idx=0;idx<featNum;idx++){
featr = featlist[idx][0];
featg = featlist[idx][1];
featb = featlist[idx][2];
tmpr = g*featb -b*featg;
tmpg = b*featr - r*featb;
tmpb = r*featg - g*featr;
if (tmpr*tmpr+tmpg*tmpg+tmpb*tmpb==0){
okflag = 0;
break;
}
}
if (okflag ==1){
sumabs = abs(r)+abs(g)+abs(b);
sumneg = 0;
if (r<0) sumneg = sumneg +r;
if (g<0) sumneg = sumneg +g;
if (b<0) sumneg = sumneg +b;
featlist[featNum][0] = r;
featlist[featNum][1] = g;
featlist[featNum][2] = b;
featlist[featNum][3] = -256*sumneg;
featlist[featNum][4] = sumabs;
// denum = sqrt(r*r+g*g+b*b);
// uveclist[featNum][0] = r/denum;
// uveclist[featNum][1] = g/denum;
// uveclist[featNum][2] = b/denum;
featNum = featNum+1;
}
}
}//end b
}//end g
}//end r
for (i=0;i<featNum;i++){
strcpy(strLabel,"");
first = 1;
for (j=0;j<3;j++){
if (featlist[i][j]!=0){
if (!first && featlist[i][j]>0){
strcat(strLabel, "+");
}
if (featlist[i][j]<0){
strcat(strLabel, "-");
}
if (abs(featlist[i][j])==1){
wsprintf(strtmp, "%c", letters[j]);
strcat(strLabel, strtmp);
}
else{
wsprintf(strtmp, "%d%c", abs(featlist[i][j]),letters[j]);
strcat(strLabel, strtmp);
}
first = 0;
}
}
strcpy(featlabels[i],strLabel);
}
//return to global variable
for (i=0;i<featNum;i++){
for(j=0;j<5;j++){
gFeatlist[i][j] = featlist[i][j];
}
strcpy(gFeatlabels[i], featlabels[i]);
}
}
///////////////////////////////////////////////////////////////////////////////
int compare( const void *arg1, const void *arg2 )
//function used in qsort and _lfind
{
/* Compare two args: */
double num1 = *(double*)arg1;
double num2 = *(double*)arg2;
if(num1> num2){ return 1;}
else{
if(num1<num2) return -1;
else return 0;
}
}
///////////////////////////////////////////////////////////////////////////////
char* feat_GetFeatLabel()
{
return gFeatlabels[gMaxFeatIdx[0]]; //string label of the max ratio feature
}
///////////////////////////////////////////////////////////////////////////////
IplImage* feat_GetWeightImage()
{
return gWeightImg; //string label of the max ratio feature
}
///////////////////////////////////////////////////////////////////////////////
float feat_CountFGPixel(IplImage *inImg, RECT inRect)
//cout foreground pixel number to find score
{
int pixCount;
float score;
CvRect crectRoi;
//count foreground points
crectRoi.x = inRect.left;
crectRoi.y = inRect.top;
crectRoi.width = inRect.right - inRect.left;
crectRoi.height = inRect.bottom - inRect.top;
cvSetImageROI(inImg, crectRoi);
pixCount = cvCountNonZero(inImg);
inImg->roi = NULL;
score = (float)pixCount/(crectRoi.width*crectRoi.height);
return score;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -