1.双线性插值的代码:
inline double getBilinearInterpolatedValue(const Mat& img,const Vector2d& pt)
{
uchar* d=&img.data[int(pt(1,0))img.step+int(pt(0,0))]; //取左上角
double xx=pt(0,0)-floor(pt(0,0));
double yy=pt(1,0)-floor(pt(0,0));
return ((1-xx)(1-yy)double(d[0])+xx(1-yy)double(d[1])+(1-xx)yydouble(d[img.step])+
xxyy*double(d[img.step+1]))/255.0; //灰度归一化处理
}
2.关于NCC SSD SAD的部分代码:
double NCC(const Mat& ref,const Mat& curr,const Vector2d& pt_ref,Vector2d& pt_curr)
{
double mean_ref=0,mean_curr=0;
vector values_ref,values_curr;
for(int x=-ncc_window_size;x<=ncc_window_size;x++)
{
for(int y=-ncc_window_size;y<=ncc_window_size;y++)
{
double value_ref=double(ref.ptr(y+ptr_ref(1,0))[x+ptr_ref(0,0)])/255.0; //灰度值归一化
mean_ref+=value_ref;
double value_curr=getBilinearInterpolatedValue(curr,pt_curr+Vector2d(x,y));
mean_curr+=value_curr;
//把块变成向量
values_ref.push_back(value_ref);
values_curr.push_back(value_curr);
}
}
mean_ref/=ncc_area;
mean_curr/=ncc_area;
double numerator=0;multiple1=0,multiply2=0;
for(int i=0;i<values_ref.size();i++)
{
double n=(values_curr[i]-mean_curr)*(values_ref[i]-mean_ref);
numerator+=n;
multiple1+=(values_curr[i]-mean_curr)*(values_curr[i]-mean_curr);
multiple2+=(values_ref[i]-mean_ref)*(values_ref[i]-mean_ref);
}
return double(numerator/sqrt(multiple1*multiple2+le-10));//防止分母出现0
}
//不去均值的ncc
double NCC_n(const Mat& ref,const Mat& curr,const Vector2d& pt_ref,Vector2d& pt_curr)
{
//double mean_ref=0,mean_curr=0;
vector values_ref,values_curr;
for(int x=-ncc_window_size;x<=ncc_window_size;x++)
{
for(int y=-ncc_window_size;y<=ncc_window_size;y++)
{
double value_ref=double(ref.ptr(y+ptr_ref(1,0))[x+ptr_ref(0,0)])/255.0; //灰度值归一化
//mean_ref+=value_ref;
double value_curr=getBilinearInterpolatedValue(curr,pt_curr+Vector2d(x,y));
//mean_curr+=value_curr;
//把块变成向量
values_ref.push_back(value_ref);
values_curr.push_back(value_curr);
}
}
//mean_ref/=ncc_area;
// mean_curr/=ncc_area;
double numerator=0,multiple1=0,multiply2=0;
for(int i=0;i<values_ref.size();i++)
{
double n=(values_curr[i])*(values_ref[i]);
numerator+=n;
multiple1+=(values_curr[i])*(values_curr[i]);
multiple2+=(values_ref[i])*(values_ref[i]);
}
return double(numerator/sqrt(multiple1*multiple2+le-10));//防止分母出现0
}
//不去均值的SSD
double SSD_n(const Mat& ref,const Mat& curr,const Vector2d& pt_ref,Vector2d& pt_curr)
{
vector values_ref,values_curr;
for(int y=-ncc_window_size;y<=ncc_window_size;y++)
{
for(int x=-ncc_window_size;x<=ncc_window_size;x++)
{
double value_ref=double(ref.ptr(ptr_ref(1,0)+y)[ptr_ref(0,0)+x])/255.0;
double value_curr=getBilinearInterpolatedValue( curr, pt_curr+Vector2d(x,y) );
values_ref.push_back(value_ref);
values_curr.push_back(value_curr);
}
}
double sum_sqrt=0;
for(int i=0;i<values_ref.size();i++)
{
sum_sqrt+=(values_ref[i]-values_curr[i])*(values_ref[i]-values_curr[i]);
}
return double(sum_sqrt);
}
//去均值的SSD
double SSD(const Mat& ref,const Mat& curr,const Vector2d& pt_ref,Vector2d& pt_curr)
{
vector values_ref,values_curr;
double mean_ref=0,mean_curr=0;
for(int y=-ncc_window_size;y<=ncc_window_size;y++)
{
for(int x=-ncc_window_size;x<=ncc_window_size;x++)
{
double value_ref=double(ref.ptr(ptr_ref(1,0)+y)[ptr_ref(0,0)+x])/255.0;
mean_ref+=value_ref;
double value_curr=getBilinearInterpolatedValue( curr, pt_curr+Vector2d(x,y) );
mean_curr+=value_curr;
values_ref.push_back(value_ref);
values_curr.push_back(value_curr);
}
}
double sum_sqrt=0;
for(int i=0;i<values_ref.size();i++)
{
sum_sqrt+=((values_ref[i]-mean_ref)-(values_curr[i]-mean_curr))*((values_ref[i]-mean_ref)-(values_curr[i]-mean_curr));
}
return double(sum_sqrt);
}
//去均值的SAD
double SAD(const Mat& ref,const Mat& curr,const Vector2d& pt_ref,Vector2d& pt_curr)
{
vector values_ref,values_curr;
double mean_ref=0,mean_curr=0;
for(int y=-ncc_window_size;y<=ncc_window_size;y++) //给定一个点就可以进行不同方向上的搜索
{
for(int x=-ncc_window_size;x<=ncc_window_size;x++)
{
double value_ref=double(ref.ptr(ptr_ref(1,0)+y)[ptr_ref(0,0)+x])/255.0;
mean_ref+=value_ref;
double value_curr=getBilinearInterpolatedValue( curr, pt_curr+Vector2d(x,y) );
mean_curr+=value_curr;
values_ref.push_back(value_ref);
values_curr.push_back(value_curr);
}
}
double sum_abs=0;
for(int i=0;i<values_ref.size();i++)
{
sum_abs+=fabs((values_ref[i]-mean_ref)-(values_curr[i]-mean_curr));
}
return double(sum_abs);
}
//不去均值的SAD
double SAD_n(const Mat& ref,const Mat& curr,const Vector2d& pt_ref,Vector2d& pt_curr)
{
vector values_ref,values_curr;
//double mean_ref=0,mean_curr=0;
for(int y=-ncc_window_size;y<=ncc_window_size;y++) //给定一个点就可以进行不同方向上的搜索
{
for(int x=-ncc_window_size;x<=ncc_window_size;x++)
{
double value_ref=double(ref.ptr(ptr_ref(1,0)+y)[ptr_ref(0,0)+x])/255.0;
//mean_ref+=value_ref;
double value_curr=getBilinearInterpolatedValue( curr, pt_curr+Vector2d(x,y) );
//mean_curr+=value_curr;
values_ref.push_back(value_ref);
values_curr.push_back(value_curr);
}
}
double sum_abs=0;
for(int i=0;i<values_ref.size();i++)
{
sum_abs+=fabs(values_ref[i]-values_curr[i]);
}
return double(sum_abs);
}