tensorflow/tools/android/test/jni/object_tracking/image_neon.cc
// Puts the image gradient matrix about a pixel into the 2x2 float array G.
// vals_x should be an array of the window x gradient values, whose indices
// can be in any order but are parallel to the vals_y entries.
// See http://robots.stanford.edu/cs223b04/algo_tracking.pdf for more details.
Puts the image gradient matrix about a pixel into the 2x2 float array G.
vals_x should be an array of the window x gradient values, whose indices
can be in any order but are parallel to the vals_y entries.
Puts the image gradient matrix about a pixel into the 2x2 float array G . vals_x should be an array of the window x gradient values whose indices can be in any order but are parallel to the vals_y entries .
void CalculateGNeon(const float* const vals_x, const float* const vals_y,
                    const int num_vals, float* const G) {
  const float32_t* const arm_vals_x = (const float32_t*) vals_x;
  const float32_t* const arm_vals_y = (const float32_t*) vals_y;
  float32x4_t xx = vdupq_n_f32(0.0f);
  float32x4_t xy = vdupq_n_f32(0.0f);
  float32x4_t yy = vdupq_n_f32(0.0f);
  const int max_i = num_vals - 4;
  int i = 0;
  for (; i <= max_i; i += 4) {
    float32x4_t x = vld1q_f32(arm_vals_x + i);
    xx = vmlaq_f32(xx, x, x);
    float32x4_t y = vld1q_f32(arm_vals_y + i);
    xy = vmlaq_f32(xy, x, y);
    yy = vmlaq_f32(yy, y, y);
  }
  static float32_t xx_vals[4];
  static float32_t xy_vals[4];
  static float32_t yy_vals[4];
  vst1q_f32(xx_vals, xx);
  vst1q_f32(xy_vals, xy);
  vst1q_f32(yy_vals, yy);
  for (int j = 0; j < 4; ++j) {
    G[0] += xx_vals[j];
    G[1] += xy_vals[j];
    G[3] += yy_vals[j];
  }
  for (; i < num_vals; ++i) {
    G[0] += Square(vals_x[i]);
    G[1] += vals_x[i] * vals_y[i];
    G[3] += Square(vals_y[i]);
  }
  G[2] = G[1];
}
void CalculateGNeon ( const float * const vals_x , const float * const vals_y , const int num_vals , float * const G ) { const float32_t * const arm_vals_x = ( const float32_t * ) vals_x ; const float32_t * const arm_vals_y = ( const float32_t * ) vals_y ; float32x4_t xx = vdupq_n_f32 ( 0.0f ) ; float32x4_t xy = vdupq_n_f32 ( 0.0f ) ; float32x4_t yy = vdupq_n_f32 ( 0.0f ) ; const int max_i = num_vals - 4 ; int i = 0 ; for ( ; i <= max_i ; i += 4 ) { float32x4_t x = vld1q_f32 ( arm_vals_x + i ) ; xx = vmlaq_f32 ( xx , x , x ) ; float32x4_t y = vld1q_f32 ( arm_vals_y + i ) ; xy = vmlaq_f32 ( xy , x , y ) ; yy = vmlaq_f32 ( yy , y , y ) ; } static float32_t xx_vals [ 4 ] ; static float32_t xy_vals [ 4 ] ; static float32_t yy_vals [ 4 ] ; vst1q_f32 ( xx_vals , xx ) ; vst1q_f32 ( xy_vals , xy ) ; vst1q_f32 ( yy_vals , yy ) ; for ( int j = 0 ; j < 4 ; ++ j ) { G [ 0 ] += xx_vals [ j ] ; G [ 1 ] += xy_vals [ j ] ; G [ 3 ] += yy_vals [ j ] ; } for ( ; i < num_vals ; ++ i ) { G [ 0 ] += Square ( vals_x [ i ] ) ; G [ 1 ] += vals_x [ i ] * vals_y [ i ] ; G [ 3 ] += Square ( vals_y [ i ] ) ; } G [ 2 ] = G [ 1 ] ; }
Puts the image gradient matrix about a pixel into the 2x2 float array G.
vals_x should be an array of the window x gradient values, whose indices
can be in any order but are parallel to the vals_y entries.
Puts the image gradient matrix about a pixel into the 2x2 float array G . vals_x should be an array of the window x gradient values whose indices can be in any order but are parallel to the vals_y entries .
// Running sums. // Maximum index we can load 4 consecutive values from. // e.g. if there are 81 values, our last full pass can be from index 77: // 81-4=>77 (77, 78, 79, 80) // Defined here because we want to keep track of how many values were // processed by NEON, so that we can finish off the remainder the normal // way. // Process values 4 at a time, accumulating the sums of // the pixel-wise x*x, x*y, and y*y values. // Load xs // Multiply x*x and accumulate. // Load ys // Multiply x*y and accumulate. // Multiply y*y and accumulate. // Accumulated values are store in sets of 4, we have to manually add // the last bits together. // Finishes off last few values (< 4) from above. // The matrix is symmetric, so this is a given.