示例#1
0
int vsReadLocalMotionsFile(FILE* f, VSManyLocalMotions* mlms){
  int version = vsReadFileVersion(f);
  if(version<1) // old format or unknown
    return VS_ERROR;
  if(version>1){
    vs_log_error(modname,"Version of VID.STAB file too large: got %i, expect <= 1",
                 version);
    return VS_ERROR;
  }
  assert(mlms);
  // initial number of frames, but it will automatically be increaseed
  vs_vector_init(mlms,1024);
  int index;
  int oldindex = 0;
  LocalMotions lms;
  while((index = vsReadFromFile(f,&lms)) != VS_ERROR){
    if(index > oldindex+1){
      vs_log_info(modname,"VID.STAB file: index of frames is not continuous %i -< %i",
                  oldindex, index);
    }
    if(index<1){
      vs_log_info(modname,"VID.STAB file: Frame number < 1 (%i)", index);
    } else {
      vs_vector_set_dup(mlms,index-1,&lms, sizeof(LocalMotions));
    }
    oldindex=index;
  }
  return VS_OK;
}
示例#2
0
Transform simpleMotionsToTransform(TransformData* td,
                                   const LocalMotions* motions){
  int center_x = 0;
  int center_y = 0;
	Transform t = null_transform();
  if(motions==0) return t;
  int num_motions=vs_vector_size(motions);
  double *angles = (double*) vs_malloc(sizeof(double) * num_motions);
  LocalMotion meanmotion;
  int i;
  if(num_motions < 1)
    return t;

  // calc center point of all remaining fields
  for (i = 0; i < num_motions; i++) {
    center_x += LMGet(motions,i)->f.x;
    center_y += LMGet(motions,i)->f.y;
  }
  center_x /= num_motions;
  center_y /= num_motions;

  // cleaned mean
  meanmotion = cleanmean_localmotions(motions);

  // figure out angle
  if (num_motions < 6) {
    // the angle calculation is inaccurate for 5 and less fields
    t.alpha = 0;
  } else {
    for (i = 0; i < num_motions; i++) {
      // substract avg and calc angle
      LocalMotion m = sub_localmotion(LMGet(motions,i),&meanmotion);
      angles[i] = calcAngle(&m, center_x, center_y);
    }
    double min, max;
    t.alpha = -cleanmean(angles, num_motions, &min, &max);
    if (max - min > td->maxAngleVariation) {
      t.alpha = 0;
      vs_log_info(td->modName, "too large variation in angle(%f)\n",
		  max-min);
    }
  }
  vs_free(angles);
  // compensate for off-center rotation
  double p_x = (center_x - td->fiSrc.width / 2);
  double p_y = (center_y - td->fiSrc.height / 2);
  t.x = meanmotion.v.x + (cos(t.alpha) - 1) * p_x - sin(t.alpha) * p_y;
  t.y = meanmotion.v.y + sin(t.alpha) * p_x + (cos(t.alpha) - 1) * p_y;

  return t;
}
示例#3
0
int vsMotionDetectInit(VSMotionDetect* md, const VSMotionDetectConfig* conf, const VSFrameInfo* fi){
  assert(md && fi);
  md->conf = *conf;
  md->fi = *fi;

  if(fi->pFormat<=PF_NONE ||  fi->pFormat==PF_PACKED || fi->pFormat>=PF_NUMBER) {
    vs_log_warn(md->conf.modName, "unsupported Pixel Format (%i)\n",
                md->fi.pFormat);
    return VS_ERROR;
  }

#ifdef USE_OMP
  if(md->conf.numThreads==0)
    md->conf.numThreads=VS_MAX(omp_get_max_threads()*0.8,1);
  vs_log_info(md->conf.modName, "Multitheading: use %i threads\n",md->conf.numThreads);
#endif

  vsFrameAllocate(&md->prev, &md->fi);
  if (vsFrameIsNull(&md->prev)) {
    vs_log_error(md->conf.modName, "malloc failed");
    return VS_ERROR;
  }

  vsFrameNull(&md->curr);
  vsFrameNull(&md->currorig);
  vsFrameNull(&md->currtmp);
  md->hasSeenOneFrame = 0;
  md->frameNum = 0;

  // TODO: get rid of shakiness parameter in the long run
  md->conf.shakiness = VS_MIN(10,VS_MAX(1,md->conf.shakiness));
  md->conf.accuracy = VS_MIN(15,VS_MAX(1,md->conf.accuracy));
  if (md->conf.accuracy < md->conf.shakiness / 2) {
    vs_log_info(md->conf.modName, "Accuracy should not be lower than shakiness/2 -- fixed");
    md->conf.accuracy = md->conf.shakiness / 2;
  }
  if (md->conf.accuracy > 9 && md->conf.stepSize > 6) {
    vs_log_info(md->conf.modName, "For high accuracy use lower stepsize  -- set to 6 now");
    md->conf.stepSize = 6; // maybe 4
  }

  int minDimension = VS_MIN(md->fi.width, md->fi.height);
//  shift: shakiness 1: height/40; 10: height/4
//  md->maxShift = VS_MAX(4,(minDimension*md->conf.shakiness)/40);
//  size: shakiness 1: height/40; 10: height/6 (clipped)
//  md->fieldSize = VS_MAX(4,VS_MIN(minDimension/6, (minDimension*md->conf.shakiness)/40));

  // fixed size and shift now
  int maxShift      = VS_MAX(16, minDimension/7);
  int fieldSize     = VS_MAX(16, minDimension/10);
  int fieldSizeFine = VS_MAX(6, minDimension/60);
#if defined(USE_SSE2) || defined(USE_SSE2_ASM)
  fieldSize     = (fieldSize / 16 + 1) * 16;
  fieldSizeFine = (fieldSizeFine / 16 + 1) * 16;
#endif
  if (!initFields(md, &md->fieldscoarse, fieldSize, maxShift, md->conf.stepSize,
                  1, 0, md->conf.contrastThreshold)) {
    return VS_ERROR;
  }
  // for the fine check we use a smaller size and smaller maximal shift (=size)
  if (!initFields(md, &md->fieldsfine, fieldSizeFine, fieldSizeFine,
                  2, 1, fieldSizeFine, md->conf.contrastThreshold/2)) {
    return VS_ERROR;
  }

  vsFrameAllocate(&md->curr,&md->fi);
  vsFrameAllocate(&md->currtmp, &md->fi);

  md->initialized = 2;
  return VS_OK;
}