接着“sift算法搭建,上半部,七”,先看公式,函数最优极值公式,再看代码:
接着前面的代码,for循环中的5,是迭代5次寻优,亚像素极值:
//将找到的极值点对应成像素(整数)
c += (int)Math.Round(xc);
r += (int)Math.Round(xr);
layer += (int)Math.Round(xi);
if (layer < 1 || layer > 3 ||
c < 5 || c >= 512 - 5 ||
r < 5 || r >= 512 - 5)
{
return false;
}
}
if (i >= 5)//5次迭代,无果,退出
{
return false;
}
{ // Matx31f dD((img.at
// (img.at
// (next.at
//float t = dD.dot(Matx31f(xc, xr, xi));
//contr = img.at
double aa = (三层dog金字塔[L][temp + 1] - 三层dog金字塔[L][temp - 1]) * 0.5;//x
double bb = (三层dog金字塔[L][temp + 512] - 三层dog金字塔[L][temp - 512]) * 0.5;//y
double cc = (三层dog金字塔[L + 1][temp] - 三层dog金字塔[L - 1][temp]) * 0.5;//s
//函数最优极值公式
// contr = aa * xc + bb * xr + cc * xi;//是否丢掉了系数1/2?//202010091112
contr =三层dog金字塔[L][temp]+1.0/2*( aa * xc + bb * xr + cc * xi);
if (Math.Abs(contr) < conthreshold) { //0.04
return false; //收敛后的值f(x)-f(x0)太小,干掉
}
下面代码,和harris角点相似,边缘(入1,入2,特征值一边大)上的最优极值干扰排除。
//使用harris角点的方法
double v2 = 三层dog金字塔[L][temp] * 2;
double dxx = (三层dog金字塔[L][temp + 1] + 三层dog金字塔[L][temp - 1] - v2);
double dyy = (三层dog金字塔[L][temp + 512] + 三层dog金字塔[L][temp - 512] - v2);
double dxy = (三层dog金字塔[L][temp + 1 + 512] + 三层dog金字塔[L][temp - 1 - 512] - (三层dog金字塔[L][temp - 1 + 512] + 三层dog金字塔[L][temp + 1 - 512])) * 0.25;
double tr = dxx + dyy;
double det = dxx * dyy - dxy * dxy;
//这里edgeThreshold可以在调用SIFT()时输入;
//其实代码中定义了 static const float SIFT_CURV_THR = 10.f 可以直接使用
if (det <= 0 || tr * tr * edgethreshold >= (edgethreshold + 1) * (edgethreshold + 1) * det)//10
{
return false;
}
}
最后,记录亚像素最优极值,我们并没有这样做,依然使用亚像素取整最优极值像素位置:
//先记录下来,找到局部极值,
keyPt.Add(new Point(c + (int)Math.Round(xc), r + (int)Math.Round(xr)));
//keyPtval.Add(new Point(c + xc, r + xr));
keyPtval.Add(三层dog金字塔[layer + (int)Math.Round(xi)][(r + (int)Math.Round(xr)) * 512 + c + (int)Math.Round(xc)]);
return true;
}
注意,我们只演示了求极大值,极小值求解调用函数一样,只是val的判断值改变了,很容易,试试看!
adjustLocalExtrema(第一组dog五层金字塔, ref keyPt, ref keyPtVal, ref layer, ref r1, ref c1,
(double)contrastThreshold,
(double)edgeThreshold))
好,sift算法搭建,上半部,完成,先告一段落!