一个很奇怪的问题,本意是想调用一个函数时才对某个变量赋值,但是为什么我还没调用个函数,这个变量的值就改变量,求助大虾们.具体情况是这样的,我定义了一个函数,它的功能是求相似度,原代码如下:
double MuBiaoShiBie::similarity(double Qu[16],double Pu[16],double similar)
{
int i;
for(i=0;i<16;i++)
similar+=sqrt(Qu[i]*Pu[i]);

return similar;
}
执行这个函数后,将其值还回到similar中,另外还定义了一个函数,起代码如下:
void MuBiaoShiBie::Density(unsigned char *tempimage,MuBiaoCanShu obj,int width,int height,int hx,int hy,double probality[16],double * k,int **BianMa)
{
int i,j;
double Gj,Gi;     //x,y方向梯度;
double ctea;   //角度
int Sum;
Gj=Gi=0;

//防止边界出界
if((obj.mov.x-hx)<0)
obj.mov.x=hx;
if((obj.mov.y-hy)<0)
obj.mov.y=hy;
if((obj.mov.x+hx)>width-2)
obj.mov.x=width-hx-2;
if((obj.mov.y+hy)>height-2)
obj.mov.y=height-hy-2;
for(i=obj.mov.y-hy;i<=obj.mov.y+hy;i++)
for(j=obj.mov.x-hx;j<=obj.mov.x+hx;j++)
{
/* Gj=(tempimage[j-1][i+1]+2*tempimage[j][i+1]+tempimage[j+1][i+1])
-(tempimage[j-1][i-1]+2*tempimage[j][i-1]+tempimage[j+1][i-1]);  //x方向
Gi=(tempimage[j+1][i-1]+2*tempimage[j+1][i]+tempimage[j+1][i+1])
-(tempimage[j-1][i-1]+2*tempimage[j-1][i]+tempimage[j-1][i+1]);  //y方向
*/
Gj=double(tempimage[i*width+j+1]-tempimage[i*width+j]);///tempimage[i][j];
Gi=double(tempimage[(i+1)*width+j]-tempimage[i*width+j]);///tempimage[i][j];
if(Gj<0 && Gi!=0)  //第二,三象限
ctea=atan(Gj/Gi)+PI;
else if(Gj>0 && Gi<0)  //第四象限
ctea=atan(Gj/Gi)+2*PI;
else if(Gj==0 && Gi>0)   //PI/2
ctea=PI/2;
else if(Gj==0 && Gi<0)   //3*PI/2
ctea=3*PI/2;
else if(Gj>=0 && Gi==0)   //0
ctea=0;
else if(Gj<0 && Gi==0)   //PI
ctea=PI;
else if(Gj>0 && Gi>0)  //第一象限
ctea=atan(Gj/Gi);
//需要阈值,因为搜索窗口中占有的边缘还是比较少的,大部分的梯度值还是比较小
//这部分的值出现的概率比较大,因此要是让这部分值参与运算,将使的它对相似度的影响比较大
//因此设置阈值可以剔除这部分值的影响
Sum=(int)(fabs(Gj)+fabs(Gi));
if(Sum>20)  //此阈值设为20则可以跟踪到"航模特技飞行"视频中的2:42到2:49这段视频
BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]=long(8*ctea/PI+0.5);  //量化成16个方向角度
else
BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]=16; }
for(i=obj.mov.y-hy;i<=obj.mov.y+hy;i++)
for(j=obj.mov.x-hx;j<=obj.mov.x+hx;j++)
{
probality[BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]]=probality[BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]]
+k[(i-obj.mov.y+hy)*(2*hx+1)+j-obj.mov.x+hx];
}

}
程序运行时将在这个函数中调用它们
MuBiaoCanShu MuBiaoShiBie::GrayobjectMeanshift(unsigned char *tempimage, int width, int height, MuBiaoCanShu obj, int hx,int hy,\
   double Qu[16],int tem_l,int tem_h)
{
int i,j;
int e=1;   //均值漂移算出来的新中心与原来中心的差值的允许最大值
double similary1,similary2;  //记录相似度
similary1=similary2=0.0;
double Pu[16];
memset(Pu,0,16*sizeof(double));  //侯选区域中每个方向角的特征编码出现概率

int X,Y;    //
// int hx,hy;    //搜索窗口的宽和高
double distance;  //两像素点之间空间距离;
double Ch;      //搜索区域内所有点的核函数值之和
Ch=0; double * k=(double*)malloc((2*hx+1)*(2*hy+1)*sizeof(double));
memset(k,0,(2*hx+1)*(2*hy+1)*sizeof(double));   //核函数值,窗口的宽度为(2hx+1)*(2hy+1) int **BianMa=(int **)malloc((2*hy+1)*sizeof(int *));
for(i=0;i<(2*hy+1);i++)
{
BianMa[i]=(int *)malloc((2*hx+1)*sizeof(int));
memset(BianMa[i],0,(2*hx+1)*(sizeof(int)));
} double **weight=(double **)malloc((2*hy+1)*sizeof(double *));
for(i=0;i<(2*hy+1);i++)
{
weight[i]=(double *)malloc((2*hx+1)*sizeof(double));
memset(weight[i],0,(2*hx+1)*(sizeof(double)));
}
//计算核函数的值
for(i=0;i<2*hy+1;i++)
for(j=0;j<2*hx+1;j++)
{
X=j-hx;
Y=i-hy;

distance=pow(X,2)+pow(Y,2); k[i*(2*hx+1)+j]=1-distance/(pow(hx+1,2)+pow(hy+1,2));
Ch+=k[i*(2*hx+1)+j];
}
//核函数值归一化
for(i=0;i<2*hy+1;i++)
for(j=0;j<2*hx+1;j++)
{
k[i*(2*hx+1)+j]/=Ch;
}



//前五帧利用邻域信息熵,检测出目标,并获得其中心位置,
//同时计算出目标模板的编码概率密度
if(obj.n<3)
{
obj=LocalXinXiShang(tempimage,width,height,obj,tem_l,tem_h);
//计算模板目标特征模型
Density(tempimage,obj,width,height,hx,hy,Qu,k,BianMa);
// obj.n++;
obj.center[0].x=obj.mov.x;
obj.center[0].y=obj.mov.y;
}
//此后开始利用基于梯度方向角度的mean-shift方法跟踪目标
else
{

//计算侯选目标特征模型
Density(tempimage,obj,width,height,hx,hy,Pu,k,BianMa);
//计算侯选区域模型与模板模型的相似度
similary1=similarity(Qu,Pu,similary1);

label: obj.center[0].x=obj.mov.x;
obj.center[0].y=obj.mov.y;
//计算权值
Weight(BianMa,weight,hx,hy,Qu,Pu);

//由Mean—shift算法迭代的侯选目标新位置
obj=newcenter(obj, weight,hx,hy);
//新的侯选目标位置的目标特征模型概率密度
Density(tempimage,obj,width,height,hx,hy,Pu,k,BianMa);  
//新的候选区域与模板的相似度
// similary2=0;
similary2=similarity(Qu,Pu,similary2);
while(similary2<similary1)
{
obj.mov.x=long((obj.center[0].x+obj.mov.x)/2+0.5);   //y2=(y1+y2)/2
obj.mov.y=long((obj.center[0].y+obj.mov.y)/2+0.5);   //y1,y2为目标中心 Density(tempimage,obj,width,height,hx,hy,Pu,k,BianMa);  
//新的候选区域与模板的相似度
// similary2=0;
similary2=similarity(Qu,Pu,similary2);
}
// }
if(abs(obj.center[0].x-obj.mov.x)>e || abs(obj.center[0].y-obj.mov.y)>e)
goto label;
for(i=0;i<16;i++)
Qu[i]=Pu[i];//+0.2*Qu[i];
obj.n++;
}

//释放空间;
free(k);
for(i=0;i<2*hy+1;i++)
{
free(weight[i]);
free(BianMa[i]);
} //用十字线跟踪目标,波门和十字线
//if条件是为了保证小波门超出图像范围,避免出错

if((obj.mov.y-15)>0 && (obj.mov.y+15)<height &&  (obj.mov.x-15)>0 && (obj.mov.x+15)<width )
{
for(i=obj.mov.y-14;i<obj.mov.y+14;i++)
{
tempimage[i*width+obj.mov.x-14]=(BYTE)200;  
tempimage[i*width+obj.mov.x-13]=(BYTE)200; tempimage[i*width+obj.mov.x]=(BYTE)255;
tempimage[i*width+obj.mov.x+14]=(BYTE)200; tempimage[i*width+obj.mov.x+15]=(BYTE)200;
}
for(j=obj.mov.x-14;j<obj.mov.x+15;j++)
{
tempimage[(obj.mov.y-13)*width+j]=(BYTE)200;
tempimage[(obj.mov.y+13)*width+j]=(BYTE)200; tempimage[obj.mov.y*width+j]=(BYTE)255; tempimage[(obj.mov.y-12)*width+j]=(BYTE)200;
tempimage[(obj.mov.y+14)*width+j]=(BYTE)200;
}
}
else
{
for(i=height/2-80;i<height/2+80;i++)
{
tempimage[i*width+width/2-120]=(BYTE)200;  
tempimage[i*width+width/2-119]=(BYTE)200; tempimage[i*width+width/2]=(BYTE)255;

tempimage[i*width+width/2+120]=(BYTE)200;
tempimage[i*width+width/2+119]=(BYTE)200;
}
for(j=width/2-120;j<width/2+120;j++)
{
tempimage[(height/2-80)*width+j]=(BYTE)200;
tempimage[(height/2+80)*width+j]=(BYTE)200; tempimage[height/2*width+j]=(BYTE)255; tempimage[(height/2-79)*width+j]=(BYTE)200;
tempimage[(height/2-81)*width+j]=(BYTE)200;
} }
//屏幕十字线
for(i=(height/2-height/3);i<(height/2+height/3);i++)
{
tempimage[i*width+(width/2)-1]=(BYTE)0;  
tempimage[i*width+width/2]=(BYTE)0;
tempimage[i*width+(width/2)+1]=(BYTE)0;
} for(j=(width/2-width/3);j<(width/2+width/3);j++)
{
tempimage[(height/2-1)*width+j]=(BYTE)0;
tempimage[(height/2)*width+j]=(BYTE)0;
tempimage[(height/2+1)*width+j]=(BYTE)0;
}
return obj;
}
开始时,如上面函数中,我将similary1=similary2=0.0;但是为什么当我调试执行上面蓝色代码处时,即Density(tempimage,obj,width,height,hx,hy,Pu,k,BianMa);函数时,similary1=0;similary2不等于0,按道理上他们两应该都为0才对啊,因为还没有执行similarity(,,)函数啊,同理在执行到下面那行蓝色代码时,也会改变similary2的值,这是为什么啊,请大虾们帮忙看看阿,多谢了

解决方案 »

  1.   

    最大的可能就是Density函数中处理数组时越界了。
      

  2.   

    单步调试程序,监视similary2。
      

  3.   

    支持楼上。
    感觉应该是这句的问题:
    probality[BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]]=probality[BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]]
    +k[(i-obj.mov.y+hy)*(2*hx+1)+j-obj.mov.x+hx]; 
    你的probality数组只有16个单元,当BianMa[i-obj.mov.y+hy][j-obj.mov.x+hx]=16 时,你的访问就越界了。
      

  4.   

    对,问题已经解决了,是Density函数中有越界现象.谢谢,给分了