Beispiel #1
0
inline
void
reaccum_moments(accum &A, int *t, int n)
{
  clear_accum(A);
  for(int i=0; i<n; i++)
      accum_moment(A, RAPID_moment[t[i]]);
}
int SelTempAvgMain::process_buffer(VFrame *frame,
		int64_t start_position,
		double frame_rate)
{
	int h = frame->get_h();
	int w = frame->get_w();
	int color_model = frame->get_color_model();
	load_configuration();

// Allocate accumulation
	if(!accumulation)
	{
		accumulation = new unsigned char[w * 
						 h * 
						 BC_CModels::components(color_model) *
						 sizeof(float)];

		accumulation_sq = new unsigned char[w * 
						    h *
						    3 *
						    sizeof(float)];
		clear_accum(w, h, color_model);
	}

	if(!config.nosubtract)
	{
// Reallocate history
		if(history)
		{
			if(config.frames != history_size)
			{
				VFrame **history2;
				int64_t *history_frame2;
				int *history_valid2;
				history2 = new VFrame*[config.frames];
				history_frame2 = new int64_t[config.frames];
				history_valid2 = new int[config.frames];

// Copy existing frames over
				int i, j;
				for(i = 0, j = 0; i < config.frames && j < history_size; i++, j++)
				{
					history2[i] = history[j];
					history_frame2[i] = history_frame[i];
					history_valid2[i] = history_valid[i];
				}

// Delete extra previous frames and subtract from accumulation
				for( ; j < history_size; j++)
				{
					subtract_accum(history[j]);
					delete history[j];
				}
				delete [] history;
				delete [] history_frame;
				delete [] history_valid;


// Create new frames
				for( ; i < config.frames; i++)
				{
					history2[i] = new VFrame(0, -1, w, h, color_model, -1);
					history_frame2[i] = -0x7fffffff;
					history_valid2[i] = 0;
				}

				history = history2;
				history_frame = history_frame2;
				history_valid = history_valid2;

				history_size = config.frames;
			}
		}
		else
// Allocate history
		{
			history = new VFrame*[config.frames];
			for(int i = 0; i < config.frames; i++)
				history[i] = new VFrame(0, -1, w, h, color_model, -1);
			history_size = config.frames;
			history_frame = new int64_t[config.frames];
			bzero(history_frame, sizeof(int64_t) * config.frames);
			history_valid = new int[config.frames];
			bzero(history_valid, sizeof(int) * config.frames);
		}






// Create new history frames based on current frame
		int64_t *new_history_frames = new int64_t[history_size];

		int64_t theoffset = (int64_t) config.offset_fixed_value;
		if (config.offsetmode == SelTempAvgConfig::OFFSETMODE_RESTARTMARKERSYS)
			theoffset = (int64_t) restartoffset;

		for(int i = 0; i < history_size; i++)
		{
			new_history_frames[history_size - i - 1] = start_position + theoffset + i;
		}

// Subtract old history frames which are not in the new vector
		int no_change = 1;
		for(int i = 0; i < history_size; i++)
		{
// Old frame is valid
			if(history_valid[i])
			{
				int got_it = 0;
				for(int j = 0; j < history_size; j++)
				{
// Old frame is equal to a new frame
					if(history_frame[i] == new_history_frames[j]) 
					{
						got_it = 1;
						break;
					}
				}

// Didn't find old frame in new frames
				if(!got_it)
				{
					subtract_accum(history[i]);
					history_valid[i] = 0;
					no_change = 0;
				}
			}
		}
// If all frames are still valid, assume tweek occurred upstream and reload.
		if(config.paranoid && no_change)
		{
			for(int i = 0; i < history_size; i++)
			{
				history_valid[i] = 0;
			}
			clear_accum(w, h, color_model);
		}

// Add new history frames which are not in the old vector
		for(int i = 0; i < history_size; i++)
		{
// Find new frame in old vector
			int got_it = 0;
			for(int j = 0; j < history_size; j++)
			{
				if(history_valid[j] && history_frame[j] == new_history_frames[i])
				{
					got_it = 1;
					break;
				}
			}

// Didn't find new frame in old vector
			if(!got_it)
			{
// Get first unused entry
				for(int j = 0; j < history_size; j++)
				{
					if(!history_valid[j])
					{
// Load new frame into it
						history_frame[j] = new_history_frames[i];
						history_valid[j] = 1;
						read_frame(history[j],
							0,
							history_frame[j],
							frame_rate);
						add_accum(history[j]);
						break;
					}
				}
			}
		}
		delete [] new_history_frames;
	}
	else
// No subtraction
	{
// Force reload if not repositioned or just started
		if(config.paranoid && prev_frame == start_position ||
			prev_frame < 0)
		{
			prev_frame = start_position - config.frames + 1;
			prev_frame = MAX(0, prev_frame);
			clear_accum(w, h, color_model);
		}

		for(int64_t i = prev_frame; i <= start_position; i++)
		{
			read_frame(frame,
				0,
				i,
				frame_rate);
			add_accum(frame);
//printf("SelTempAvgMain::process_buffer 1 %lld %lld %lld\n", prev_frame, start_position, i);
		}

		prev_frame = start_position;
	}



	// Read current frame into buffer (needed for the std-deviation tool)
	read_frame(frame,
			0,
			start_position,
			frame_rate);


// Transfer accumulation to output with division if average is desired.
	transfer_accum(frame);

//printf("SelTempAvgMain::process_buffer 2\n");


	return 0;
}
Beispiel #3
0
int
box::split_recurse(int *t, int n)
{
  // The orientation for the parent box is already assigned to this->pR.
  // The axis along which to split will be column 0 of this->pR.
  // The mean point is passed in on this->pT.

  // When this routine completes, the position and orientation in model
  // space will be established, as well as its dimensions.  Child boxes
  // will be constructed and placed in the parent's CS.

  if (n == 1)
    {
      return split_recurse(t);
    }
  
  // walk along the tris for the box, and do the following:
  //   1. collect the max and min of the vertices along the axes of <or>.
  //   2. decide which group the triangle goes in, performing appropriate swap.
  //   3. accumulate the mean point and covariance data for that triangle.

  accum M1, M2;
  double C[3][3];
  double c[3];
  double minval[3], maxval[3];

  int rc;   // for return code on procedure calls.
  int in;
  tri *ptr;
  int i;
  double axdmp;
  int n1 = 0;  // The number of tris in group 1.  
  // Group 2 will have n - n1 tris.

  // project approximate mean point onto splitting axis, and get coord.
  axdmp = (pR[0][0] * pT[0] + pR[1][0] * pT[1] + pR[2][0] * pT[2]);

  clear_accum(M1);
  clear_accum(M2);

  MTxV(c, pR, RAPID_tri[t[0]].p1);
  minval[0] = maxval[0] = c[0];
  minval[1] = maxval[1] = c[1];
  minval[2] = maxval[2] = c[2];
  for(i=0; i<n; i++)
    {
      in = t[i];
      ptr = RAPID_tri + in;
      
      MTxV(c, pR, ptr->p1);
      minmax(minval[0], maxval[0], c[0]);
      minmax(minval[1], maxval[1], c[1]);
      minmax(minval[2], maxval[2], c[2]);

      MTxV(c, pR, ptr->p2);
      minmax(minval[0], maxval[0], c[0]);
      minmax(minval[1], maxval[1], c[1]);
      minmax(minval[2], maxval[2], c[2]);

      MTxV(c, pR, ptr->p3);
      minmax(minval[0], maxval[0], c[0]);
      minmax(minval[1], maxval[1], c[1]);
      minmax(minval[2], maxval[2], c[2]);

      // grab the mean point of the in'th triangle, project
      // it onto the splitting axis (1st column of pR) and
      // see where it lies with respect to axdmp.
      mean_from_moment(c, RAPID_moment[in]);
      
      if (((pR[0][0]*c[0] + pR[1][0]*c[1] + pR[2][0]*c[2]) < axdmp)
	  && ((n!=2)) || ((n==2) && (i==0)))    
	{
	  // accumulate first and second order moments for group 1
	  accum_moment(M1, RAPID_moment[in]);

	  // put it in group 1 by swapping t[i] with t[n1]
	  int temp = t[i];
	  t[i] = t[n1];
	  t[n1] = temp;
	  n1++;
	}
      else
	{
	  // accumulate first and second order moments for group 2
	  accum_moment(M2, RAPID_moment[in]);

	  // leave it in group 2
	  // do nothing...it happens by default
	}
    }

  // done using this->pT as a mean point.


  // error check!
  if ((n1 == 0) || (n1 == n))
    {
      // our partitioning has failed: all the triangles fell into just
      // one of the groups.  So, we arbitrarily partition them into
      // equal parts, and proceed.

      n1 = n/2;
      
      // now recompute accumulated stuff
      reaccum_moments(M1, t, n1);
      reaccum_moments(M2, t + n1, n - n1);
    }

  // With the max and min data, determine the center point and dimensions
  // of the parent box.

  c[0] = (minval[0] + maxval[0])*0.5;
  c[1] = (minval[1] + maxval[1])*0.5;
  c[2] = (minval[2] + maxval[2])*0.5;

  pT[0] = c[0] * pR[0][0] + c[1] * pR[0][1] + c[2] * pR[0][2];
  pT[1] = c[0] * pR[1][0] + c[1] * pR[1][1] + c[2] * pR[1][2];
  pT[2] = c[0] * pR[2][0] + c[1] * pR[2][1] + c[2] * pR[2][2];
  d[0] = (maxval[0] - minval[0])*0.5;
  d[1] = (maxval[1] - minval[1])*0.5;
  d[2] = (maxval[2] - minval[2])*0.5;

  // allocate new boxes
  P = RAPID_boxes + RAPID_boxes_inited++;
  N = RAPID_boxes + RAPID_boxes_inited++;

  // Compute the orienations for the child boxes (eigenvectors of
  // covariance matrix).  Select the direction of maximum spread to be
  // the split axis for each child.
  
  double tR[3][3];

  if (n1 > 1)
    {
      mean_from_accum(P->pT, M1);
      covariance_from_accum(C, M1);

      if (eigen_and_sort1(tR, C) > 30)
	{
	  // unable to find an orientation.  We'll just pick identity.
	  Midentity(tR);
	}

      McM(P->pR, tR);
      if ((rc = P->split_recurse(t, n1)) != RAPID_OK) return rc;
    }
  else
    {
      if ((rc = P->split_recurse(t)) != RAPID_OK) return rc;
    }
  McM(C, P->pR);  MTxM(P->pR, pR, C);   // and F1
  VmV(c, P->pT, pT);  MTxV(P->pT, pR, c);

  if ((n-n1) > 1)
    {      
      mean_from_accum(N->pT, M2);
      covariance_from_accum (C, M2);

      if (eigen_and_sort1(tR, C) > 30)
	{
	  // unable to find an orientation.  We'll just pick identity.
	  Midentity(tR);
	}
      
      McM(N->pR, tR);
      if ((rc = N->split_recurse(t + n1, n - n1)) != RAPID_OK) return rc;
    }
  else
    {
      if ((rc = N->split_recurse(t+n1)) != RAPID_OK) return rc;
    }
  McM(C, N->pR); MTxM(N->pR, pR, C);
  VmV(c, N->pT, pT);  MTxV(N->pT, pR, c);  

  return RAPID_OK;
}
Beispiel #4
0
int
RAPID_model::build_hierarchy()
{
  // allocate the boxes and set the box list globals

  num_boxes_alloced = num_tris * 2;
  b = new box[num_boxes_alloced];
  if (b == 0) return RAPID_ERR_MODEL_OUT_OF_MEMORY;
  RAPID_boxes = b;
  RAPID_boxes_inited = 1;   // we are in process of initializing b[0].
  
  // Determine initial orientation, mean point, and splitting axis.

  int i; 
  accum M;
  
  //  double F1[3];
  //  double S1[6];
  double C[3][3];
  
  RAPID_moment = new moment[num_tris]; 
  if (RAPID_moment == 0)
    {
      delete [] b;
      return RAPID_ERR_MODEL_OUT_OF_MEMORY;
    }
  compute_moments(RAPID_moment, tris, num_tris);

  clear_accum(M);  
  for(i=0; i<num_tris; i++)
    accum_moment(M, RAPID_moment[i]);
  
  mean_from_accum(b[0].pT, M);
  covariance_from_accum(C, M);
  
  eigen_and_sort1(b[0].pR, C);

  // create the index list
  int *t = new int[num_tris];
  if (t == 0)
    {
      delete [] b;
      delete [] RAPID_moment;
      return RAPID_ERR_MODEL_OUT_OF_MEMORY;
    }
  for(i=0; i<num_tris; i++) t[i] = i;

  // set the tri pointer
  RAPID_tri = tris;
  
  // do the build
  int rc = b[0].split_recurse(t, num_tris);
  if (rc != RAPID_OK)
    {
      delete [] b;
      delete [] RAPID_moment;
      delete [] t;
      return RAPID_ERR_MODEL_OUT_OF_MEMORY;
    }
  
  // free the moment list
  delete [] RAPID_moment;  RAPID_moment = 0;

  // null the tri pointer
  RAPID_tri = 0;
  
  // free the index list
  delete [] t;

  return RAPID_OK;
}
Beispiel #5
0
int
build_recurse(PQP_Model *m, int bn, int first_tri, int num_tris)
{
  BV *b = m->child(bn);

  // compute a rotation matrix

  PQP_REAL C[3][3], E[3][3], R[3][3], s[3], axis[3], mean[3], coord;

#if RAPID2_FIT
  moment *tri_moment = new moment[num_tris];
  compute_moments(tri_moment, &(m->tris[first_tri]), num_tris);  
  accum acc;
  clear_accum(acc);
  for(int i = 0; i < num_tris; i++) accum_moment(acc, tri_moment[i]);
  delete [] tri_moment;
  covariance_from_accum(C,acc);
#else
  get_covariance_triverts(C,&m->tris[first_tri],num_tris);
#endif

  Meigen(E, s, C);

  // place axes of E in order of increasing s

  int min, mid, max;
  if (s[0] > s[1]) { max = 0; min = 1; }
  else { min = 0; max = 1; }
  if (s[2] < s[min]) { mid = min; min = 2; }
  else if (s[2] > s[max]) { mid = max; max = 2; }
  else { mid = 2; }
  McolcMcol(R,0,E,max);
  McolcMcol(R,1,E,mid);
  R[0][2] = E[1][max]*E[2][mid] - E[1][mid]*E[2][max];
  R[1][2] = E[0][mid]*E[2][max] - E[0][max]*E[2][mid];
  R[2][2] = E[0][max]*E[1][mid] - E[0][mid]*E[1][max];

  // fit the BV

  b->FitToTris(R, &m->tris[first_tri], num_tris);

  if (num_tris == 1)
  {
    // BV is a leaf BV - first_child will index a triangle

    b->first_child = -(first_tri + 1);
  }
  else if (num_tris > 1)
  {
    // BV not a leaf - first_child will index a BV

    b->first_child = m->num_bvs;
    m->num_bvs+=2;

    // choose splitting axis and splitting coord

    McolcV(axis,R,0);

#if RAPID2_FIT
    mean_from_accum(mean,acc);
#else
    get_centroid_triverts(mean,&m->tris[first_tri],num_tris);
#endif
    coord = VdotV(axis, mean);

    // now split

    int num_first_half = split_tris(&m->tris[first_tri], num_tris, 
                                    axis, coord);

    // recursively build the children

    build_recurse(m, m->child(bn)->first_child, first_tri, num_first_half); 
    build_recurse(m, m->child(bn)->first_child + 1,
                  first_tri + num_first_half, num_tris - num_first_half); 
  }
  return PQP_OK;
}