sift算法搭建(上半部,七,dog金字塔中筛选后的极值点求最优偏差,亚像素级别,c#实现)

接“sift算法搭建上半部,六”中未完成的程序,调用函数:

    else
                        {
                            int r1 = j, c1 = i, layer = L;
                            double contrastThreshold = 0.04;
                            double edgeThreshold = 10.0;
                            // 关键点精确定位  
                            if (!adjustLocalExtrema(第一组dog五层金字塔, ref keyPt, ref  keyPtVal, ref layer, ref  r1, ref c1,
                                                    (double)contrastThreshold,
                                                    (double)edgeThreshold))
                            {
                                continue;
                            }
                        }

然后,看图,使用有限差分法可知xy的二阶偏导等于yx的二阶偏导,同理xsigma的二阶偏导等于sigmax的二阶偏导,ysigma的二级偏导等于sigmay的二阶偏导:

sift算法搭建(上半部,七,dog金字塔中筛选后的极值点求最优偏差,亚像素级别,c#实现)

sift算法搭建(上半部,七,dog金字塔中筛选后的极值点求最优偏差,亚像素级别,c#实现)

看程序:

 bool adjustLocalExtrema(List<int[]> 三层dog金字塔, ref List<Point> keyPt, ref List<int> keyPtval, ref int layer, ref int r, ref int c, double conthreshold, double edgethreshold)
        {
            double xi = 0, xr = 0, xc = 0, contr=0;
            int i = 0;
            int L = 0;//layer=L,j=r1;i=c1
            int temp =0;
             //三维子像元插值  
            for (; i < 5; i++)
            {
               
                L = layer;//这里使用的就三层,活动范围1,2,3层,对应L=0,1,2,否则,出界
                temp = r * 512 + c;//针对512*512图像,r是行,高h,c是列,宽w
                if (L >= 2) return false;
                double Ddx = (三层dog金字塔[L][temp + 1] - 三层dog金字塔[L][temp - 1]) * 0.5;
                double Ddy = (三层dog金字塔[L][temp + 512] - 三层dog金字塔[L][temp - 512]) * 0.5;
                double Ddsigama = (三层dog金字塔[L + 1][temp] - 三层dog金字塔[L - 1][temp]) * 0.5;


                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 dss = (三层dog金字塔[L + 1][temp] + 三层dog金字塔[L - 1][temp] - 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 dxs = (三层dog金字塔[L + 1][temp + 1] - 三层dog金字塔[L + 1][temp - 1] - 三层dog金字塔[L - 1][temp + 1] + 三层dog金字塔[L - 1][temp - 1]) * 0.25;
                double dys = (三层dog金字塔[L + 1][temp + 512] - 三层dog金字塔[L + 1][temp - 512] - 三层dog金字塔[L - 1][temp + 512] + 三层dog金字塔[L - 1][temp - 512]) * 0.25;

好,一阶,二阶导数有了,黑塞矩阵有了,黑塞矩阵的逆也有了,极值的最优偏差根据下面公式写程序:

sift算法搭建(上半部,七,dog金字塔中筛选后的极值点求最优偏差,亚像素级别,c#实现)

    接着上面程序:

//   HH = [dxx,dxy,dxs;dxy,dyy,dys;dxs,dys,dss];
                bool hello = 黑塞矩阵三阶的逆(ref dxx, ref dxy, ref dxs, ref dxy, ref dyy, ref dys, ref dxs, ref dys, ref dss);//二阶导数的值全改变,要注意
                if (false == hello) 
                { 
                    return false;
                }//说明黑塞矩阵三阶的逆不存在,
                // D = [Ddx,Ddy,Ddsigama];
                // X = inv(HH)*D';
                double t0 = Ddx * dxx + Ddy * dxy + Ddsigama * dxs;//使用三阶黑塞矩阵的逆参与运算
                double t1 = Ddx * dxy + Ddy * dyy + Ddsigama * dys;//一阶导数的值并未改变
                double t2 = Ddx * dxs + Ddy * dys + Ddsigama * dss;

                xi = -t2;//所在层L
                xr = -t1;//所在行r//图像高度h中的y
                xc = -t0;//所在列//图像宽度w中的x

                if (Math.Abs(xi) < 0.5 && Math.Abs(xr) < 0.5 && Math.Abs(xc) < 0.5 )//显示出来
                {             
                    break;//这个break是跳出迭代循环
                }

好,极值亚像素最优偏差得到。可以进入下一步