float* describe_point(const IplImage *src, t_point *pt, int &size) { int offsetX[] = {1, 1, -1, -1}; int offsetY[] = {1, -1, 1, -1}; int radius = 2; // float mag[(radius + 1) * (radius + 1) + 1]; // float ori[(radius + 1) * (radius + 1) + 1]; int _x = pt->x; int _y = pt->y; int x, y; float _mag, _ori; int bin_num = 8; float *_hist = new float[bin_num * 4]; float *hist = _hist; float sum; //memset(hist, 0, sizeof(hist)); for (int i = 0; i < bin_num * 4; i++) hist[i] = 0; for (int o = 0; o < 4; o++) { x = offsetX[o] * radius + _x; y = offsetY[o] * radius + _y; hist = _hist + o * bin_num; if (x < 0 || x >= src->width || y < 0 || y >= src->height) continue; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { //cout << x + i << " " << y + i << endl; if (calc_grad_mag_ori(src, x + i, y + j, _mag, _ori)) { int bin = cvRound(bin_num * (_ori + CV_PI) / (2 * CV_PI)); bin = bin < bin_num ? bin : 0; int ai = ABS(i); int aj = ABS(j); hist[bin] += gauss[ai][aj] * _mag; // cout << bin << endl; // cout << gauss[ai][aj] * _mag << endl; } } } // cout << "----\n"; } //cout << "****\n"; sum = 0.0; for (int j = 0; j < bin_num * 4; j++) { sum += _hist[j] * _hist[j]; } for (int i = 0; i < bin_num * 4; i++) { _hist[i] = _hist[i] / sum; } size = bin_num * 4; return _hist; }
/* Computes a gradient orientation histogram at a specified pixel. @param img image @param r pixel row @param c pixel col @param n number of histogram bins @param rad radius of region over which histogram is computed @param sigma std for Gaussian weighting of histogram entries @return Returns an n-element array containing an orientation histogram representing orientations between 0 and 2 PI. */ double* ori_hist( IplImage* img, int r, int c, int n, int rad, double sigma) { double* hist; double mag, ori, w, exp_denom, PI2 = CV_PI * 2.0; int bin, i, j; hist = (double* )calloc( n, sizeof( double ) ); exp_denom = 2.0 * sigma * sigma; for( i = -rad; i <= rad; i++ ) for( j = -rad; j <= rad; j++ ) if( calc_grad_mag_ori( img, r + i, c + j, &mag, &ori ) ) { w = exp( -( i*i + j*j ) / exp_denom ); bin = cvRound( n * ( ori + CV_PI ) / PI2 ); bin = ( bin < n )? bin : 0; hist[bin] += w * mag; } return hist; }
/* Computes a gradient orientation histogram at a specified pixel. @param img image @param r pixel row @param c pixel col @param n number of histogram bins @param rad radius of region over which histogram is computed @param sigma std for Gaussian weighting of histogram entries @return Returns an n-element array containing an orientation histogram representing orientations between 0 and 2 PI. */ static double* ori_hist( IplImage* img, int r, int c, int n, int rad, double sigma) { double* hist;//直方图数组 double mag, ori, w, exp_denom, PI2 = CV_PI * 2.0; int bin, i, j; //为直方图数组分配空间,共n个元素,n是柱的个数 hist = calloc( n, sizeof( double ) ); exp_denom = 2.0 * sigma * sigma; //遍历以指定点为中心的搜索区域 for( i = -rad; i <= rad; i++ ) for( j = -rad; j <= rad; j++ ) //计算指定点的梯度的幅值mag和方向ori,返回值为1表示计算成功 if( calc_grad_mag_ori( img, r + i, c + j, &mag, &ori ) ) { w = exp( -( i*i + j*j ) / exp_denom );//该点的梯度幅值权重 bin = cvRound( n * ( ori + CV_PI ) / PI2 );//计算梯度的方向对应的直方图中的bin下标 bin = ( bin < n )? bin : 0; hist[bin] += w * mag;//在直方图的某个bin中累加加权后的幅值 } return hist;//返回直方图数组 }