//: Convert a mesh entity to a single point //: in cartesian coordinates (x,y,z) void GeomDecomp::entity_to_point (const mesh::Entity & entity, const VectorField & nodeCoord, std::vector<double> & coor) { compute_entity_centroid(entity, nodeCoord, coor); apply_rotation (coor); }
/* Rotates the tetrimino to the left (counterclockwise) */ void rotate_counterclockwise() { Tetrimino copy = *in_play; copy.rotation = (copy.rotation + 3) % 4; //3 is -1 % 4 apply_rotation(copy); }
/** @brief Extract keypoint feature vector * * ----INPUT---- * @param x_key * @param y_key * @param sigma_key * @param theta_key keypoint coordinates. * * @param imX * @param imX precomputed gradient relative to the nearest scale. * * ----PARAM---- * @param lambda_descr (=6) * - The gaussian window has a standard deviation of lambda_descr X=* sigma_key * - The patch P^descr is ( 2 * lambda_descr * sigma_key * (1+1/Nhist) wide * * @param Nhist (=4) number of histograms in each of the two directions, * @param Nbins (=8) number of bins covering the range [0,2pi] * * ----OUTPUT---- * @output descr * * ----RETURN---- * @return count number of sample contributing to the descriptor */ void sift_extract_feature_vector(float x_key, float y_key, float sigma_key, float theta_key, const float* imX, const float* imY, int w, int h, int Nhist, int Nbins, float lambda_descr, float* descr) { // Initialize descr tab for(int i = 0; i < Nhist*Nhist*Nbins; i++){descr[i] = 0.0;} // Contributing pixels are inside a patch [siMin;siMax]X[sjMin;sjMax] of // width 2*lambda_descr*sigma_key*(nhist+1)/nhist float R = (1+1/(float)Nhist)*lambda_descr*sigma_key; float Rp = M_SQRT2*R; int siMin = MAX(0, (int)(x_key - Rp +0.5)); int sjMin = MAX(0, (int)(y_key - Rp +0.5)); int siMax = MIN((int)(x_key + Rp +0.5), h-1); int sjMax = MIN((int)(y_key + Rp +0.5), w-1); /// For each pixel inside the patch. for(int si = siMin; si < siMax; si++){ for(int sj = sjMin; sj < sjMax; sj++){ // Compute pixel coordinates (sX,sY) on keypoint's invariant referential. float X = si - x_key; float Y = sj - y_key; apply_rotation(X, Y, &X, &Y, -theta_key); // Does this sample fall inside the descriptor area ? if (MAX(ABS(X),ABS(Y)) < R) { // Compute the gradient orientation (theta) on keypoint referential. double dx = imX[si*w+sj]; double dy = imY[si*w+sj]; float ori = atan2(dy, dx) - theta_key; ori = modulus(ori, 2*M_PI); // Compute the gradient magnitude and apply a Gaussian weighing to give less emphasis to distant sample double t = lambda_descr*sigma_key; double M = hypot(dx, dy) * exp(-(X*X+Y*Y)/(2*t*t)); // bin indices, Compute the (tri)linear weightings ... float alpha = X/(2*lambda_descr*sigma_key/Nhist) + (Nhist-1.0)/2.0; float beta = Y/(2*lambda_descr*sigma_key/Nhist) + (Nhist-1.0)/2.0; float gamma = ori/(2*M_PI)*Nbins; // ...and add contributions to respective bins in different histograms. // a loop with 1 or two elements int i0 = floor(alpha); int j0 = floor(beta); for(int i = MAX(0,i0);i<=MIN(i0+1,Nhist-1);i++){ for(int j = MAX(0,j0);j<=MIN(j0+1,Nhist-1);j++){ // looping through all surrounding histograms. int k; // Contribution to left bin. k = ((int)gamma+Nbins)%Nbins; descr[i*Nhist*Nbins+j*Nbins+k] += (1.-(gamma-floor(gamma))) *(1.0-ABS((float)i-alpha)) *(1.0-ABS((float)j-beta)) *M; // Contribution to right bin. k = ((int)gamma+1+Nbins)%Nbins; descr[i*Nhist*Nbins+j*Nbins+k] += (1.0-(floor(gamma)+1-gamma)) *(1.0-ABS((float)i-alpha)) *(1.0-ABS((float)j-beta)) *M; } } } } } }
/* Rotates the tetrimino to the right (clockwise) */ void rotate_clockwise() { Tetrimino copy = *in_play; copy.rotation = (copy.rotation + 1) % 4; apply_rotation(copy); }