/*** * Convertions between cv::Keypoint and KAZE::Ipoint */ static inline void convertPoint(const cv::KeyPoint& kp, Ipoint& aux) { aux.xf = kp.pt.x; aux.yf = kp.pt.y; aux.x = fRound(aux.xf); aux.y = fRound(aux.yf); //cout << "SURF size: " << kpts_surf1_[i].size*.5 << endl; aux.octave = kp.octave; // Get the radius for visualization aux.scale = kp.size*.2; // Updated by Yuhua Zou aux.angle = DEGREE_TO_RADIAN(kp.angle); //aux.descriptor_size = 64; }
//! Get the upright descriptor vector of the provided Ipoint void Surf::getUprightDescriptor() { int y, x, count=0; float scale, *desc, dx, dy, mdx, mdy; float gauss, rx, ry, len = 0.f; Ipoint *ipt = &ipts.at(index); scale = ipt->scale; y = fRound(ipt->y); x = fRound(ipt->x); desc = ipt->descriptor; // Calculate descriptor for this interest point for (int i = -10; i < 10; i+=5) { for (int j = -10; j < 10; j+=5) { dx=dy=mdx=mdy=0; for (int k = i; k < i + 5; ++k) { for (int l = j; l < j + 5; ++l) { // get Gaussian weighted x and y responses gauss = static_cast<float>(gauss33[abs(k)][abs(l)]); rx = gauss * haarX(fRound(k*scale+y), fRound(l*scale+x), 2*fRound(scale)); ry = gauss * haarY(fRound(k*scale+y), fRound(l*scale+x), 2*fRound(scale)); dx += rx; dy += ry; mdx += fabs(rx); mdy += fabs(ry); } } // add the values to the descriptor vector desc[count++] = dx; desc[count++] = dy; desc[count++] = mdx; desc[count++] = mdy; // store the current length^2 of the vector len += dx*dx + dy*dy + mdx*mdx + mdy*mdy; } } // convert to unit vector len = sqrt(len); for (int i = 0; i < 64; i++) desc[i] /= len; }
void ofxOpenSurf :: drawPoints ( int x, int y, float scale, vector<Ipoint> &ipts, int tailSize ) { glPushMatrix(); glTranslatef( x, y, 0 ); glScalef( scale, scale, 1 ); Ipoint* ipt; float s,o; int r1,c1,r2,c2,lap; for( int i=0; i<ipts.size(); i++ ) { ipt = &ipts.at( i ); s = ( ( 9.0f / 1.2f ) * ipt->scale ) / 3.0f; o = ipt->orientation; lap = ipt->laplacian; r1 = fRound( ipt->y ); c1 = fRound( ipt->x ); c2 = fRound( s * cos( o ) ) + c1; r2 = fRound( s * sin( o ) ) + r1; if( o ) //green line = orientation { ofSetColor( ofColor :: green ); ofLine( c1, r1, c2, r2 ); } else //green dot = upright conversion { ofSetColor( ofColor :: green ); ofCircle( c1, r1, 1 ); } if( lap >= 0 ) //blue circle = dark blob on light { ofNoFill(); ofSetColor( ofColor :: blue ); ofCircle( c1, r1, fRound( s ) ); } else // red circle = light blob on dark { ofNoFill(); ofSetColor( ofColor :: red ); ofCircle( c1, r1, fRound( s ) ); } if( tailSize ) //draw motion ipoint dx dy { ofSetColor( ofColor :: white ); ofLine( c1, r1, (int)( c1 + ipt->dx * tailSize ), (int)( r1 + ipt->dy * tailSize ) ); } } glPopMatrix(); }
UINT64 CWaveformTransmitter::u64GetCurrAmplitude(int CurrItr, sWaveformInfo& ouCurrSig) { float Result = 0.0; switch (ouCurrSig.m_eSignalWaveType) { case eWave_SINE: { Result = ouCurrSig.m_fAmplitude * sin(CurrItr * ouCurrSig.m_fGranularity); } break; case eWave_COS: { Result = ouCurrSig.m_fAmplitude * cos(CurrItr * ouCurrSig.m_fGranularity); } break; case eWave_TRIANGLE: { float Val = CurrItr * ouCurrSig.m_fGranularity; Result = (sin(Val) - sin(3 * Val) / 9 + sin(5 * Val) / 25 - sin(7 * Val) / 49 + sin(9 * Val) / 81) * SINE_COEFF; Result *= ouCurrSig.m_fAmplitude; } break; default: ASSERT(FALSE); } //ArunKumar K: Currently using the Peak to Peak Amplitude as 0 to 2*Amplitude //instead of -Amplitude to +Amplitude Result += ouCurrSig.m_fAmplitude; if(Result!=0) { Result = fRound(Result, 0); } return (UINT64) Result; }
void ofxDrawIpoints(int x, int y, float sz, std::vector<Ipoint> &ipts, int tailSize) { glPushMatrix(); glTranslatef(x,y,0); glScalef(sz,sz,1); Ipoint * ipt; float s,o; int r1,c1,r2,c2,lap; for(unsigned int i=0; i<ipts.size(); i++) { ipt = &ipts.at(i); s = ((9.0f/1.2f) * ipt->scale) / 3.0f; o = ipt->orientation; lap = ipt->laplacian; r1 = fRound(ipt->y); c1 = fRound(ipt->x); c2 = fRound(s * cos(o)) + c1; r2 = fRound(s * sin(o)) + r1; if(o) { //green line = orientation ofSetColor(0x00ff00); ofLine(c1,r1,c2,r2); } else { //green dot = upright conversion ofSetColor(0x00ff00); ofCircle(c1,r1,1); } if(lap>=0) { //blue circle = dark blob on light ofSetColor(0x0000ff); ofNoFill(); ofCircle(c1,r1,fRound(s)); } else { // red circle = light blob on dark ofSetColor(0xff0000); ofNoFill(); ofCircle(c1,r1,fRound(s)); } if(tailSize) { //draw motion ipoint dx dy ofSetColor(0xffffff); ofLine(c1,r1,int(c1+ipt->dx*tailSize),int(r1+ipt->dy*tailSize)); } } glPopMatrix(); }
/* This is the main workhorse of the QGridLayout. It portions out available space to the chain's children. The calculation is done in fixed point: "fixed" variables are scaled by a factor of 256. If the layout runs "backwards" (i.e. RightToLeft or Up) the layout is computed mirror-reversed, and it's the caller's responsibility do reverse the values before use. chain contains input and output parameters describing the geometry. count is the count of items in the chain; pos and space give the interval (relative to parentWidget topLeft). */ Q_EXPORT void qGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos, int space, int spacer ) { typedef int fixed; int cHint = 0; int cMin = 0; int cMax = 0; int sumStretch = 0; int spacerCount = 0; bool wannaGrow = FALSE; // anyone who really wants to grow? // bool canShrink = FALSE; // anyone who could be persuaded to shrink? int i; for ( i = start; i < start + count; i++ ) { chain[i].done = FALSE; cHint += chain[i].smartSizeHint(); cMin += chain[i].minimumSize; cMax += chain[i].maximumSize; sumStretch += chain[i].stretch; if ( !chain[i].empty ) spacerCount++; wannaGrow = wannaGrow || chain[i].expansive || chain[i].stretch > 0; } int extraspace = 0; if ( spacerCount ) spacerCount--; // only spacers between things if ( space < cMin + spacerCount * spacer ) { for ( i = start; i < start+count; i++ ) { chain[i].size = chain[i].minimumSize; chain[i].done = TRUE; } } else if ( space < cHint + spacerCount*spacer ) { /* Less space than smartSizeHint(), but more than minimumSize. Currently take space equally from each, as in Qt 2.x. Commented-out lines will give more space to stretchier items. */ int n = count; int space_left = space - spacerCount*spacer; int overdraft = cHint - space_left; // first give to the fixed ones: for ( i = start; i < start + count; i++ ) { if ( !chain[i].done && chain[i].minimumSize >= chain[i].smartSizeHint() ) { chain[i].size = chain[i].smartSizeHint(); chain[i].done = TRUE; space_left -= chain[i].smartSizeHint(); // sumStretch -= chain[i].stretch; n--; } } bool finished = n == 0; while ( !finished ) { finished = TRUE; fixed fp_over = toFixed( overdraft ); fixed fp_w = 0; for ( i = start; i < start+count; i++ ) { if ( chain[i].done ) continue; // if ( sumStretch <= 0 ) fp_w += fp_over / n; // else // fp_w += (fp_over * chain[i].stretch) / sumStretch; int w = fRound( fp_w ); chain[i].size = chain[i].smartSizeHint() - w; fp_w -= toFixed( w ); // give the difference to the next if ( chain[i].size < chain[i].minimumSize ) { chain[i].done = TRUE; chain[i].size = chain[i].minimumSize; finished = FALSE; overdraft -= ( chain[i].smartSizeHint() - chain[i].minimumSize ); // sumStretch -= chain[i].stretch; n--; break; } } } } else { // extra space int n = count; int space_left = space - spacerCount*spacer; // first give to the fixed ones, and handle non-expansiveness for ( i = start; i < start + count; i++ ) { if ( !chain[i].done && (chain[i].maximumSize <= chain[i].smartSizeHint() || (wannaGrow && !chain[i].expansive && chain[i].stretch == 0)) ) { chain[i].size = chain[i].smartSizeHint(); chain[i].done = TRUE; space_left -= chain[i].smartSizeHint(); sumStretch -= chain[i].stretch; n--; } } extraspace = space_left; /* Do a trial distribution and calculate how much it is off. If there are more deficit pixels than surplus pixels, give the minimum size items what they need, and repeat. Otherwise give to the maximum size items, and repeat. Paul Olav Tvete has a wonderful mathematical proof of the correctness of this principle, but unfortunately this comment is too small to contain it. */ int surplus, deficit; do { surplus = deficit = 0; fixed fp_space = toFixed( space_left ); fixed fp_w = 0; for ( i = start; i < start+count; i++ ) { if ( chain[i].done ) continue; extraspace = 0; if ( sumStretch <= 0 ) fp_w += fp_space / n; else fp_w += (fp_space * chain[i].stretch) / sumStretch; int w = fRound( fp_w ); chain[i].size = w; fp_w -= toFixed( w ); // give the difference to the next if ( w < chain[i].smartSizeHint() ) { deficit += chain[i].smartSizeHint() - w; } else if ( w > chain[i].maximumSize ) { surplus += w - chain[i].maximumSize; } } if ( deficit > 0 && surplus <= deficit ) { // give to the ones that have too little for ( i = start; i < start+count; i++ ) { if ( !chain[i].done && chain[i].size < chain[i].smartSizeHint() ) { chain[i].size = chain[i].smartSizeHint(); chain[i].done = TRUE; space_left -= chain[i].smartSizeHint(); sumStretch -= chain[i].stretch; n--; } } } if ( surplus > 0 && surplus >= deficit ) { // take from the ones that have too much for ( i = start; i < start+count; i++ ) { if ( !chain[i].done && chain[i].size > chain[i].maximumSize ) { chain[i].size = chain[i].maximumSize; chain[i].done = TRUE; space_left -= chain[i].maximumSize; sumStretch -= chain[i].stretch; n--; } } } } while ( n > 0 && surplus != deficit ); if ( n == 0 ) extraspace = space_left; } /* As a last resort, we distribute the unwanted space equally among the spacers (counting the start and end of the chain). We could, but don't, attempt a sub-pixel allocation of the extra space. */ int extra = extraspace / ( spacerCount + 2 ); int p = pos + extra; for ( i = start; i < start+count; i++ ) { chain[i].pos = p; p = p + chain[i].size; if ( !chain[i].empty ) p += spacer+extra; } }
/* This is the main workhorse of the QGridLayout. It portions out available space to the chain's children. The calculation is done in fixed point: "fixed" variables are scaled by a factor of 256. If the layout runs "backwards" (i.e. RightToLeft or Up) the layout is computed mirror-reversed, and it's the caller's responsibility do reverse the values before use. chain contains input and output parameters describing the geometry. count is the count of items in the chain; pos and space give the interval (relative to parentWidget topLeft). */ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count, int pos, int space, int spacer) { int cHint = 0; int cMin = 0; int cMax = 0; int sumStretch = 0; int sumSpacing = 0; bool wannaGrow = false; // anyone who really wants to grow? // bool canShrink = false; // anyone who could be persuaded to shrink? bool allEmptyNonstretch = true; int pendingSpacing = -1; int spacerCount = 0; int i; for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; data->done = false; cHint += data->smartSizeHint(); cMin += data->minimumSize; cMax += data->maximumSize; sumStretch += data->stretch; if (!data->empty) { /* Using pendingSpacing, we ensure that the spacing for the last (non-empty) item is ignored. */ if (pendingSpacing >= 0) { sumSpacing += pendingSpacing; ++spacerCount; } pendingSpacing = data->effectiveSpacer(spacer); } wannaGrow = wannaGrow || data->expansive || data->stretch > 0; allEmptyNonstretch = allEmptyNonstretch && !wannaGrow && data->empty; } int extraspace = 0; if (space < cMin + sumSpacing) { /* Less space than minimumSize; take from the biggest first */ int minSize = cMin + sumSpacing; // shrink the spacers proportionally if (spacer >= 0) { spacer = minSize > 0 ? spacer * space / minSize : 0; sumSpacing = spacer * spacerCount; } QList<int> list; for (i = start; i < start + count; i++) list << chain.at(i).minimumSize; qSort(list); int space_left = space - sumSpacing; int sum = 0; int idx = 0; int space_used=0; int current = 0; while (idx < count && space_used < space_left) { current = list.at(idx); space_used = sum + current * (count - idx); sum += current; ++idx; } --idx; int deficit = space_used - space_left; int items = count - idx; /* * If we truncate all items to "current", we would get "deficit" too many pixels. Therefore, we have to remove * deficit/items from each item bigger than maxval. The actual value to remove is deficitPerItem + remainder/items * "rest" is the accumulated error from using integer arithmetic. */ int deficitPerItem = deficit/items; int remainder = deficit % items; int maxval = current - deficitPerItem; int rest = 0; for (i = start; i < start + count; i++) { int maxv = maxval; rest += remainder; if (rest >= items) { maxv--; rest-=items; } QLayoutStruct *data = &chain[i]; data->size = qMin(data->minimumSize, maxv); data->done = true; } } else if (space < cHint + sumSpacing) { /* Less space than smartSizeHint(), but more than minimumSize. Currently take space equally from each, as in Qt 2.x. Commented-out lines will give more space to stretchier items. */ int n = count; int space_left = space - sumSpacing; int overdraft = cHint - space_left; // first give to the fixed ones: for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; if (!data->done && data->minimumSize >= data->smartSizeHint()) { data->size = data->smartSizeHint(); data->done = true; space_left -= data->smartSizeHint(); // sumStretch -= data->stretch; n--; } } bool finished = n == 0; while (!finished) { finished = true; Fixed64 fp_over = toFixed(overdraft); Fixed64 fp_w = 0; for (i = start; i < start+count; i++) { QLayoutStruct *data = &chain[i]; if (data->done) continue; // if (sumStretch <= 0) fp_w += fp_over / n; // else // fp_w += (fp_over * data->stretch) / sumStretch; int w = fRound(fp_w); data->size = data->smartSizeHint() - w; fp_w -= toFixed(w); // give the difference to the next if (data->size < data->minimumSize) { data->done = true; data->size = data->minimumSize; finished = false; overdraft -= data->smartSizeHint() - data->minimumSize; // sumStretch -= data->stretch; n--; break; } } } } else { // extra space int n = count; int space_left = space - sumSpacing; // first give to the fixed ones, and handle non-expansiveness for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; if (!data->done && (data->maximumSize <= data->smartSizeHint() || (wannaGrow && !data->expansive && data->stretch == 0) || (!allEmptyNonstretch && data->empty && !data->expansive && data->stretch == 0))) { data->size = data->smartSizeHint(); data->done = true; space_left -= data->size; sumStretch -= data->stretch; n--; } } extraspace = space_left; /* Do a trial distribution and calculate how much it is off. If there are more deficit pixels than surplus pixels, give the minimum size items what they need, and repeat. Otherwise give to the maximum size items, and repeat. Paul Olav Tvete has a wonderful mathematical proof of the correctness of this principle, but unfortunately this comment is too small to contain it. */ int surplus, deficit; do { surplus = deficit = 0; Fixed64 fp_space = toFixed(space_left); Fixed64 fp_w = 0; for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; if (data->done) continue; extraspace = 0; if (sumStretch <= 0) fp_w += fp_space / n; else fp_w += (fp_space * data->stretch) / sumStretch; int w = fRound(fp_w); data->size = w; fp_w -= toFixed(w); // give the difference to the next if (w < data->smartSizeHint()) { deficit += data->smartSizeHint() - w; } else if (w > data->maximumSize) { surplus += w - data->maximumSize; } } if (deficit > 0 && surplus <= deficit) { // give to the ones that have too little for (i = start; i < start+count; i++) { QLayoutStruct *data = &chain[i]; if (!data->done && data->size < data->smartSizeHint()) { data->size = data->smartSizeHint(); data->done = true; space_left -= data->smartSizeHint(); sumStretch -= data->stretch; n--; } } } if (surplus > 0 && surplus >= deficit) { // take from the ones that have too much for (i = start; i < start + count; i++) { QLayoutStruct *data = &chain[i]; if (!data->done && data->size > data->maximumSize) { data->size = data->maximumSize; data->done = true; space_left -= data->maximumSize; sumStretch -= data->stretch; n--; } } } } while (n > 0 && surplus != deficit); if (n == 0) extraspace = space_left; } /* As a last resort, we distribute the unwanted space equally among the spacers (counting the start and end of the chain). We could, but don't, attempt a sub-pixel allocation of the extra space. */ int extra = extraspace / (spacerCount + 2); int p = pos + extra; for (i = start; i < start+count; i++) { QLayoutStruct *data = &chain[i]; data->pos = p; p += data->size; if (!data->empty) p += data->effectiveSpacer(spacer) + extra; } #ifdef QLAYOUT_EXTRA_DEBUG qDebug() << "qGeomCalc" << "start" << start << "count" << count << "pos" << pos << "space" << space << "spacer" << spacer; for (i = start; i < start + count; ++i) { qDebug() << i << ":" << chain[i].minimumSize << chain[i].smartSizeHint() << chain[i].maximumSize << "stretch" << chain[i].stretch << "empty" << chain[i].empty << "expansive" << chain[i].expansive << "spacing" << chain[i].spacing; qDebug() << "result pos" << chain[i].pos << "size" << chain[i].size; } #endif }
//! Get the descriptor vector of the provided Ipoint void Surf::getDescriptor() { int y, x, sample_x, sample_y, count=0; float scale, *desc, dx, dy, mdx, mdy, co, si; float gauss, rx, ry, rrx, rry, len=0; Ipoint *ipt = &ipts.at(index); scale = ipt->scale; x = fRound(ipt->x); y = fRound(ipt->y); co = cos(ipt->orientation); si = sin(ipt->orientation); desc = ipt->descriptor; // Calculate descriptor for this interest point for (int i = -10; i < 10; i+=5) { for (int j = -10; j < 10; j+=5) { dx=dy=mdx=mdy=0; for (int k = i; k < i + 5; ++k) { for (int l = j; l < j + 5; ++l) { // Get coords of sample point on the rotated axis sample_x = fRound(x + (-l*scale*si + k*scale*co)); sample_y = fRound(y + ( l*scale*co + k*scale*si)); // Get the gaussian weighted x and y responses gauss = static_cast<float>(gauss33[abs(k)][abs(l)]); rx = gauss * haarX(sample_y, sample_x, 2*fRound(scale)); ry = gauss * haarY(sample_y, sample_x, 2*fRound(scale)); // Get the gaussian weighted x and y responses on rotated axis rrx = -rx*si + ry*co; rry = rx*co + ry*si; dx += rrx; dy += rry; mdx += fabs(rrx); mdy += fabs(rry); } } // add the values to the descriptor vector desc[count++] = dx; desc[count++] = dy; desc[count++] = mdx; desc[count++] = mdy; // store the current length^2 of the vector len += dx*dx + dy*dy + mdx*mdx + mdy*mdy; } } // convert to unit vector len = sqrt(len); for (int i = 0; i < 64; i++) desc[i] /= len; }
//! Assign the supplied Ipoint an orientation void Surf::getOrientation() { Ipoint *ipt = &ipts.at(index); float gauss, scale = ipt->scale; int s = fRound(scale), r = fRound(ipt->y), c = fRound(ipt->x); std::vector<float> resX, resY, Ang; // calculate haar responses for points within radius of 6*scale for (int i = -6; i <= 6; ++i) { for (int j = -6; j <= 6; ++j) { if (i*i + j*j < 36) { gauss = static_cast<float>(gauss25[abs(i)][abs(j)]); resX.push_back( gauss * haarX(r+j*s, c+i*s, 4*s) ); resY.push_back( gauss * haarY(r+j*s, c+i*s, 4*s) ); Ang.push_back(getAngle(resX.back(), resY.back())); } } } // calculate the dominant direction float sumX, sumY; float max=0, old_max = 0, orientation = 0, old_orientation = 0; float ang1, ang2, ang; // loop slides pi/3 window around feature point for (ang1 = 0; ang1 < 2*pi; ang1+=0.15f) { ang2 = ( ang1+pi/3.0f > 2*pi ? ang1-5.0f*pi/3.0f : ang1+pi/3.0f); sumX = sumY = 0; for (unsigned int k = 0; k < Ang.size(); k++) { // get angle from the x-axis of the sample point ang = Ang.at(k); // determine whether the point is within the window if (ang1 < ang2 && ang1 < ang && ang < ang2) { sumX+=resX.at(k); sumY+=resY.at(k); } else if (ang2 < ang1 && ((ang > 0 && ang < ang2) || (ang > ang1 && ang < 2*pi) )) { sumX+=resX.at(k); sumY+=resY.at(k); } } // if the vector produced from this window is longer than all // previous vectors then this forms the new dominant direction if (sumX*sumX + sumY*sumY > max) { // store largest orientation max = sumX*sumX + sumY*sumY; orientation = getAngle(sumX, sumY); } } // assign orientation of the dominant response vector ipt->orientation = orientation; }
IT("tries to cast lazy expressions to booleans") initializeGlobals(); expr = newExpressionLaz(newExpressionStr(newString(strDup("-10")))); result = castToBoo(expr); SHOULD_EQUAL(result->ev.intval, 1) freeExpr(result); freeExpr(expr); freeGlobals(); END_IT END_DESCRIBE DESCRIBE(fRound, "expression* fRound (double result, int digits)") expression* expr; IT("rounds floats to integers") expr = fRound(101.3, -1); SHOULD_EQUAL(expr->ev.intval, 101) freeExpr(expr); expr = fRound(34.5, -1); SHOULD_EQUAL(expr->ev.intval, 34) freeExpr(expr); expr = fRound(35.5, -1); SHOULD_EQUAL(expr->ev.intval, 36) freeExpr(expr); END_IT IT("rounds floats to arbitrary precisions") expr = fRound(203.45, 1); SHOULD_EQUAL(expr->ev.floval, 203.4) freeExpr(expr); expr = fRound(-0.5689, 3);
//! Assign the supplied Ipoint an orientation void Surf::getOrientation() { Ipoint *ipt = &ipts[index]; float gauss = 0.f, scale = ipt->scale; const int s = fRound(scale), r = fRound(ipt->y), c = fRound(ipt->x); std::vector<float> resX(109), resY(109), Ang(109); const int id[] = {6,5,4,3,2,1,0,1,2,3,4,5,6}; int idx = 0; // calculate haar responses for points within radius of 6*scale for(int i = -6; i <= 6; ++i) { for(int j = -6; j <= 6; ++j) { if(i*i + j*j < 36) { gauss = static_cast<float>(gauss25[id[i+6]][id[j+6]]); resX[idx] = gauss * haarX(r+j*s, c+i*s, 4*s); resY[idx] = gauss * haarY(r+j*s, c+i*s, 4*s); Ang[idx] = getAngle(resX[idx], resY[idx]); ++idx; } } } // calculate the dominant direction float sumX=0.f, sumY=0.f; float max=0.f, orientation = 0.f; float ang1=0.f, ang2=0.f; // loop slides pi/3 window around feature point for(ang1 = 0; ang1 < 2*pi; ang1+=0.15f) { ang2 = ( ang1+pi/3.0f > 2*pi ? ang1-5.0f*pi/3.0f : ang1+pi/3.0f); sumX = sumY = 0.f; for(unsigned int k = 0; k < Ang.size(); ++k) { // get angle from the x-axis of the sample point const float & ang = Ang[k]; // determine whether the point is within the window if (ang1 < ang2 && ang1 < ang && ang < ang2) { sumX+=resX[k]; sumY+=resY[k]; } else if (ang2 < ang1 && ((ang > 0 && ang < ang2) || (ang > ang1 && ang < 2*pi) )) { sumX+=resX[k]; sumY+=resY[k]; } } // if the vector produced from this window is longer than all // previous vectors then this forms the new dominant direction if (sumX*sumX + sumY*sumY > max) { // store largest orientation max = sumX*sumX + sumY*sumY; orientation = getAngle(sumX, sumY); } } // assign orientation of the dominant response vector ipt->orientation = orientation; }
//! Get the modified descriptor. See Agrawal ECCV 08 //! Modified descriptor contributed by Pablo Fernandez void Surf::getDescriptor(bool bUpright) { int y, x, sample_x, sample_y, count=0; int i = 0, ix = 0, j = 0, jx = 0, xs = 0, ys = 0; float scale, *desc, dx, dy, mdx, mdy, co, si; float gauss_s1 = 0.f, gauss_s2 = 0.f; float rx = 0.f, ry = 0.f, rrx = 0.f, rry = 0.f, len = 0.f; float cx = -0.5f, cy = 0.f; //Subregion centers for the 4x4 gaussian weighting Ipoint *ipt = &ipts[index]; scale = ipt->scale; x = fRound(ipt->x); y = fRound(ipt->y); desc = ipt->descriptor; if (bUpright) { co = 1; si = 0; } else { co = cos(ipt->orientation); si = sin(ipt->orientation); } i = -8; //Calculate descriptor for this interest point while(i < 12) { j = -8; i = i-4; cx += 1.f; cy = -0.5f; while(j < 12) { dx=dy=mdx=mdy=0.f; cy += 1.f; j = j - 4; ix = i + 5; jx = j + 5; xs = fRound(x + ( -jx*scale*si + ix*scale*co)); ys = fRound(y + ( jx*scale*co + ix*scale*si)); for (int k = i; k < i + 9; ++k) { for (int l = j; l < j + 9; ++l) { //Get coords of sample point on the rotated axis sample_x = fRound(x + (-l*scale*si + k*scale*co)); sample_y = fRound(y + ( l*scale*co + k*scale*si)); //Get the gaussian weighted x and y responses gauss_s1 = gaussian(xs-sample_x,ys-sample_y,2.5f*scale); rx = haarX(sample_y, sample_x, 2*fRound(scale)); ry = haarY(sample_y, sample_x, 2*fRound(scale)); //Get the gaussian weighted x and y responses on rotated axis rrx = gauss_s1*(-rx*si + ry*co); rry = gauss_s1*(rx*co + ry*si); dx += rrx; dy += rry; mdx += fabs(rrx); mdy += fabs(rry); } } //Add the values to the descriptor vector gauss_s2 = gaussian(cx-2.0f,cy-2.0f,1.5f); desc[count++] = dx*gauss_s2; desc[count++] = dy*gauss_s2; desc[count++] = mdx*gauss_s2; desc[count++] = mdy*gauss_s2; len += (dx*dx + dy*dy + mdx*mdx + mdy*mdy) * gauss_s2*gauss_s2; j += 9; } i += 9; } //Convert to Unit Vector len = sqrt(len); for(int i = 0; i < 64; ++i) desc[i] /= len; }
void SURF::eval(unsigned char *in, float *out, int xres, int yres,float scale,float orientation) { img = in; float co,si; this->xres = xres; this->yres = yres; co = cos(orientation); si = sin(orientation); #pragma omp parallel for for(int y = 0; y < yres; y ++) { int sample_x, sample_y, count; int i, ix, j, jx, xs, ys; #ifdef SURF_128 float dx1, dx2, dx3, dx4, dy1, dy2, dy3, dy4; #else float dx, dy, mdx, mdy; #endif float gauss_s1, gauss_s2; float rx, ry, rrx, rry, len; float cx,cy; //Subregion centers for the 4x4 gaussian weighting for(int x = 0; x < xres; x ++) { #ifdef SURF_128 float *desc = out+(x+y*xres)*128; #else float *desc = out+(x+y*xres)*64; #endif count = 0; len = 0; cx = -0.5f; i = -8; //Calculate descriptor while(i < 12) { j = -8; i = i-4; cx += 1.f; cy = -0.5f; while(j < 12) { #ifdef SURF_128 dx1 = dx2 = dx3 = dx4 = dy1 = dy2 = dy3 = dy4 = 0.f; #else dx=dy=mdx=mdy=0.f; #endif cy += 1.f; j = j - 4; ix = i + 5; jx = j + 5; xs = fRound(x + ( -jx*scale*si + ix*scale*co)); ys = fRound(y + ( jx*scale*co + ix*scale*si)); for (int k = i; k < i + 9; ++k) { for (int l = j; l < j + 9; ++l) { //Get coords of sample point on the rotated axis sample_x = fRound(x + (-l*scale*si + k*scale*co)); sample_y = fRound(y + ( l*scale*co + k*scale*si)); //Get the gaussian weighted x and y responses gauss_s1 = gaussian(xs-sample_x,ys-sample_y,2.5f*scale); rx = haarX(sample_y, sample_x, 2*fRound(scale)); ry = haarY(sample_y, sample_x, 2*fRound(scale)); //Get the gaussian weighted x and y responses on rotated axis rrx = gauss_s1*(-rx*si + ry*co); rry = gauss_s1*(rx*co + ry*si); #ifdef SURF_128 if(rry > 0) if(rrx > 0) { dx1 += rrx; dy1 += rry; } else { dx2 -= rrx; dy2 += rry; } else if(rrx < 0) { dx3 -= rrx; dy3 -= rry; } else { dx4 += rrx; dy4 -= rry; } #else dx += rrx; dy += rry; mdx += fabs(rrx); mdy += fabs(rry); #endif } } //Add the values to the descriptor vector gauss_s2 = gaussian(cx-2.0f,cy-2.0f,1.5f); #ifdef SURF_128 desc[count++] = dx1*gauss_s2; desc[count++] = dy1*gauss_s2; desc[count++] = dx2*gauss_s2; desc[count++] = dy2*gauss_s2; desc[count++] = dx3*gauss_s2; desc[count++] = dy3*gauss_s2; desc[count++] = dx4*gauss_s2; desc[count++] = dy4*gauss_s2; len += (dx1*dx1 + dy1*dy1 + dx2*dx2 + dy2*dy2 + dx3*dx3 + dy3*dy3 + dx4*dx4 + dy4*dy4 ) * gauss_s2*gauss_s2; #else desc[count++] = dx*gauss_s2; desc[count++] = dy*gauss_s2; desc[count++] = mdx*gauss_s2; desc[count++] = mdy*gauss_s2; len += (dx*dx + dy*dy + mdx*mdx + mdy*mdy) * gauss_s2*gauss_s2; #endif j += 9; } i += 9; } //Convert to Unit Vector len = sqrt(len); #ifdef SURF_128 for(int i = 0; i < 128; ++i) #else for(int i = 0; i < 64; ++i) #endif desc[i] /= len; } } }