void interp_step( IplImage*** dog_pyr, int octv, int intvl, int r, int c, double* xi, double* xr, double* xc ) { CvMat* dD, * H, * H_inv, X; double x[3] = { 0 }; dD = deriv_3D( dog_pyr, octv, intvl, r, c ); H = hessian_3D( dog_pyr, octv, intvl, r, c ); H_inv = cvCreateMat( 3, 3, CV_64FC1 ); cvInvert( H, H_inv, CV_SVD ); cvInitMatHeader( &X, 3, 1, CV_64FC1, x, CV_AUTOSTEP ); cvGEMM( H_inv, dD, -1, NULL, 0, &X, 0 ); cvReleaseMat( &dD ); cvReleaseMat( &H ); cvReleaseMat( &H_inv ); *xi = x[2]; *xr = x[1]; *xc = x[0]; }
/* Performs one step of extremum interpolation. Based on Eqn. (3) in Lowe's paper. @param dog_pyr difference of Gaussians scale space pyramid @param octv octave of scale space @param intvl interval being interpolated @param r row being interpolated @param c column being interpolated @param xi output as interpolated subpixel increment to interval @param xr output as interpolated subpixel increment to row @param xc output as interpolated subpixel increment to col */ static void interp_step( IplImage*** dog_pyr, int octv, int intvl, int r, int c, double* xi, double* xr, double* xc ) { CvMat* dD, * H, * H_inv, X; double x[3] = { 0 }; //在DoG金字塔中计算某点的x方向、y方向以及尺度方向上的偏导数,结果存放在列向量dD中 dD = deriv_3D( dog_pyr, octv, intvl, r, c ); //在DoG金字塔中计算某点的3*3海森矩阵 H = hessian_3D( dog_pyr, octv, intvl, r, c ); H_inv = cvCreateMat( 3, 3, CV_64FC1 );//海森矩阵的逆阵 cvInvert( H, H_inv, CV_SVD ); cvInitMatHeader( &X, 3, 1, CV_64FC1, x, CV_AUTOSTEP ); //X = - H^(-1) * dD,H的三个元素分别是x,y,σ方向上的偏移量(具体见SIFT算法说明) cvGEMM( H_inv, dD, -1, NULL, 0, &X, 0 ); cvReleaseMat( &dD ); cvReleaseMat( &H ); cvReleaseMat( &H_inv ); *xi = x[2];//σ方向(层方向)偏移量 *xr = x[1];//y方向上偏移量 *xc = x[0];//x方向上偏移量 }