Example #1
0
VL_EXPORT
int vl_pgm_write_f (char const *name, float const* data, int width, int height)
{
  int err = 0 ;
  int k ;
  float min = + VL_INFINITY_F ;
  float max = - VL_INFINITY_F ;
  float scale ;

  vl_uint8 * buffer = (vl_uint8*)vl_malloc (sizeof(float) * width * height) ;

  for (k = 0 ; k < width * height ; ++k) {
    min = VL_MIN(min, data [k]) ;
    max = VL_MAX(max, data [k]) ;
  }

  scale = 255 / (max - min + VL_EPSILON_F) ;

  for (k = 0 ; k < width * height ; ++k) {
    buffer [k] = (vl_uint8) ((data [k] - min) * scale) ;
  }

  err = vl_pgm_write (name, buffer, width, height) ;

  vl_free (buffer) ;
  return err ;
}
Example #2
0
static void
_vl_scalespace_start_octave_from_previous_octave (VlScaleSpace *self, vl_index o)
{
  double sigma, prevSigma ;
  float *level, *prevLevel ;
  vl_index prevLevelIndex ;
  VlScaleSpaceOctaveGeometry ogeom ;

  assert(self) ;
  assert(o > self->geom.firstOctave) ; /* must not be the first octave */
  assert(o <= self->geom.lastOctave) ;

  /*
   * From the previous octave pick the level which is closer to
   * self->geom.octaveFirstSubdivision in this octave.
   * The is self->geom.octaveFirstSubdivision + self->numLevels since there are
   * self->geom.octaveResolution levels in an octave, provided that
   * this value does not exceed self->geom.octaveLastSubdivision.
   */

  prevLevelIndex = VL_MIN(self->geom.octaveFirstSubdivision
                          + (signed)self->geom.octaveResolution,
                          self->geom.octaveLastSubdivision) ;
  prevLevel = vl_scalespace_get_level (self, o - 1, prevLevelIndex) ;
  level = vl_scalespace_get_level (self, o, self->geom.octaveFirstSubdivision) ;
  ogeom = vl_scalespace_get_octave_geometry(self, o - 1) ;

  copy_and_downsample (level, prevLevel, ogeom.width, ogeom.height, 1) ;

  /*
   * Add remaining smoothing, if any.
   */

  sigma = vl_scalespace_get_level_sigma(self, o, self->geom.octaveFirstSubdivision) ;
  prevSigma = vl_scalespace_get_level_sigma(self, o - 1, prevLevelIndex) ;

  if (sigma > prevSigma) {
    VlScaleSpaceOctaveGeometry ogeom = vl_scalespace_get_octave_geometry(self, o) ;
    double deltaSigma = sqrt (sigma*sigma - prevSigma*prevSigma) ;
    level = vl_scalespace_get_level (self, o, self->geom.octaveFirstSubdivision) ;

    /* todo: this may fail due to an out-of-memory condition */
    vl_imsmooth_f (level, ogeom.width,
                   level, ogeom.width, ogeom.height, ogeom.width,
                   deltaSigma / ogeom.step, deltaSigma / ogeom.step) ;
  }
}
Example #3
0
VlScaleSpaceGeometry
vl_scalespace_get_default_geometry (vl_size width, vl_size height)
{
  VlScaleSpaceGeometry geom ;
  assert(width >= 1) ;
  assert(height >= 1) ;
  geom.width = width ;
  geom.height = height ;
  geom.firstOctave = 0 ;
  geom.lastOctave = VL_MAX(floor(vl_log2_d(VL_MIN(width, height))) - 3, 0) ;
  geom.octaveResolution= 3 ;
  geom.octaveFirstSubdivision = 0 ;
  geom.octaveLastSubdivision = geom.octaveResolution - 1 ;
  geom.baseScale = 1.6 * pow(2.0, 1.0 / geom.octaveResolution) ;
  geom.nominalScale = 0.5 ;
  return geom ;
}
Example #4
0
vl_bool CHIKMTree::vl_hikm_train(const vl_ikm_data *data, vl_uint32 N)
{
	//char fileName[MAX_PATH];
	//sprintf(fileName, "%s\\index\\info_train.txt", m_WorkSpace);
	//FILE* file = fopen(fileName, "wb");
	//if (!file) {
	//	return 0;
	//}

	m_VlHIKMTree->root = xmeans (m_VlHIKMTree, data, N, VL_MIN(m_VlHIKMTree->K, N), m_VlHIKMTree->depth, NULL);
	if (!m_VlHIKMTree->root) {
		return FALSE;
	}
	//fclose(file);

	return TRUE;
}
Example #5
0
static VlHIKMNode * 
xmeans (VlHIKMTree *tree, 
        vl_uint8 const *data, 
        int N, int K, int height)
{
  VlHIKMNode *node = vl_malloc (sizeof(VlHIKMNode)) ;
  vl_uint     *ids = vl_malloc (sizeof(vl_uint) * N) ;

  node-> filter   = vl_ikm_new (tree -> method) ;    
  node-> children = (height == 1) ? 0 : vl_malloc (sizeof(VlHIKMNode*) * K) ;

  vl_ikm_set_max_niters (node->filter, tree->max_niters) ;
  vl_ikm_set_verbosity  (node->filter, tree->verb - 1  ) ;
  vl_ikm_init_rand_data (node->filter, data, tree->M, N, K) ;
  vl_ikm_train          (node->filter, data, N) ;
  vl_ikm_push           (node->filter, ids, data, N) ;
  
  /* recurse for each child */
  if (height > 1) {
    int k ;
    for (k = 0 ; k < K ; k ++) {
      int partition_N ;
      int partition_K ;
      vl_uint8 *partition ;
      
      partition = vl_hikm_copy_subset
        (data, ids, N, tree->M, k, &partition_N) ;
      
      partition_K = VL_MIN (K, partition_N) ;
      
      node->children [k] = xmeans
        (tree, partition, partition_N, partition_K, height - 1) ;
      
      vl_free (partition) ;

      if (tree->verb > tree->depth - height) {
        VL_PRINTF("hikmeans: branch at depth %d: %6.1f %% completed\n", 
                  tree->depth - height,
                  (double) (k+1) / K * 100) ;
      }
    }
  }
  
  vl_free (ids) ;
  return node ;
}
Example #6
0
VL_EXPORT
int
vl_string_copy (char *dst, int n, char const *src)
{

  char c ;
  int  k = 0 ;
    
  while (( c = *src++ )) {
    if (dst && k < n - 1) dst [k] = c ;
    ++ k ;
  }

  /* finalize */
  if (n > 0) dst [VL_MIN(k, n - 1)] = 0 ;
  return  k ;
}
Example #7
0
VL_EXPORT
int
vl_string_copy_sub (char *dst, int n, 
                    char const *beg,
                    char const *end)
{
  char c ;
  int  k = 0 ;

  while (beg < end && (c = *beg++)) {
    if (dst && k < n - 1) dst [k] = c ;
    ++ k ;
  }

  /* finalize */
  if (n > 0) dst [VL_MIN(k, n - 1)] = 0 ;
  return  k ;
}
Example #8
0
VL_EXPORT VlKDForest *
vl_kdforest_new (vl_type dataType,
                 vl_size dimension, vl_size numTrees)
{
  VlKDForest * self = vl_malloc (sizeof(VlKDForest)) ;

  assert(dataType == VL_TYPE_FLOAT || dataType == VL_TYPE_DOUBLE) ;
  assert(dimension >= 1) ;
  assert(numTrees >= 1) ;

  self -> rand = vl_get_rand () ;
  self -> dataType = dataType ;
  self -> numData = 0 ;
  self -> data = 0 ;
  self -> dimension = dimension ;
  self -> numTrees = numTrees ;
  self -> trees = 0 ;
  self -> thresholdingMethod = VL_KDTREE_MEDIAN ;
  self -> splitHeapSize = VL_MIN(numTrees, VL_KDTREE_SPLIT_HEAP_SIZE) ;
  self -> splitHeapNumNodes = 0 ;

  self -> searchHeapArray = 0 ;
  self -> searchHeapNumNodes = 0 ;

  self -> searchMaxNumComparisons = 0 ;
  self -> searchIdBook = 0 ;
  self -> searchId = 0 ;

  switch (self->dataType) {
    case VL_TYPE_FLOAT:
      self -> distanceFunction = (void(*)(void))
      vl_get_vector_comparison_function_f (VlDistanceL2) ;
      break ;
    case VL_TYPE_DOUBLE :
      self -> distanceFunction = (void(*)(void))
      vl_get_vector_comparison_function_d (VlDistanceL2) ;
      break ;
    default :
      abort() ;
  }

  return self ;
}
Example #9
0
static VlHIKMNode * xmeans (VlHIKMTree *tree, const vl_ikm_data *data, vl_uint32 N, vl_uint32 K, vl_uint32 height, FILE* file)
{
	VlHIKMNode *node = (VlHIKMNode*)malloc (sizeof(VlHIKMNode)) ;
	vl_uint32  *ids  = (vl_uint32*) malloc (sizeof(vl_uint32) * N);

	node-> filter   =  new CIKMTree(); 
	node-> children = (height == 1) ? NULL : (VlHIKMNode**)malloc(sizeof(VlHIKMNode*) * K) ;

	node->filter->vl_ikm_new_tree();
	node->filter->vl_ikm_set_max_niters(tree->max_niters);
	node->filter->vl_ikm_set_verbosity (1) ;
	node->filter->vl_ikm_init_rand_data(data, tree->M, N, K);
	node->filter->vl_ikm_train(data, N, file) ;
	node->filter->vl_ikm_push (ids, data, N) ;

	/* recurse for each child */
	if (height > 1) {

		for (vl_uint32 k = 0 ; k < K ; k ++) {
			vl_uint32		partition_N ;
			vl_uint32		partition_K ;
			vl_ikm_data *	partition ;

			partition = vl_hikm_copy_subset(data, ids, N, tree->M, k, &partition_N) ;

			partition_K = VL_MIN (K, partition_N);

			node->children [k] = xmeans(tree, partition, partition_N, partition_K, height - 1, file) ;

			free (partition) ;

			/*  print some information */
			if (tree->verb > (int)tree->depth - (int)height && file) {
				fprintf(file, "hikmeans: branch at depth %d: %6.1f %% completed\n", 
					tree->depth - height, (double) (k+1) / K * 100) ;
				fflush(file);
			}
		}
	}
	free (ids) ;
	return node ;
}
Example #10
0
VL_EXPORT
int
vl_string_replace_wildcard (char *dst, int n, 
                            char const *src, 
                            char wild, 
                            char esc,
                            char const *repl)
{
  char    c ;
  int     k = 0 ;
  vl_bool escape = 0 ;

  while (( c = *src++ )) {
    
    /* enter escape mode ? */
    if (! escape && c == esc) {
      escape = 1 ;
      continue ;
    }

    /* wildcard or regular? */
    if (! escape && c == wild) {
      char const *repl_ = repl ;
      while (( c = *repl_++ )) {
        if (dst && k < n - 1) dst [k]  = c ;
        ++ k ;
      }
    }
    /* regular character */
    else {
      if (dst && k < n - 1) dst [k] = c ;
      ++ k ;
    }

    escape = 0 ;
  }

  /* add trailing 0 */
  if (n > 0) dst [VL_MIN(k, n - 1)] = 0 ;
  return  k ;
}
Example #11
0
VL_EXPORT void
VL_XCAT(vl_pegasos_train_binary_svm_,SFX)(T *  model,
                                          T const * data,
                                          vl_size dimension,
                                          vl_size numSamples,
                                          vl_int8 const * labels,
                                          double regularizer,
                                          double biasMultiplier,
                                          vl_uindex startingIteration,
                                          vl_size numIterations,
                                          VlRand * randomGenerator)
{
  vl_uindex iteration ;
  vl_uindex i ;
  T const * x ;
  T acc, eta, y, scale = 1 ;
  double lambda = regularizer ;
  double sqrtLambda = sqrt(lambda) ;


#if (FLT == VL_TYPE_FLOAT)
  VlFloatVectorComparisonFunction dotFn =
#else
  VlDoubleVectorComparisonFunction dotFn =
#endif
  VL_XCAT(vl_get_vector_comparison_function_,SFX)(VlKernelL2) ;

  if (randomGenerator == NULL) randomGenerator = vl_get_rand() ;

  assert(startingIteration >= 1) ;

  /*
     The model is stored as scale*model[]. When a sample does not violate
     the margin, only scale needs to be updated.
   */

  for (iteration = startingIteration ;
       iteration < startingIteration + numIterations ;
       ++ iteration) {
    /* pick a sample  */
    vl_uindex k = vl_rand_uindex(randomGenerator, numSamples) ;
    x = data + dimension * k ;
    y = labels[k] ;

    /* project on the weight vector */
    acc = dotFn(dimension, x, model) ;
    if (biasMultiplier) acc += biasMultiplier * model[dimension] ;
    acc *= scale ;

    /* learning rate */
    eta = 1.0 / (iteration * lambda) ;

    if (y * acc < (T) 1.0) {
      /* margin violated */
      T a = scale * (1 - eta * lambda)  ;
      T b = y * eta ;

      acc = 0 ;
      for (i = 0 ; i < dimension ; ++i) {
        model[i] = a * model[i] + b * x[i] ;
        acc += model[i] * model[i] ;
      }
      if (biasMultiplier) {
        model[dimension] = a * model[dimension] + b * biasMultiplier ;
        acc += model[dimension] * model[dimension] ;
      }
      scale = VL_MIN((T)1.0 / (sqrtLambda * sqrt(acc + VL_EPSILON_D)), (T)1.0) ;
    } else {
      /* margin not violated */
      scale *= 1 - eta * lambda ;
    }
  }

  /* denormalize representation */
  for (i = 0 ; i < dimension + (biasMultiplier ? 1 : 0) ; ++i) {
    model[i] *= scale ;
  }
}
Example #12
0
VL_EXPORT
void
vl_hikm_train (VlHIKMTree *f, vl_uint8 const *data, int N)
{
  f -> root  = xmeans (f, data, N, VL_MIN(f->K, N), f->depth) ;
}
void
vl_slic_segment (vl_uint32 * segmentation,
                 float const * image,
                 vl_size width,
                 vl_size height,
                 vl_size numChannels,
                 vl_size regionSize,
                 float regularization,
                 vl_size minRegionSize)
{

  vl_index i, x, y, u, v, k, region ;
  vl_uindex iter ;
  vl_size const numRegionsX = (vl_size) ceil((double) width / regionSize) ;
  vl_size const numRegionsY = (vl_size) ceil((double) height / regionSize) ;
  vl_size const numRegions = numRegionsX * numRegionsY ;
  vl_size const numPixels = width * height ;
  float * centers ;
  float * edgeMap ;
  float previousEnergy = VL_INFINITY_F ;
  float startingEnergy ;
  vl_uint32 * masses ;
  vl_size const maxNumIterations = 100 ;

  assert(segmentation) ;
  assert(image) ;
  assert(width >= 1) ;
  assert(height >= 1) ;
  assert(numChannels >= 1) ;
  assert(regionSize >= 1) ;
  assert(regularization >= 0) ;

#define atimage(x,y,k) image[(x)+(y)*width+(k)*width*height]
#define atEdgeMap(x,y) edgeMap[(x)+(y)*width]

  edgeMap = vl_calloc(numPixels, sizeof(float)) ;
  masses = vl_malloc(sizeof(vl_uint32) * numPixels) ;
  centers = vl_malloc(sizeof(float) * (2 + numChannels) * numRegions) ;

  /* compute edge map (gradient strength) */
  for (k = 0 ; k < (signed)numChannels ; ++k) {
    for (y = 1 ; y < (signed)height-1 ; ++y) {
      for (x = 1 ; x < (signed)width-1 ; ++x) {
        float a = atimage(x-1,y,k) ;
        float b = atimage(x+1,y,k) ;
        float c = atimage(x,y+1,k) ;
        float d = atimage(x,y-1,k) ;
        atEdgeMap(x,y) += (a - b)  * (a - b) + (c - d) * (c - d) ;
      }
    }
  }

  /* initialize K-means centers */
  i = 0 ;
  for (v = 0 ; v < (signed)numRegionsY ; ++v) {
    for (u = 0 ; u < (signed)numRegionsX ; ++u) {
      vl_index xp ;
      vl_index yp ;
      vl_index centerx = 0 ;
      vl_index centery = 0 ;
      float minEdgeValue = VL_INFINITY_F ;

      x = (vl_index) vl_round_d(regionSize * (u + 0.5)) ;
      y = (vl_index) vl_round_d(regionSize * (v + 0.5)) ;

      x = VL_MAX(VL_MIN(x, (signed)width-1),0) ;
      y = VL_MAX(VL_MIN(y, (signed)height-1),0) ;

      /* search in a 3x3 neighbourhood the smallest edge response */
      for (yp = VL_MAX(0, y-1) ; yp <= VL_MIN((signed)height-1, y+1) ; ++ yp) {
        for (xp = VL_MAX(0, x-1) ; xp <= VL_MIN((signed)width-1, x+1) ; ++ xp) {
          float thisEdgeValue = atEdgeMap(xp,yp) ;
          if (thisEdgeValue < minEdgeValue) {
            minEdgeValue = thisEdgeValue ;
            centerx = xp ;
            centery = yp ;
          }
        }
      }

      /* initialize the new center at this location */
      centers[i++] = (float) centerx ;
      centers[i++] = (float) centery ;
      for (k  = 0 ; k < (signed)numChannels ; ++k) {
        centers[i++] = atimage(centerx,centery,k) ;
      }
    }
  }

  /* run k-means iterations */
  for (iter = 0 ; iter < maxNumIterations ; ++iter) {
    float factor = regularization / (regionSize * regionSize) ;
    float energy = 0 ;

    /* assign pixels to centers */
    for (y = 0 ; y < (signed)height ; ++y) {
      for (x = 0 ; x < (signed)width ; ++x) {
        vl_index u = floor((double)x / regionSize - 0.5) ;
        vl_index v = floor((double)y / regionSize - 0.5) ;
        vl_index up, vp ;
        float minDistance = VL_INFINITY_F ;

        for (vp = VL_MAX(0, v) ; vp <= VL_MIN((signed)numRegionsY-1, v+1) ; ++vp) {
          for (up = VL_MAX(0, u) ; up <= VL_MIN((signed)numRegionsX-1, u+1) ; ++up) {
            vl_index region = up  + vp * numRegionsX ;
            float centerx = centers[(2 + numChannels) * region + 0]  ;
            float centery = centers[(2 + numChannels) * region + 1] ;
            float spatial = (x - centerx) * (x - centerx) + (y - centery) * (y - centery) ;
            float appearance = 0 ;
            float distance ;
            for (k = 0 ; k < (signed)numChannels ; ++k) {
              float centerz = centers[(2 + numChannels) * region + k + 2]  ;
              float z = atimage(x,y,k) ;
              appearance += (z - centerz) * (z - centerz) ;
            }

            distance = appearance + factor * spatial ;
            if (minDistance > distance) {
              minDistance = distance ;
              segmentation[x + y * width] = (vl_uint32)region ;
            }
          }
        }
        energy += minDistance ;
      }
    }

    /*
      VL_PRINTF("vl:slic: iter %d: energy: %g\n", iter, energy) ;
    */

    /* check energy termination conditions */
    if (iter == 0) {
      startingEnergy = energy ;
    } else {
      if ((previousEnergy - energy) < 1e-5 * (startingEnergy - energy)) {
        break ;
      }
    }
    previousEnergy = energy ;

    /* recompute centers */
    memset(masses, 0, sizeof(vl_uint32) * width * height) ;
    memset(centers, 0, sizeof(float) * (2 + numChannels) * numRegions) ;

    for (y = 0 ; y < (signed)height ; ++y) {
      for (x = 0 ; x < (signed)width ; ++x) {
        vl_index pixel = x + y * width ;
        vl_index region = segmentation[pixel] ;
        masses[region] ++ ;
        centers[region * (2 + numChannels) + 0] += x ;
        centers[region * (2 + numChannels) + 1] += y ;
        for (k = 0 ; k < (signed)numChannels ; ++k) {
          centers[region * (2 + numChannels) + k + 2] += atimage(x,y,k) ;
        }
      }
    }

    for (region = 0 ; region < (signed)numRegions ; ++region) {
      float mass = VL_MAX(masses[region], 1e-8) ;
      for (i = (2 + numChannels) * region ;
           i < (signed)(2 + numChannels) * (region + 1) ;
           ++i) {
        centers[i] /= mass ;
      }
    }
  }

  vl_free(masses) ;
  vl_free(centers) ;
  vl_free(edgeMap) ;

  /* elimiate small regions */
  {
    vl_uint32 * cleaned = vl_calloc(numPixels, sizeof(vl_uint32)) ;
    vl_uindex * segment = vl_malloc(sizeof(vl_uindex) * numPixels) ;
    vl_size segmentSize ;
    vl_uint32 label ;
    vl_uint32 cleanedLabel ;
    vl_size numExpanded ;
    vl_index const dx [] = {+1, -1,  0,  0} ;
    vl_index const dy [] = { 0,  0, +1, -1} ;
    vl_index direction ;
    vl_index pixel ;

    for (pixel = 0 ; pixel < (signed)numPixels ; ++pixel) {
      if (cleaned[pixel]) continue ;
      label = segmentation[pixel] ;
      numExpanded = 0 ;
      segmentSize = 0 ;
      segment[segmentSize++] = pixel ;

      /*
    	find cleanedLabel as the label of an already cleaned
    	region neighbor of this pixel
      */
      cleanedLabel = label + 1 ;
      cleaned[pixel] = label + 1 ;
      x = pixel % width ;
      y = pixel / width ;
      for (direction = 0 ; direction < 4 ; ++direction) {
        vl_index xp = x + dx[direction] ;
        vl_index yp = y + dy[direction] ;
        vl_index neighbor = xp + yp * width ;
        if (0 <= xp && xp < (signed)width &&
            0 <= yp && yp < (signed)height &&
            cleaned[neighbor]) {
          cleanedLabel = cleaned[neighbor] ;
        }
      }

      /* expand the segment */
      while (numExpanded < segmentSize) {
        vl_index open = segment[numExpanded++] ;
        x = open % width ;
        y = open / width ;
        for (direction = 0 ; direction < 4 ; ++direction) {
          vl_index xp = x + dx[direction] ;
          vl_index yp = y + dy[direction] ;
          vl_index neighbor = xp + yp * width ;
          if (0 <= xp && xp < (signed)width &&
              0 <= yp && yp < (signed)height &&
              cleaned[neighbor] == 0 &&
              segmentation[neighbor] == label) {
            cleaned[neighbor] = label + 1 ;
            segment[segmentSize++] = neighbor ;
          }
        }
      }

      /* change label to cleanedLabel if the segment is too small */
      if (segmentSize < minRegionSize) {
        while (segmentSize > 0) {
          cleaned[segment[--segmentSize]] = cleanedLabel ;
        }
      }
    }
    /* restore base 0 indexing of the regions */
    for (pixel = 0 ; pixel < (signed)numPixels ; ++pixel) cleaned[pixel] -- ;

    memcpy(segmentation, cleaned, numPixels * sizeof(vl_uint32)) ;
    vl_free(cleaned) ;
    vl_free(segment) ;
  }
}
Example #14
0
vector<vector<float> > Encoder::extractMultiDSIFT(Mat normMat, Mat landmarks, int level){
	vector<vector<float> > ret;
	//hard code max LBP size
	int tunedCellSize = 10;
	int tunedCols, tunedRows;
	int dimension = patchSize / cellSize;
	vector<float> dsiftCode;
	for (int l = 0; l < level; l++){
		int tmpcellSize = cellSize - l;
		int tmppatchSize = tmpcellSize*dimension;
		for (unsigned int i = 0; i < landmarks.cols; i++){
			if (landmarks.at<float>(0, i) > tmppatchSize/2 && landmarks.at<float>(1, i) > tmppatchSize/2 && landmarks.at<float>(0, i) + tmppatchSize/2 < normMat.cols && landmarks.at<float>(1, i) + tmppatchSize/2 < normMat.rows){
				Mat roi(normMat, Rect(landmarks.at<float>(0, i) - tmppatchSize/2 , landmarks.at<float>(1, i) - tmppatchSize/2, tmppatchSize, tmppatchSize));
				vector<float> data;
				for (int j = 0; j < roi.cols; j++){
					for (int k = 0; k < roi.rows; k++){
						data.push_back((float)roi.at<unsigned char>(k, j)/255);
					}
				}
				//dsift
				int numFrames ;
				int descrSize ;
				VlDsiftKeypoint const *frames ;
				float const *descrs ;
				VlDsiftFilter *dsift ;
				VlDsiftDescriptorGeometry geom ;
				geom.numBinX = 2 ;
				geom.numBinY = 2 ;
				geom.numBinT = 4 ;
				geom.binSizeX = 4 ;
				geom.binSizeY = 4 ;
				dsift = vl_dsift_new (roi.rows, roi.cols) ;
				vl_dsift_set_geometry(dsift, &geom) ;
				vl_dsift_set_steps(dsift, 2, 2) ;
				vl_dsift_set_flat_window(dsift, 1) ;
				numFrames = vl_dsift_get_keypoint_num (dsift) ;
				descrSize = vl_dsift_get_descriptor_size (dsift) ;
				geom = *vl_dsift_get_geometry (dsift) ;
				vl_dsift_process (dsift, &data[0]) ;
				frames = vl_dsift_get_keypoints (dsift) ;
				descrs = vl_dsift_get_descriptors (dsift) ;	
				//cout<<"frames: "<<numFrames<<" descrs: "<<descrSize<<" cols: "<<roi.cols<<" rows: "<<roi.rows<<endl;
				float tranDescr[128];
				for (int f = 0; f < numFrames; f++){
					vl_dsift_transpose_descriptor (tranDescr, descrs + descrSize * f, geom.numBinT, geom.numBinX, geom.numBinY) ;
					for (int d = 0 ; d < descrSize ; d++) {
						tranDescr[d] = VL_MIN(512.0F * tranDescr[d], 255.0F) ;
						dsiftCode.push_back(tranDescr[d]);
						//cout<<tmpDescr[i]<<" ";
					}
				}
				//if (i != 0 && i != 2){
					ret.push_back(dsiftCode);
					dsiftCode.clear();			
				//}
				 vl_dsift_delete (dsift) ;
			}
			else{
				cout<<"Patch out of bound: "<<landmarks.at<float>(0, i)<<" "<<landmarks.at<float>(1, i)<<endl;
				cout<<"landmark: "<<i<<" Cols: "<<tunedCols<<" Rows: "<<tunedRows<<endl;
				imwrite("tmp/outOfBound.jpg", normMat);
				exit(1);
			}
		}
	}
	return ret;	
}
Example #15
0
File: hog.c Project: CVML/SUN3Dsfm
void
vl_hog_render (VlHog const * self,
               float * image,
               float const * descriptor,
               vl_size width,
               vl_size height)
{
  vl_index x, y, k, cx, cy ;
  vl_size hogStride = width * height ;

  assert(self) ;
  assert(image) ;
  assert(descriptor) ;
  assert(width > 0) ;
  assert(height > 0) ;

  for (y = 0 ; y < (signed)height ; ++y) {
    for (x = 0 ; x < (signed)width ; ++x) {
      float minWeight = 0 ;
      float maxWeight = 0 ;

      for (k = 0 ; k < (signed)self->numOrientations ; ++k) {
        float weight ;
        float const * glyph = self->glyphs + k * (self->glyphSize*self->glyphSize) ;
        float * glyphImage = image + self->glyphSize * x + y * width * (self->glyphSize*self->glyphSize) ;

        switch (self->variant) {
          case VlHogVariantUoctti:
            weight =
            descriptor[k * hogStride] +
            descriptor[(k + self->numOrientations) * hogStride] +
            descriptor[(k + 2 * self->numOrientations) * hogStride] ;
            break ;
          case VlHogVariantDalalTriggs:
            weight =
            descriptor[k * hogStride] +
            descriptor[(k + self->numOrientations) * hogStride] +
            descriptor[(k + 2 * self->numOrientations) * hogStride] +
            descriptor[(k + 3 * self->numOrientations) * hogStride] ;
            break ;
          default:
            abort() ;
        }
        maxWeight = VL_MAX(weight, maxWeight) ;
        minWeight = VL_MIN(weight, minWeight);

        for (cy = 0 ; cy < (signed)self->glyphSize ; ++cy) {
          for (cx = 0 ; cx < (signed)self->glyphSize ; ++cx) {
            *glyphImage++ += weight * (*glyph++) ;
          }
          glyphImage += (width - 1) * self->glyphSize  ;
        }
      } /* next orientation */

      {
        float * glyphImage = image + self->glyphSize * x + y * width * (self->glyphSize*self->glyphSize) ;
        for (cy = 0 ; cy < (signed)self->glyphSize ; ++cy) {
          for (cx = 0 ; cx < (signed)self->glyphSize ; ++cx) {
            float value = *glyphImage ;
            *glyphImage++ = VL_MAX(minWeight, VL_MIN(maxWeight, value)) ;
          }
          glyphImage += (width - 1) * self->glyphSize  ;
        }
      }

      ++ descriptor ;
    } /* next column of cells (x) */
  } /* next row of cells (y) */
}
Example #16
0
static double
VL_XCAT(_vl_kmeans_refine_centers_elkan_, SFX)
(VlKMeans * self,
 TYPE const * data,
 vl_size numData)
{
  vl_size d, iteration, x ;
  vl_uint32 c, j ;
  vl_bool allDone ;
  TYPE * distances = vl_malloc (sizeof(TYPE) * numData) ;
  vl_uint32 * assignments = vl_malloc (sizeof(vl_uint32) * numData) ;
  vl_size * clusterMasses = vl_malloc (sizeof(vl_size) * numData) ;

#if (FLT == VL_TYPE_FLOAT)
    VlFloatVectorComparisonFunction distFn = vl_get_vector_comparison_function_f(self->distance) ;
#else
    VlDoubleVectorComparisonFunction distFn = vl_get_vector_comparison_function_d(self->distance) ;
#endif

  TYPE * nextCenterDistances = vl_malloc (sizeof(TYPE) * self->numCenters) ;
  TYPE * pointToClosestCenterUB = vl_malloc (sizeof(TYPE) * numData) ;
  vl_bool * pointToClosestCenterUBIsStrict = vl_malloc (sizeof(vl_bool) * numData) ;
  TYPE * pointToCenterLB = vl_malloc (sizeof(TYPE) * numData * self->numCenters) ;
  TYPE * newCenters = vl_malloc(sizeof(TYPE) * self->dimension * self->numCenters) ;
  TYPE * centerToNewCenterDistances = vl_malloc (sizeof(TYPE) * self->numCenters) ;

  vl_uint32 * permutations = NULL ;
  vl_size * numSeenSoFar = NULL ;

  double energy ;

  vl_size totDistanceComputationsToInit = 0 ;
  vl_size totDistanceComputationsToRefreshUB = 0 ;
  vl_size totDistanceComputationsToRefreshLB = 0 ;
  vl_size totDistanceComputationsToRefreshCenterDistances = 0 ;
  vl_size totDistanceComputationsToNewCenters = 0 ;
  vl_size totDistanceComputationsToFinalize = 0 ;

  if (self->distance == VlDistanceL1) {
    permutations = vl_malloc(sizeof(vl_uint32) * numData * self->dimension) ;
    numSeenSoFar = vl_malloc(sizeof(vl_size) * self->numCenters) ;
    VL_XCAT(_vl_kmeans_sort_data_helper_, SFX)(self, permutations, data, numData) ;
  }

  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  /*                          Initialization                        */
  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

  /* An iteration is: get_new_centers + reassign + get_energy.
     This counts as iteration 0, where get_new_centers is assumed
     to be performed before calling the train function by
     the initialization function */

  /* update distances between centers */
  totDistanceComputationsToInit +=
  VL_XCAT(_vl_kmeans_update_center_distances_, SFX)(self) ;

  /* assigmen points to the initial centers and initialize bounds */
  memset(pointToCenterLB, 0, sizeof(TYPE) * self->numCenters *  numData) ;
  for (x = 0 ; x < numData ; ++x) {
    TYPE distance ;

    /* do the first center */
    assignments[x] = 0 ;
    distance = distFn(self->dimension,
                      data + x * self->dimension,
                      (TYPE*)self->centers + 0) ;
    pointToClosestCenterUB[x] = distance ;
    pointToClosestCenterUBIsStrict[x] = VL_TRUE ;
    pointToCenterLB[0 + x * self->numCenters] = distance ;
    totDistanceComputationsToInit += 1 ;

    /* do other centers */
    for (c = 1 ; c < self->numCenters ; ++c) {

      /* Can skip if the center assigned so far is twice as close
         as its distance to the center under consideration */

      if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) *
          pointToClosestCenterUB[x] <=
          ((TYPE*)self->centerDistances)
          [c + assignments[x] * self->numCenters]) {
        continue ;
      }

      distance = distFn(self->dimension,
                        data + x * self->dimension,
                        (TYPE*)self->centers + c * self->dimension) ;
      pointToCenterLB[c + x * self->numCenters] = distance ;
      totDistanceComputationsToInit += 1 ;
      if (distance < pointToClosestCenterUB[x]) {
        pointToClosestCenterUB[x] = distance ;
        assignments[x] = c ;
      }
    }
  }

  /* compute UB on energy */
  energy = 0 ;
  for (x = 0 ; x < numData ; ++x) {
    energy += pointToClosestCenterUB[x] ;
  }

  if (self->verbosity) {
    VL_PRINTF("kmeans: Elkan iter 0: energy = %g, dist. calc. = %d\n",
              energy, totDistanceComputationsToInit) ;
  }

/* #define SANITY*/
#ifdef SANITY
  {
    int xx ; int cc ;
    TYPE tol = 1e-5 ;
    VL_PRINTF("inconsistencies after initial assignments:\n");
    for (xx = 0 ; xx < numData ; ++xx) {
      for (cc = 0 ; cc < self->numCenters ; ++cc) {
        TYPE a = pointToCenterLB[cc + xx * self->numCenters] ;
        TYPE b = distFn(self->dimension,
                        data + self->dimension * xx,
                        (TYPE*)self->centers + self->dimension * cc) ;
        if (cc == assignments[xx]) {
          TYPE z = pointToClosestCenterUB[xx] ;
          if (z+tol<b) VL_PRINTF("UB %d %d = %f < %f\n",
                             cc, xx, z, b) ;
        }
        if (a>b+tol) VL_PRINTF("LB %d %d = %f  > %f\n",
                           cc, xx, a, b) ;
      }
    }
  }
#endif

  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  /*                          Iterations                            */
  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

  for (iteration = 1 ; 1; ++iteration) {

    vl_size numDistanceComputationsToRefreshUB = 0 ;
    vl_size numDistanceComputationsToRefreshLB = 0 ;
    vl_size numDistanceComputationsToRefreshCenterDistances = 0 ;
    vl_size numDistanceComputationsToNewCenters = 0 ;

    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    /*                         Compute new centers                  */
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

    memset(clusterMasses, 0, sizeof(vl_size) * numData) ;
    for (x = 0 ; x < numData ; ++x) {
      clusterMasses[assignments[x]] ++ ;
    }

    switch (self->distance) {
      case VlDistanceL2:
        memset(newCenters, 0, sizeof(TYPE) * self->dimension * self->numCenters) ;
        for (x = 0 ; x < numData ; ++x) {
          TYPE * cpt = newCenters + assignments[x] * self->dimension ;
          TYPE const * xpt = data + x * self->dimension ;
          for (d = 0 ; d < self->dimension ; ++d) { cpt[d] += xpt[d] ; }
        }
        for (c = 0 ; c < self->numCenters ; ++c) {
          TYPE mass = clusterMasses[c] ;
          TYPE * cpt = newCenters + c * self->dimension ;
          for (d = 0 ; d < self->dimension ; ++d) { cpt[d] /= mass ; }
        }
        break ;
      case VlDistanceL1:
        for (d = 0 ; d < self->dimension ; ++d) {
          vl_uint32 * perm = permutations + d * numData ;
          memset(numSeenSoFar, 0, sizeof(vl_size) * self->numCenters) ;
          for (x = 0; x < numData ; ++x) {
            c = assignments[perm[x]] ;
            if (2 * numSeenSoFar[c] < clusterMasses[c]) {
              newCenters [d + c * self->dimension] =
              data [d + perm[x] * self->dimension] ;
            }
            numSeenSoFar[c] ++ ;
          }
        }
        break ;
      default:
        abort();
    } /* done compute centers */

    /* compute the distance from the old centers to the new centers */
    for (c = 0 ; c < self->numCenters ; ++c) {
      TYPE distance = distFn(self->dimension,
                             newCenters + c * self->dimension,
                             (TYPE*)self->centers + c * self->dimension) ;
      centerToNewCenterDistances[c] = distance ;
      numDistanceComputationsToNewCenters += 1 ;
    }

    /* make the new centers current */
    {
      TYPE * tmp = self->centers ;
      self->centers = newCenters ;
      newCenters = tmp ;
    }

    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    /*                Reassign points to a centers                  */
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

    /*
     Update distances between centers.
     */
    numDistanceComputationsToRefreshCenterDistances
    += VL_XCAT(_vl_kmeans_update_center_distances_, SFX)(self) ;

    for (c = 0 ; c < self->numCenters ; ++c) {
      nextCenterDistances[c] = (TYPE) VL_INFINITY_D ;
      for (j = 0 ; j < self->numCenters ; ++j) {
        if (j == c) continue ;
        nextCenterDistances[c] = VL_MIN(nextCenterDistances[c],
                                        ((TYPE*)self->centerDistances)
                                        [j + c * self->numCenters]) ;
      }
    }

    /*
     Update upper bounds on point-to-closest-center distances
     based on the center variation.
     */
    for (x = 0 ; x < numData ; ++x) {
      TYPE a = pointToClosestCenterUB[x] ;
      TYPE b = centerToNewCenterDistances[assignments[x]] ;
      if (self->distance == VlDistanceL1) {
        pointToClosestCenterUB[x] = a + b ;
      } else {
#if (FLT == VL_TYPE_FLOAT)
        TYPE sqrtab =  sqrtf (a * b) ;
#else
        TYPE sqrtab =  sqrt (a * b) ;
#endif
        pointToClosestCenterUB[x] = a + b + 2.0 * sqrtab ;
      }
      pointToClosestCenterUBIsStrict[x] = VL_FALSE ;
    }

    /*
     Update lower bounds on point-to-center distances
     based on the center variation.
     */
    for (x = 0 ; x < numData ; ++x) {
      for (c = 0 ; c < self->numCenters ; ++c) {
        TYPE a = pointToCenterLB[c + x * self->numCenters] ;
        TYPE b = centerToNewCenterDistances[c] ;
        if (a < b) {
          pointToCenterLB[c + x * self->numCenters] = 0 ;
        } else {
          if (self->distance == VlDistanceL1) {
             pointToCenterLB[c + x * self->numCenters]  = a - b ;
          } else {
#if (FLT == VL_TYPE_FLOAT)
            TYPE sqrtab =  sqrtf (a * b) ;
#else
            TYPE sqrtab =  sqrt (a * b) ;
#endif
             pointToCenterLB[c + x * self->numCenters]  = a + b - 2.0 * sqrtab ;
          }
        }
      }
    }

   #ifdef SANITY
    {
      int xx ; int cc ;
      TYPE tol = 1e-5 ;
      VL_PRINTF("inconsistencies before assignments:\n");
      for (xx = 0 ; xx < numData ; ++xx) {
        for (cc = 0 ; cc < self->numCenters ; ++cc) {
          TYPE a = pointToCenterLB[cc + xx * self->numCenters] ;
          TYPE b = distFn(self->dimension,
                          data + self->dimension * xx,
                          (TYPE*)self->centers + self->dimension * cc) ;
          if (cc == assignments[xx]) {
            TYPE z = pointToClosestCenterUB[xx] ;
            if (z+tol<b) VL_PRINTF("UB %d %d = %f < %f\n",
                                            cc, xx, z, b) ;
          }
          if (a>b+tol) VL_PRINTF("LB %d %d = %f  > %f (assign = %d)\n",
                                          cc, xx, a, b, assignments[xx]) ;
        }
      }
    }
#endif

    /*
     Scan the data and to the reassignments. Use the bounds to
     skip as many point-to-center distance calculations as possible.
     */
    for (allDone = VL_TRUE, x = 0 ; x < numData ; ++x) {
      /*
       A point x sticks with its current center assignmets[x]
       the UB to d(x, c[assigmnets[x]]) is not larger than half
       the distance of c[assigments[x]] to any other center c.
       */
      if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) *
          pointToClosestCenterUB[x] <= nextCenterDistances[assignments[x]]) {
        continue ;
      }

      for (c = 0 ; c < self->numCenters ; ++c) {
        vl_uint32 cx = assignments[x] ;
        TYPE distance ;

        /* The point is not reassigned to a given center c
         if either:

         0 - c is already the assigned center
         1 - The UB of d(x, c[assignments[x]]) is smaller than half
             the distance of c[assigments[x]] to c, OR
         2 - The UB of d(x, c[assignmets[x]]) is smaller than the
             LB of the distance of x to c.
         */
        if (cx == c) {
          continue ;
        }
        if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) *
            pointToClosestCenterUB[x] <= ((TYPE*)self->centerDistances)
            [c + cx * self->numCenters]) {
          continue ;
        }
        if (pointToClosestCenterUB[x] <= pointToCenterLB
            [c + x * self->numCenters]) {
          continue ;
        }

        /* If the UB is loose, try recomputing it and test again */
        if (! pointToClosestCenterUBIsStrict[x]) {
          distance = distFn(self->dimension,
                            data + self->dimension * x,
                            (TYPE*)self->centers + self->dimension * cx) ;
          pointToClosestCenterUB[x] = distance ;
          pointToClosestCenterUBIsStrict[x] = VL_TRUE ;
          pointToCenterLB[cx + x * self->numCenters] = distance ;
          numDistanceComputationsToRefreshUB += 1 ;

          if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) *
              pointToClosestCenterUB[x] <= ((TYPE*)self->centerDistances)
              [c + cx * self->numCenters]) {
            continue ;
          }
          if (pointToClosestCenterUB[x] <= pointToCenterLB
              [c + x * self->numCenters]) {
            continue ;
          }
        }

        /*
         Now the UB is strict (equal to d(x, assignments[x])), but
         we still could not exclude that x should be reassigned to
         c. We therefore compute the distance, update the LB,
         and check if a reassigmnet must be made
         */
        distance = distFn(self->dimension,
                          data + x * self->dimension,
                          (TYPE*)self->centers + c *  self->dimension) ;
        numDistanceComputationsToRefreshLB += 1 ;
        pointToCenterLB[c + x * self->numCenters] = distance ;

        if (distance < pointToClosestCenterUB[x]) {
          assignments[x] = c ;
          pointToClosestCenterUB[x] = distance ;
          allDone = VL_FALSE ;
          /* the UB strict flag is already set here */
        }

      } /* assign center */
    } /* next data point */

    totDistanceComputationsToRefreshUB
    += numDistanceComputationsToRefreshUB ;

    totDistanceComputationsToRefreshLB
    += numDistanceComputationsToRefreshLB ;

    totDistanceComputationsToRefreshCenterDistances
    += numDistanceComputationsToRefreshCenterDistances ;

    totDistanceComputationsToNewCenters
    += numDistanceComputationsToNewCenters ;

#ifdef SANITY
    {
      int xx ; int cc ;
      TYPE tol = 1e-5 ;
      VL_PRINTF("inconsistencies after assignments:\n");
      for (xx = 0 ; xx < numData ; ++xx) {
        for (cc = 0 ; cc < self->numCenters ; ++cc) {
          TYPE a = pointToCenterLB[cc + xx * self->numCenters] ;
          TYPE b = distFn(self->dimension,
                          data + self->dimension * xx,
                          (TYPE*)self->centers + self->dimension * cc) ;
          if (cc == assignments[xx]) {
            TYPE z = pointToClosestCenterUB[xx] ;
            if (z+tol<b) VL_PRINTF("UB %d %d = %f < %f\n",
                               cc, xx, z, b) ;
          }
          if (a>b+tol) VL_PRINTF("LB %d %d = %f  > %f (assign = %d)\n",
                             cc, xx, a, b, assignments[xx]) ;
        }
      }
    }
#endif

    /* compute UB on energy */
    energy = 0 ;
    for (x = 0 ; x < numData ; ++x) {
      energy += pointToClosestCenterUB[x] ;
    }

    if (self->verbosity) {
      vl_size numDistanceComputations =
      numDistanceComputationsToRefreshUB +
      numDistanceComputationsToRefreshLB +
      numDistanceComputationsToRefreshCenterDistances +
      numDistanceComputationsToNewCenters ;
      VL_PRINTF("kmeans: Elkan iter %d: energy <= %g, dist. calc. = %d\n",
                iteration,
                energy,
                numDistanceComputations) ;
      if (self->verbosity > 1) {
        VL_PRINTF("kmeans: Elkan iter %d: total dist. calc. per type: "
                  "UB: %.1f%% (%d), LB: %.1f%% (%d), "
                  "intra_center: %.1f%% (%d), "
                  "new_center: %.1f%% (%d)\n",
                  iteration,
                  100.0 * numDistanceComputationsToRefreshUB / numDistanceComputations,
                  numDistanceComputationsToRefreshUB,
                  100.0 *numDistanceComputationsToRefreshLB / numDistanceComputations,
                  numDistanceComputationsToRefreshLB,
                  100.0 * numDistanceComputationsToRefreshCenterDistances / numDistanceComputations,
                  numDistanceComputationsToRefreshCenterDistances,
                  100.0 * numDistanceComputationsToNewCenters / numDistanceComputations,
                  numDistanceComputationsToNewCenters) ;
      }
    }

    /* check termination conditions */
    if (iteration >= self->maxNumIterations) {
      if (self->verbosity) {
        VL_PRINTF("kmeans: Elkan terminating because maximum number of iterations reached\n") ;
      }
      break ;
    }
    if (allDone) {
      if (self->verbosity) {
        VL_PRINTF("kmeans: Elkan terminating because the algorithm fully converged\n") ;
      }
      break ;
    }

  } /* next Elkan iteration */


  /* compute true energy */
  energy = 0 ;
  for (x = 0 ; x < numData ; ++ x) {
    vl_uindex cx = assignments [x] ;
    energy += distFn(self->dimension,
                     data + self->dimension * x,
                     (TYPE*)self->centers + self->dimension * cx) ;
    totDistanceComputationsToFinalize += 1 ;
  }

  {
    vl_size totDistanceComputations =
    totDistanceComputationsToInit +
    totDistanceComputationsToRefreshUB +
    totDistanceComputationsToRefreshLB +
    totDistanceComputationsToRefreshCenterDistances +
    totDistanceComputationsToNewCenters +
    totDistanceComputationsToFinalize ;

    double saving = (double)totDistanceComputations
    / (iteration * self->numCenters * numData) ;

    if (self->verbosity) {
      VL_PRINTF("kmeans: Elkan: total dist. calc.: %d (%.2f %% of Lloyd)\n",
                totDistanceComputations, saving * 100.0) ;
    }

    if (self->verbosity > 1) {
      VL_PRINTF("kmeans: Elkan: total dist. calc. per type: "
                "init: %.1f%% (%d), UB: %.1f%% (%d), LB: %.1f%% (%d), "
                "intra_center: %.1f%% (%d), "
                "new_center: %.1f%% (%d), "
                "finalize: %.1f%% (%d)\n",
                100.0 * totDistanceComputationsToInit / totDistanceComputations,
                totDistanceComputationsToInit,
                100.0 * totDistanceComputationsToRefreshUB / totDistanceComputations,
                totDistanceComputationsToRefreshUB,
                100.0 *totDistanceComputationsToRefreshLB / totDistanceComputations,
                totDistanceComputationsToRefreshLB,
                100.0 * totDistanceComputationsToRefreshCenterDistances / totDistanceComputations,
                totDistanceComputationsToRefreshCenterDistances,
                100.0 * totDistanceComputationsToNewCenters / totDistanceComputations,
                totDistanceComputationsToNewCenters,
                100.0 * totDistanceComputationsToFinalize / totDistanceComputations,
                totDistanceComputationsToFinalize) ;
    }
  }

  if (permutations) { vl_free(permutations) ; }
  if (numSeenSoFar) { vl_free(numSeenSoFar) ; }

  vl_free(distances) ;
  vl_free(assignments) ;
  vl_free(clusterMasses) ;

  vl_free(nextCenterDistances) ;
  vl_free(pointToClosestCenterUB) ;
  vl_free(pointToClosestCenterUBIsStrict) ;
  vl_free(pointToCenterLB) ;
  vl_free(newCenters) ;
  vl_free(centerToNewCenterDistances) ;

  return energy ;
}
Example #17
0
/** ------------------------------------------------------------------
 ** @brief Python entry point
 **/
PyObject * vl_dsift_python(
		PyArrayObject & pyArray,
		int opt_step,
		PyArrayObject & opt_bounds,
		int opt_size,
		bool opt_fast,
		bool opt_verbose,
		bool opt_norm)
{
	// check data type
	assert(pyArray.descr->type_num == PyArray_FLOAT);
	assert(pyArray.flags & NPY_FORTRAN);
	assert(opt_bounds.descr->type_num == PyArray_FLOAT);

	int verbose = 0;
	int opt;
	float const *data;
	int M, N;

	int step = 1;
	int size = 3;
	vl_bool norm = 0;

	vl_bool useFlatWindow = VL_FALSE;

	double *bounds = NULL;
	double boundBuffer[4];

	/* -----------------------------------------------------------------
	 *                                               Check the arguments
	 * -------------------------------------------------------------- */
	data = (float*) pyArray.data;
	M = pyArray.dimensions[0];
	N = pyArray.dimensions[1];

	if (opt_verbose)
		++verbose;
	if (opt_fast)
		useFlatWindow = 1;
	if (opt_norm)
		norm = 1;
	if (opt_bounds.nd == 1 && opt_bounds.dimensions[0] == 4) {
		double * tmp = (double *) opt_bounds.data;
		bounds = boundBuffer;
		for (int i = 0; i < 4; i++)
			bounds[i] = tmp[i];
	}
	if (opt_size >= 0)
		size = opt_size;
	if (opt_step >= 0)
		step = opt_step;


	// create PyTuple for outputs
	PyObject * tuple = PyTuple_New(2);

	/* -----------------------------------------------------------------
	 *                                                            Do job
	 * -------------------------------------------------------------- */
	{
		int numFrames;
		int descrSize;
		VlDsiftKeypoint const *frames;
		VlDsiftDescriptorGeometry const *geom;
		float const *descrs;
		int k, i;

		VlDsiftFilter *dsift;
		dsift = vl_dsift_new_basic(M, N, step, size);
		if (bounds) {
			vl_dsift_set_bounds(dsift, VL_MAX(bounds[0], 0), VL_MAX(
				bounds[1], 0), VL_MIN(bounds[2], M - 1), VL_MIN(bounds[3], N
					- 1));
		}
		vl_dsift_set_flat_window(dsift, useFlatWindow);

	    numFrames = vl_dsift_get_keypoint_num (dsift) ;
	    descrSize = vl_dsift_get_descriptor_size (dsift) ;
	    geom = vl_dsift_get_geometry(dsift);

		if (verbose) {
			int stepX;
			int stepY;
			int minX;
			int minY;
			int maxX;
			int maxY;
			vl_bool useFlatWindow;

			vl_dsift_get_steps(dsift, &stepX, &stepY);
			vl_dsift_get_bounds(dsift, &minX, &minY, &maxX, &maxY);
			useFlatWindow = vl_dsift_get_flat_window(dsift);

			printf("dsift: image size:        %d x %d\n", N, M);
			printf(
				"      bounds:            [%d, %d, %d, %d]\n", minY, minX,
				maxY, maxX);
			printf("      subsampling steps: %d, %d\n", stepY, stepX);
			printf(
				"      num bins:          [%d, %d, %d]\n", geom->numBinT,
				geom->numBinX, geom->numBinY);
			printf("      descriptor size:   %d\n", descrSize);
			printf(
				"      bin sizes:         [%d, %d]\n", geom->binSizeX,
				geom->binSizeY);
			printf("      flat window:       %s\n", VL_YESNO(useFlatWindow));
			printf("      number of frames:  %d\n", numFrames);
		}

		vl_dsift_process(dsift, data);

		frames = vl_dsift_get_keypoints(dsift);
		descrs = vl_dsift_get_descriptors(dsift);

		/* ---------------------------------------------------------------
		 *                                            Create output arrays
		 * ------------------------------------------------------------ */
		npy_intp dims[2];

		dims[0] = descrSize;
		dims[1] = numFrames;

		// allocate PyArray objects
		PyArrayObject * _descriptors = (PyArrayObject *) PyArray_NewFromDescr(
			&PyArray_Type, PyArray_DescrFromType(PyArray_UINT8),
			2, dims, NULL, NULL, NPY_F_CONTIGUOUS, NULL);

		if (norm)
			dims[0] = 3;
		else
			dims[0] = 2;

		PyArrayObject * _frames = (PyArrayObject*) PyArray_NewFromDescr(
			&PyArray_Type, PyArray_DescrFromType(PyArray_DOUBLE),
			2, dims, NULL, NULL, NPY_F_CONTIGUOUS, NULL);

		// put PyArray objects in PyTuple
		PyTuple_SetItem(tuple, 0, PyArray_Return(_frames));
		PyTuple_SetItem(tuple, 1, PyArray_Return(_descriptors));

		/* ---------------------------------------------------------------
		 *                                                       Copy back
		 * ------------------------------------------------------------ */
		{
			float *tmpDescr = (float*) vl_malloc(sizeof(float) * descrSize);

			double *outFrameIter = (double*) _frames->data;
			vl_uint8 *outDescrIter = (vl_uint8 *) _descriptors->data;
			for (k = 0; k < numFrames; ++k) {
				*outFrameIter++ = frames[k].y;
				*outFrameIter++ = frames[k].x;

				/* We have an implied / 2 in the norm, because of the clipping
				 below */
				if (norm)
					*outFrameIter++ = frames[k].norm;

				vl_dsift_transpose_descriptor(
					tmpDescr, descrs + descrSize * k, geom->numBinT,
					geom->numBinX, geom->numBinY);

				for (i = 0; i < descrSize; ++i) {
					*outDescrIter++ = (vl_uint8) (VL_MIN(
						512.0F * tmpDescr[i], 255.0F));
				}
			}
			vl_free(tmpDescr);
		}
		vl_dsift_delete(dsift);
	}

	return tuple;
}
Example #18
0
File: hog.c Project: CVML/SUN3Dsfm
void
vl_hog_extract (VlHog * self, float * features)
{
  vl_index x, y ;
  vl_uindex k ;
  vl_size hogStride = self->hogWidth * self->hogHeight ;

  assert(features) ;

#define at(x,y,k) (self->hog[(x) + (y) * self->hogWidth + (k) * hogStride])
#define atNorm(x,y) (self->hogNorm[(x) + (y) * self->hogWidth])

  /*
   Computes the squared L2 norm of each HOG cell. This is the norm of the
   undirected orientation histogram, counting only numOrientations. This
   histogram is obtained by folding the 2*numOrientations directed
   orientations that are computed.
   */
  {
    float const * iter = self->hog ;
    for (k = 0 ; k < self->numOrientations ; ++k) {
      float * niter = self->hogNorm ;
      float * niterEnd = self->hogNorm + self->hogWidth * self->hogHeight ;
      vl_size stride = self->hogWidth*self->hogHeight*self->numOrientations ;
      while (niter != niterEnd) {
        float h1 = *iter ;
        float h2 = *(iter + stride) ;
        float h = h1 + h2 ;
        *niter += h * h ;
        niter++ ;
        iter++ ;
      }
    }
  }

  /*
   HOG block-normalisation. For each cell, there are four 2x2 blocks
   covering it. For example, the cell number 5 in the following scheme
   is covered by the four blocks 1245, 2356, 4578, 5689.

                           +---+---+---+
                           | 1 | 2 | 3 |
                           +---+---+---+
                           | 4 | 5 | 6 |
                           +---+---+---+
                           | 7 | 8 | 9 |
                           +---+---+---+

   In the Dalal-Triggs implementation, one forms all possible 2x2 blocks
   of cells, computes a descriptor vector for each by stacking the corresponding
   2x2 HOG cells, and L2 normalizes (and truncates) the result.

   Thus each HOG cell appears in four blocks. These are then decomposed
   again to produce descriptors for each cell. Each descriptor is simply
   the stacking of the portion of each block descriptor that arised
   from that cell. This process result in a descriptor
   of each cell which contains four copies of the original HOG,
   with four different normalization factors.

   @remark By stacking together the cell descriptors for a large retangular block
   of cells, one effectively stacks together the block descriptors of
   an equal number of blocks (except for the boundaries, for which
   blocks are only partially included). Since blocks are L2 normalized
   (up to truncation), this implies that the L2 norm of the resulting
   vector is approximately equal to the area of the region.

   */
  {
    float const * iter = self->hog ;
    for (y = 0 ; y < (signed)self->hogHeight ; ++y) {
      for (x = 0 ; x < (signed)self->hogWidth ; ++x) {

        /* norm of upper-left, upper-right, ... blocks */
        vl_index xm = VL_MAX(x - 1, 0) ;
        vl_index xp = VL_MIN(x + 1, (signed)self->hogWidth - 1) ;
        vl_index ym = VL_MAX(y - 1, 0) ;
        vl_index yp = VL_MIN(y + 1, (signed)self->hogHeight - 1) ;

        double norm1 = atNorm(xm,ym) ;
        double norm2 = atNorm(x,ym) ;
        double norm3 = atNorm(xp,ym) ;
        double norm4 = atNorm(xm,y) ;
        double norm5 = atNorm(x,y) ;
        double norm6 = atNorm(xp,y) ;
        double norm7 = atNorm(xm,yp) ;
        double norm8 = atNorm(x,yp) ;
        double norm9 = atNorm(xp,yp) ;

        double factor1, factor2, factor3, factor4 ;

		double t1 = 0 ;
		double t2 = 0 ;
        double t3 = 0 ;
        double t4 = 0 ;

		float * oiter = features + x + self->hogWidth * y ;

        /* each factor is the inverse of the l2 norm of one of the 2x2 blocks surrounding
           cell x,y */
#if 0
        if (self->transposed) {
          /* if the image is transposed, y and x are swapped */
          factor1 = 1.0 / VL_MAX(sqrt(norm1 + norm2 + norm4 + norm5), 1e-10) ;
          factor3 = 1.0 / VL_MAX(sqrt(norm2 + norm3 + norm5 + norm6), 1e-10) ;
          factor2 = 1.0 / VL_MAX(sqrt(norm4 + norm5 + norm7 + norm8), 1e-10) ;
          factor4 = 1.0 / VL_MAX(sqrt(norm5 + norm6 + norm8 + norm9), 1e-10) ;
        } else {
          factor1 = 1.0 / VL_MAX(sqrt(norm1 + norm2 + norm4 + norm5), 1e-10) ;
          factor2 = 1.0 / VL_MAX(sqrt(norm2 + norm3 + norm5 + norm6), 1e-10) ;
          factor3 = 1.0 / VL_MAX(sqrt(norm4 + norm5 + norm7 + norm8), 1e-10) ;
          factor4 = 1.0 / VL_MAX(sqrt(norm5 + norm6 + norm8 + norm9), 1e-10) ;
        }
#else
        /* as implemented in UOCTTI code */
        if (self->transposed) {
          /* if the image is transposed, y and x are swapped */
          factor1 = 1.0 / sqrt(norm1 + norm2 + norm4 + norm5 + 1e-4) ;
          factor3 = 1.0 / sqrt(norm2 + norm3 + norm5 + norm6 + 1e-4) ;
          factor2 = 1.0 / sqrt(norm4 + norm5 + norm7 + norm8 + 1e-4) ;
          factor4 = 1.0 / sqrt(norm5 + norm6 + norm8 + norm9 + 1e-4) ;
        } else {
          factor1 = 1.0 / sqrt(norm1 + norm2 + norm4 + norm5 + 1e-4) ;
          factor2 = 1.0 / sqrt(norm2 + norm3 + norm5 + norm6 + 1e-4) ;
          factor3 = 1.0 / sqrt(norm4 + norm5 + norm7 + norm8 + 1e-4) ;
          factor4 = 1.0 / sqrt(norm5 + norm6 + norm8 + norm9 + 1e-4) ;
        }
#endif

        for (k = 0 ; k < self->numOrientations ; ++k) {
          double ha = iter[hogStride * k] ;
          double hb = iter[hogStride * (k + self->numOrientations)] ;
          double hc ;

          double ha1 = factor1 * ha ;
          double ha2 = factor2 * ha ;
          double ha3 = factor3 * ha ;
          double ha4 = factor4 * ha ;

          double hb1 = factor1 * hb ;
          double hb2 = factor2 * hb ;
          double hb3 = factor3 * hb ;
          double hb4 = factor4 * hb ;

          double hc1 = ha1 + hb1 ;
          double hc2 = ha2 + hb2 ;
          double hc3 = ha3 + hb3 ;
          double hc4 = ha4 + hb4 ;

          ha1 = VL_MIN(0.2, ha1) ;
          ha2 = VL_MIN(0.2, ha2) ;
          ha3 = VL_MIN(0.2, ha3) ;
          ha4 = VL_MIN(0.2, ha4) ;

          hb1 = VL_MIN(0.2, hb1) ;
          hb2 = VL_MIN(0.2, hb2) ;
          hb3 = VL_MIN(0.2, hb3) ;
          hb4 = VL_MIN(0.2, hb4) ;

          hc1 = VL_MIN(0.2, hc1) ;
          hc2 = VL_MIN(0.2, hc2) ;
          hc3 = VL_MIN(0.2, hc3) ;
          hc4 = VL_MIN(0.2, hc4) ;

          t1 += hc1 ;
          t2 += hc2 ;
          t3 += hc3 ;
          t4 += hc4 ;

          switch (self->variant) {
            case VlHogVariantUoctti :
              ha = 0.5 * (ha1 + ha2 + ha3 + ha4) ;
              hb = 0.5 * (hb1 + hb2 + hb3 + hb4) ;
              hc = 0.5 * (hc1 + hc2 + hc3 + hc4) ;
              *oiter = ha ;
              *(oiter + hogStride * self->numOrientations) = hb ;
              *(oiter + 2 * hogStride * self->numOrientations) = hc ;
              break ;

            case VlHogVariantDalalTriggs :
              *oiter = hc1 ;
              *(oiter + hogStride * self->numOrientations) = hc2 ;
              *(oiter + 2 * hogStride * self->numOrientations) = hc3 ;
              *(oiter + 3 * hogStride * self->numOrientations) = hc4 ;
              break ;
          }
          oiter += hogStride ;

        } /* next orientation */

        switch (self->variant) {
          case VlHogVariantUoctti :
            oiter += 2 * hogStride * self->numOrientations ;
            *oiter = (1.0f/sqrtf(18.0f)) * t1 ; oiter += hogStride ;
            *oiter = (1.0f/sqrtf(18.0f)) * t2 ; oiter += hogStride ;
            *oiter = (1.0f/sqrtf(18.0f)) * t3 ; oiter += hogStride ;
            *oiter = (1.0f/sqrtf(18.0f)) * t4 ; oiter += hogStride ;
            break ;

          case VlHogVariantDalalTriggs :
            break ;
        }
        ++iter ;
      } /* next x */
    } /* next y */
  } /* block normalization */
}
Example #19
0
File: hog.c Project: CVML/SUN3Dsfm
void
vl_hog_put_image (VlHog * self,
                  float const * image,
                  vl_size width, vl_size height, vl_size numChannels,
                  vl_size cellSize)
{
  vl_size hogStride ;
  vl_size channelStride = width * height ;
  vl_index x, y ;
  vl_uindex k ;

  assert(self) ;
  assert(image) ;

  /* clear features */
  vl_hog_prepare_buffers(self, width, height, cellSize) ;
  hogStride = self->hogWidth * self->hogHeight ;

#define at(x,y,k) (self->hog[(x) + (y) * self->hogWidth + (k) * hogStride])

  /* compute gradients and map the to HOG cells by bilinear interpolation */
  for (y = 1 ; y < (signed)height - 1 ; ++y) {
    for (x = 1 ; x < (signed)width - 1 ; ++x) {
      float gradx = 0 ;
      float grady = 0 ;
      float grad ;
      float orientationWeights [2] = {0,0} ;
      vl_index orientationBins [2] = {-1,-1} ;
      vl_index orientation = 0 ;
      float hx, hy, wx1, wx2, wy1, wy2 ;
      vl_index binx, biny, o ;

      /*
       Compute the gradient at (x,y). The image channel with
       the maximum gradient at each location is selected.
       */
      {
        float const * iter = image + y * width + x ;
        float grad2 = 0 ;
        for (k = 0 ; k < numChannels ; ++k) {
          float gradx_ = *(iter + 1) - *(iter - 1) ;
          float grady_ = *(iter + width)  - *(iter - width) ;
          float grad2_ = gradx_ * gradx_ + grady_ * grady_ ;
          if (grad2_ > grad2) {
            gradx = gradx_ ;
            grady = grady_ ;
            grad2 = grad2_ ;
          }
          iter += channelStride ;
        }
        grad = sqrtf(grad2) ;
        gradx /= VL_MAX(grad, 1e-10) ;
        grady /= VL_MAX(grad, 1e-10) ;
      }

      /*
       Map the gradient to the closest and second closets orientation bins.
       There are numOrientations orientation in the interval [0,pi).
       The next numOriantations are the symmetric ones, for a total
       of 2*numOrientation directed orientations.
       */
      for (k = 0 ; k < self->numOrientations ; ++k) {
        float orientationScore_ = gradx * self->orientationX[k] +  grady * self->orientationY[k] ;
        vl_index orientationBin_ = k ;
        if (orientationScore_ < 0) {
          orientationScore_ = - orientationScore_ ;
          orientationBin_ += self->numOrientations ;
        }
        if (orientationScore_ > orientationWeights[0]) {
          orientationBins[1] = orientationBins[0] ;
          orientationWeights[1] = orientationWeights[0] ;
          orientationBins[0] = orientationBin_ ; ;
          orientationWeights[0] = orientationScore_ ;
        } else if (orientationScore_ > orientationWeights[1]) {
          orientationBins[1] = orientationBin_ ;
          orientationWeights[1] = orientationScore_ ;
        }
      }

      if (self->useBilinearOrientationAssigment) {
        /* min(1.0,...) guards against small overflows causing NaNs */
        float angle0 = acosf(VL_MIN(orientationWeights[0],1.0)) ;
        orientationWeights[1] = angle0 / (VL_PI / self->numOrientations) ;
        orientationWeights[0] = 1 - orientationWeights[1] ;
      } else {
        orientationWeights[0] = 1 ;
        orientationBins[1] = -1 ;
      }

      for (o = 0 ; o < 2 ; ++o) {
        /*
         Accumulate the gradient. hx is the distance of the
         pixel x to the cell center at its left, in units of cellSize.
         With this parametrixation, a pixel on the cell center
         has hx = 0, which gradually increases to 1 moving to the next
         center.
         */

        orientation = orientationBins[o] ;
        if (orientation < 0) continue ;

        /*  (x - (w-1)/2) / w = (x + 0.5)/w - 0.5 */
        hx = (x + 0.5) / cellSize - 0.5 ;
        hy = (y + 0.5) / cellSize - 0.5 ;
        binx = vl_floor_f(hx) ;
        biny = vl_floor_f(hy) ;
        wx2 = hx - binx ;
        wy2 = hy - biny ;
        wx1 = 1.0 - wx2 ;
        wy1 = 1.0 - wy2 ;

        wx1 *= orientationWeights[o] ;
        wx2 *= orientationWeights[o] ;
        wy1 *= orientationWeights[o] ;
        wy2 *= orientationWeights[o] ;

        /*VL_PRINTF("%d %d - %d %d %f %f - %f %f %f %f - %d \n ",x,y,binx,biny,hx,hy,wx1,wx2,wy1,wy2,o);*/

        if (binx >= 0 && biny >=0) {
          at(binx,biny,orientation) += grad * wx1 * wy1 ;
        }
        if (binx < (signed)self->hogWidth - 1 && biny >=0) {
          at(binx+1,biny,orientation) += grad * wx2 * wy1 ;
        }
        if (binx < (signed)self->hogWidth - 1 && biny < (signed)self->hogHeight - 1) {
          at(binx+1,biny+1,orientation) += grad * wx2 * wy2 ;
        }
        if (binx >= 0 && biny < (signed)self->hogHeight - 1) {
          at(binx,biny+1,orientation) += grad * wx1 * wy2 ;
        }
      } /* next o */
    } /* next x */
  } /* next y */
}
Example #20
0
void 
mexFunction (int nout, mxArray * out[], int nin, const mxArray * in[])
{
  enum {IN_PARENTS = 0, IN_DATA, IN_OPT} ;
  enum {OUT_TREE} ;

  vl_uint32 const *parents ;  
  vl_uint32 *tree ;
  double const *data ;

  int nnull = 0 ;
  int histmode = 0 ;
  
  int i, P, N ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if ((nin < 2) || (nin > 3)) {
    mexErrMsgTxt ("Two or three arguments required.") ;
  }

  if (nout > 1) {
    mexErrMsgTxt ("Too many output arguments.") ;
  }
  
  if (!uIsRealMatrix(in[IN_DATA], -1, -1)) {
    mexErrMsgTxt ("DATA must be a matrix of DOUBLE");
  }

  if (!uIsVector(in[IN_PARENTS], -1)) {
    mexErrMsgTxt ("PARENTS must be a vector") ;   
  }

  if (mxGetClassID(in[IN_PARENTS]) != mxUINT32_CLASS) {
    mexErrMsgTxt ("PARENTS must be UINT32") ;
  }
  
  N = mxGetNumberOfElements (in[IN_DATA]) ;
  data = mxGetPr (in[IN_DATA]) ;

  P = mxGetNumberOfElements (in[IN_PARENTS]) ;
  parents = mxGetData (in[IN_PARENTS]) ;
  
  if (nin > 2) {
    enum {buflen = 32} ;
    char buf [buflen] ;
    if (!uIsString(in[IN_OPT], -1)) {
      mexErrMsgTxt("OPT must be a string") ;
    }
    mxGetString(in[IN_OPT], buf, buflen) ;
    buf [buflen - 1] = 0 ;
    if (!uStrICmp("hist", buf)) {
      mexErrMsgTxt("OPT must be equal to 'hist'") ;
    }
    histmode = 1 ;
  }
  
  out[OUT_TREE] = mxCreateNumericMatrix(1, P,mxUINT32_CLASS, mxREAL) ;
  tree = mxGetData (out[OUT_TREE]) ;

  /* -----------------------------------------------------------------
   *                                                        Do the job
   * -------------------------------------------------------------- */

  {   
    char buf [1024] ;
    vl_uint32 max_node = 0 ;
    vl_uint32 min_node = 0 ;
    vl_uint32 last_leaf = 0 ;
    vl_uint32 root = 0 ;

    /* exhamine parents for errors and informations */
    for (i = 0 ; i  < P ; ++i) {
      vl_uint32 node = parents [i] ;

      if ((node != 0) & (node != 1)) {
        max_node = VL_MAX (node, max_node) ;
        min_node = VL_MIN (node, min_node) ;
      }

      /* check no node points outside the tree */
      if (node > P) {
        snprintf(buf, sizeof(buf),
                 "Out of bounds link PARENTS[%d] = %u > %u", i, node, P) ;
        mexErrMsgTxt (buf) ;
      }
      
      /* check node points to something above him */
      if ((node != 0) & (node != 1) & (node < i)) {
        snprintf(buf, sizeof(buf),
                 "Backward link PARENTS[%d] = %u < %d", i, node, i) ;
        mexErrMsgTxt (buf) ;
      }
      if (node == 0) ++ nnull ;      
    }

    /* now
     *
     * min_node = first node which is not a leaf
     * max_node = root node
     * nnull    = number of leaves pointing to the null node
     */
    
    last_leaf = min_node - 1 ;
    root = max_node ;
    
    /* process data */
    for (i = 0 ; i < N ; ++i) {
      int w = 1 ;
      int x = (int) data [i] ;

      if (histmode) {
        w = x ;
        x = i ;
      }
      
      if ((x < 1) | (x > last_leaf)) {
        if (histmode) {
          snprintf(buf, sizeof(buf), 
                   "DATA length exceeds number of AIB leaves") ;
        } else {
          snprintf(buf, sizeof(buf),
                   "DATA [%d] = %d is not a leaf", i, x) ;
        }
        mexErrMsgTxt (buf) ;        
      }
      
      while (true) {
        int x_ = (int) parents [x -1] ;
        /*     mexPrintf("%d : x_=%d, x=%d\n", i, x_, x) ; */
        ++ tree [x - 1] ;        
        if ((x_ == x) | (x_ == 0) | (x_ == 1)) break ;
        x = x_ ;
      }
    }
  }
}
Example #21
0
static void
vl_kdtree_build_recursively
(VlKDForest * forest,
 VlKDTree * tree, vl_uindex nodeIndex,
 vl_uindex dataBegin, vl_uindex dataEnd,
 unsigned int depth)
{
  vl_uindex d, i, medianIndex, splitIndex ;
  VlKDTreeNode * node = tree->nodes + nodeIndex ;
  VlKDTreeSplitDimension * splitDimension ;

  /* base case: there is only one data point */
  if (dataEnd - dataBegin <= 1) {
    if (tree->depth < depth) tree->depth = depth ;
    node->lowerChild = - dataBegin - 1;
    node->upperChild = - dataEnd - 1 ;
    return ;
  }

  /* compute the dimension with largest variance */
  forest->splitHeapNumNodes = 0 ;
  for (d = 0 ; d < forest->dimension ; ++ d) {
    double mean = 0 ; /* unnormalized */
    double secondMoment = 0 ;
    double variance = 0 ;
    for (i = dataBegin ; i < dataEnd ; ++ i) {
      int di = tree -> dataIndex [i] .index ;
      double datum ;
      switch(forest->dataType) {
        case VL_TYPE_FLOAT: datum = ((float const*)forest->data)
          [di * forest->dimension + d] ; break ;
        case VL_TYPE_DOUBLE: datum = ((double const*)forest->data)
          [di * forest->dimension + d] ; break ;
        default:
          abort() ;
      }
      mean += datum ;
      secondMoment += datum * datum ;
    }
    mean /= (dataEnd - dataBegin) ;
    secondMoment /= (dataEnd - dataBegin) ;
    variance = secondMoment - mean * mean ;

    /* keep splitHeapSize most varying dimensions */
    if (forest->splitHeapNumNodes < forest->splitHeapSize) {
      VlKDTreeSplitDimension * splitDimension
        = forest->splitHeapArray + forest->splitHeapNumNodes ;
      splitDimension->dimension = d ;
      splitDimension->mean = mean ;
      splitDimension->variance = variance ;
      vl_kdtree_split_heap_push (forest->splitHeapArray, &forest->splitHeapNumNodes) ;
    } else {
      VlKDTreeSplitDimension * splitDimension = forest->splitHeapArray + 0 ;
      if (splitDimension->variance < variance) {
        splitDimension->dimension = d ;
        splitDimension->mean = mean ;
        splitDimension->variance = variance ;
        vl_kdtree_split_heap_update (forest->splitHeapArray, forest->splitHeapNumNodes, 0) ;
      }
    }
  }

  /* toss a dice to decide the splitting dimension */
  splitDimension = forest->splitHeapArray
  + (vl_rand_uint32(forest->rand) % VL_MIN(forest->splitHeapSize, forest->splitHeapNumNodes)) ;

  /* additional base case: variance is equal to 0 (overlapping points) */
  if (splitDimension->variance == 0) {
    node->lowerChild = - dataBegin - 1 ;
    node->upperChild = - dataEnd - 1 ;
    return ;
  }
  node->splitDimension = splitDimension->dimension ;

  /* sort data along largest variance dimension */
  for (i = dataBegin ; i < dataEnd ; ++ i) {
    int di = tree->dataIndex [i] .index ;
    double datum ;
    switch (forest->dataType) {
      case VL_TYPE_FLOAT: datum = ((float const*)forest->data)
        [di * forest->dimension + splitDimension->dimension] ;
        break ;
      case VL_TYPE_DOUBLE: datum = ((double const*)forest->data)
        [di * forest->dimension + splitDimension->dimension] ;
        break ;
      default:
        abort() ;
    }
    tree->dataIndex [i] .value = datum ;
  }
  qsort (tree->dataIndex + dataBegin,
         dataEnd - dataBegin,
         sizeof (VlKDTreeDataIndexEntry),
         vl_kdtree_compare_index_entries) ;

  /* determine split threshold */
  switch (forest->thresholdingMethod) {
    case VL_KDTREE_MEAN :
      node->splitThreshold = splitDimension->mean ;
      for (splitIndex = dataBegin ;
           splitIndex < dataEnd && tree->dataIndex[splitIndex].value <= node->splitThreshold ;
           ++ splitIndex) ;
      splitIndex -= 1 ;
      /* If the mean does not provide a proper partition, fall back to
       * median. This usually happens if all points have the same
       * value and the zero variance test fails for numerical accuracy
       * reasons. In this case, also due to numerical accuracy, the
       * mean value can be smaller, equal, or larger than all
       * points. */
      if (dataBegin <= splitIndex && splitIndex + 1 < dataEnd) break ;

    case VL_KDTREE_MEDIAN :
      medianIndex = (dataBegin + dataEnd - 1) / 2 ;
      splitIndex = medianIndex ;
      node -> splitThreshold = tree->dataIndex[medianIndex].value ;
      break ;

    default:
      abort() ;
  }

  /* divide subparts */
  node->lowerChild = vl_kdtree_node_new (tree, nodeIndex) ;
  vl_kdtree_build_recursively (forest, tree, node->lowerChild, dataBegin, splitIndex + 1, depth + 1) ;

  node->upperChild = vl_kdtree_node_new (tree, nodeIndex) ;
  vl_kdtree_build_recursively (forest, tree, node->upperChild, splitIndex + 1, dataEnd, depth + 1) ;
}
Example #22
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_I=0, IN_END} ;
  enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ;

  int verbose = 0 ;
  int opt ;
  int next = IN_END ;
  mxArray const *optarg ;

  float const *data ;
  int M, N ;

  int step [2] = {1,1} ;
  vl_bool norm = 0 ;

  vl_bool floatDescriptors = VL_FALSE ;
  vl_bool useFlatWindow = VL_FALSE ;
  double windowSize = -1.0 ;

  double *bounds = NULL ;
  double boundBuffer [4] ;
  VlDsiftDescriptorGeometry geom ;

  VL_USE_MATLAB_ENV ;

  geom.numBinX = 4 ;
  geom.numBinY = 4 ;
  geom.numBinT = 8 ;
  geom.binSizeX = 3 ;
  geom.binSizeY = 3 ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 1) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  } else if (nout > 2) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  if (mxGetNumberOfDimensions (in[IN_I]) != 2              ||
      mxGetClassID            (in[IN_I]) != mxSINGLE_CLASS ) {
    vlmxError(vlmxErrInvalidArgument,
              "I must be a matrix of class SINGLE.") ;
  }

  data = (float*) mxGetData (in[IN_I]) ;
  M    = mxGetM (in[IN_I]) ;
  N    = mxGetN (in[IN_I]) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {

      case opt_verbose :
        ++ verbose ;
        break ;

      case opt_fast :
        useFlatWindow = 1 ;
        break ;

      case opt_norm :
        norm = 1 ;
        break ;

      case opt_bounds :
        if (!vlmxIsPlainVector(optarg, 4)) {
          mexErrMsgTxt("BOUNDS must be a 4-dimensional vector.") ;
        }
        bounds = boundBuffer ;
        bounds [0] = mxGetPr(optarg)[0] - 1 ;
        bounds [1] = mxGetPr(optarg)[1] - 1 ;
        bounds [2] = mxGetPr(optarg)[2] - 1 ;
        bounds [3] = mxGetPr(optarg)[3] - 1 ;
        break ;

      case opt_size :
        if (!vlmxIsPlainVector(optarg,-1)) {
          vlmxError(vlmxErrInvalidArgument,"SIZE is not a plain vector.") ;
        }
        if (mxGetNumberOfElements(optarg) == 1) {
          geom.binSizeX = (int) mxGetPr(optarg)[0] ;
          geom.binSizeY = (int) mxGetPr(optarg)[0] ;
        } else if (mxGetNumberOfElements(optarg) == 2) {
          geom.binSizeX = (int) mxGetPr(optarg)[1] ;
          geom.binSizeY = (int) mxGetPr(optarg)[0] ;
        } else {
          vlmxError(vlmxErrInvalidArgument,"SIZE is neither a scalar or a 2D vector.") ;
        }
        if (geom.binSizeX < 1 || geom.binSizeY < 1) {
          vlmxError(vlmxErrInvalidArgument,"SIZE value is invalid.") ;
        }
        break ;

      case opt_step :
        if (!vlmxIsPlainVector(optarg,-1)) {
          vlmxError(vlmxErrInvalidArgument,"STEP is not a plain vector.") ;
        }
        if (mxGetNumberOfElements(optarg) == 1) {
          step[0] = (int) mxGetPr(optarg)[0] ;
          step[1] = (int) mxGetPr(optarg)[0] ;
        } else if (mxGetNumberOfElements(optarg) == 2) {
          step[0] = (int) mxGetPr(optarg)[1] ;
          step[1] = (int) mxGetPr(optarg)[0] ;
        } else {
          vlmxError(vlmxErrInvalidArgument,"STEP is neither a scalar or a 2D vector.") ;
        }
        if (step[0] < 1 || step[1] < 1) {
          vlmxError(vlmxErrInvalidArgument,"STEP value is invalid.") ;
        }
        break ;

      case opt_window_size :
        if (!vlmxIsPlainScalar(optarg) || (windowSize = *mxGetPr(optarg)) < 0) {
          vlmxError(vlmxErrInvalidArgument,"WINDOWSIZE is not a scalar or it is negative.") ;
        }
        break ;

      case opt_float_descriptors :
        floatDescriptors = VL_TRUE ;
        break ;

      case opt_geometry :
        if (!vlmxIsPlainVector(optarg,3)) {
          vlmxError(vlmxErrInvalidArgument, "GEOMETRY is not a 3D vector.") ;
        }
        geom.numBinY = (int)mxGetPr(optarg)[0] ;
        geom.numBinX = (int)mxGetPr(optarg)[1] ;
        geom.numBinT = (int)mxGetPr(optarg)[2] ;
        if (geom.numBinX < 1 ||
            geom.numBinY < 1 ||
            geom.numBinT < 1) {
          vlmxError(vlmxErrInvalidArgument, "GEOMETRY value is invalid.") ;
        }
        break ;

      default :
        abort() ;
    }
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  {
    int numFrames ;
    int descrSize ;
    VlDsiftKeypoint const *frames ;
    float const *descrs ;
    int k, i ;

    VlDsiftFilter *dsift ;

    /* note that the image received from MATLAB is transposed */
    dsift = vl_dsift_new (M, N) ;
    vl_dsift_set_geometry(dsift, &geom) ;
    vl_dsift_set_steps(dsift, step[0], step[1]) ;

    if (bounds) {
      vl_dsift_set_bounds(dsift,
                          VL_MAX(bounds[1], 0),
                          VL_MAX(bounds[0], 0),
                          VL_MIN(bounds[3], M - 1),
                          VL_MIN(bounds[2], N - 1));
    }
    vl_dsift_set_flat_window(dsift, useFlatWindow) ;

    if (windowSize >= 0) {
      vl_dsift_set_window_size(dsift, windowSize) ;
    }

    numFrames = vl_dsift_get_keypoint_num (dsift) ;
    descrSize = vl_dsift_get_descriptor_size (dsift) ;
    geom = *vl_dsift_get_geometry (dsift) ;

    if (verbose) {
      int stepX ;
      int stepY ;
      int minX ;
      int minY ;
      int maxX ;
      int maxY ;
      vl_bool useFlatWindow ;

      vl_dsift_get_steps (dsift, &stepY, &stepX) ;
      vl_dsift_get_bounds (dsift, &minY, &minX, &maxY, &maxX) ;
      useFlatWindow = vl_dsift_get_flat_window(dsift) ;

      mexPrintf("vl_dsift: image size         [W, H] = [%d, %d]\n", N, M) ;
      mexPrintf("vl_dsift: bounds:            [minX,minY,maxX,maxY] = [%d, %d, %d, %d]\n",
                minX+1, minY+1, maxX+1, maxY+1) ;
      mexPrintf("vl_dsift: subsampling steps: stepX=%d, stepY=%d\n", stepX, stepY) ;
      mexPrintf("vl_dsift: num bins:          [numBinT, numBinX, numBinY] = [%d, %d, %d]\n",
                geom.numBinT,
                geom.numBinX,
                geom.numBinY) ;
      mexPrintf("vl_dsift: descriptor size:   %d\n", descrSize) ;
      mexPrintf("vl_dsift: bin sizes:         [binSizeX, binSizeY] = [%d, %d]\n",
                geom.binSizeX,
                geom.binSizeY) ;
      mexPrintf("vl_dsift: flat window:       %s\n", VL_YESNO(useFlatWindow)) ;
      mexPrintf("vl_dsift: window size:       %g\n", vl_dsift_get_window_size(dsift)) ;
      mexPrintf("vl_dsift: num of features:   %d\n", numFrames) ;
    }

    vl_dsift_process (dsift, data) ;

    frames = vl_dsift_get_keypoints (dsift) ;
    descrs = vl_dsift_get_descriptors (dsift) ;

    /* ---------------------------------------------------------------
     *                                            Create output arrays
     * ------------------------------------------------------------ */
    {
      mwSize dims [2] ;

      dims [0] = descrSize ;
      dims [1] = numFrames ;

      if (floatDescriptors) {
        out[OUT_DESCRIPTORS] = mxCreateNumericArray
        (2, dims, mxSINGLE_CLASS, mxREAL) ;
      } else {
        out[OUT_DESCRIPTORS] = mxCreateNumericArray
        (2, dims, mxUINT8_CLASS, mxREAL) ;
      }

      dims [0] = norm ? 3 : 2 ;

      out[OUT_FRAMES] = mxCreateNumericArray
      (2, dims, mxDOUBLE_CLASS, mxREAL) ;
    }

    /* ---------------------------------------------------------------
     *                                                       Copy back
     * ------------------------------------------------------------ */
    {
      float *tmpDescr = mxMalloc(sizeof(float) * descrSize) ;
      double *outFrameIter = mxGetPr(out[OUT_FRAMES]) ;
      void *outDescrIter = mxGetData(out[OUT_DESCRIPTORS]) ;
      for (k = 0 ; k < numFrames ; ++k) {
        *outFrameIter++ = frames[k].y + 1 ;
        *outFrameIter++ = frames[k].x + 1 ;

        /* We have an implied / 2 in the norm, because of the clipping
           below */
        if (norm)
          *outFrameIter++ = frames [k].norm ;

        vl_dsift_transpose_descriptor (tmpDescr,
                                       descrs + descrSize * k,
                                       geom.numBinT,
                                       geom.numBinX,
                                       geom.numBinY) ;

        if (floatDescriptors) {
          for (i = 0 ; i < descrSize ; ++i) {
            float * pt = (float*) outDescrIter ;
            *pt++ = VL_MIN(512.0F * tmpDescr[i], 255.0F) ;
            outDescrIter = pt ;
          }
        } else {
          for (i = 0 ; i < descrSize ; ++i) {
            vl_uint8 * pt = (vl_uint8*) outDescrIter ;
            *pt++ = (vl_uint8) (VL_MIN(512.0F * tmpDescr[i], 255.0F)) ;
            outDescrIter = pt ;

          }
        }
      }
      mxFree(tmpDescr) ;
    }
    vl_dsift_delete (dsift) ;
  }
}
Example #23
0
static void
VL_XCAT(_vl_kmeans_seed_centers_plus_plus_, SFX)
(VlKMeans * self,
 TYPE const * data,
 vl_size dimension,
 vl_size numData,
 vl_size numCenters)
{
  vl_uindex x, c ;
  VlRand * rand = vl_get_rand () ;
  TYPE * distances = vl_malloc (sizeof(TYPE) * numData) ;
  TYPE * minDistances = vl_malloc (sizeof(TYPE) * numData) ;
#if (FLT == VL_TYPE_FLOAT)
  VlFloatVectorComparisonFunction distFn = vl_get_vector_comparison_function_f(self->distance) ;
#else
  VlDoubleVectorComparisonFunction distFn = vl_get_vector_comparison_function_d(self->distance) ;
#endif

  self->dimension = dimension ;
  self->numCenters = numCenters ;
  self->centers = vl_malloc (sizeof(TYPE) * dimension * numCenters) ;

  for (x = 0 ; x < numData ; ++x) {
    minDistances[x] = (TYPE) VL_INFINITY_D ;
  }

  /* select the first point at random */
  x = vl_rand_uindex (rand, numData) ;
  c = 0 ;
  while (1) {
    TYPE energy = 0 ;
    TYPE acc = 0 ;
    TYPE thresh = (TYPE) vl_rand_real1 (rand) ;

    memcpy ((TYPE*)self->centers + c * dimension,
            data + x * dimension,
            sizeof(TYPE) * dimension) ;

    c ++ ;
    if (c == numCenters) break ;

    VL_XCAT(vl_eval_vector_comparison_on_all_pairs_, SFX)
    (distances,
     dimension,
     (TYPE*)self->centers + (c - 1) * dimension, 1,
     data, numData,
     distFn) ;

    for (x = 0 ; x < numData ; ++x) {
      minDistances[x] = VL_MIN(minDistances[x], distances[x]) ;
      energy += minDistances[x] ;
    }

    for (x = 0 ; x < numData - 1 ; ++x) {
      acc += minDistances[x] ;
      if (acc >= thresh * energy) break ;
    }
  }

  vl_free(distances) ;
  vl_free(minDistances) ;
}
void quickshift(image_t im, float sigma, float tau, float * map, float * gaps, float * E)
{
  int verb = 1 ;

  float *M = 0, *n = 0;
  float tau2;
  
  int K, d;
  int N1,N2, i1,i2, j1,j2, R, tR;

  int medoid = 0 ;

  float const * I = im.I;
  N1 = im.N1;
  N2 = im.N2;
  K = im.K;

  d = 2 + K ; /* Total dimensions include spatial component (x,y) */
  
  tau2  = tau*tau;

  
  if (medoid) { /* n and M are only used in mediod shift */
    M = (float *) calloc(N1*N2*d, sizeof(float)) ;
    n = (float *) calloc(N1*N2,   sizeof(float)) ;
  }

  R = (int) ceil (3 * sigma) ;
  tR = (int) ceil (tau) ;
  
  if (verb) {
    printf("quickshift: [N1,N2,K]: [%d,%d,%d]\n", N1,N2,K) ;
    printf("quickshift: type: %s\n", medoid ? "medoid" : "quick");
    printf("quickshift: sigma:   %g\n", sigma) ;
    /* R is ceil(3 * sigma) and determines the window size to accumulate
     * similarity */
    printf("quickshift: R:       %d\n", R) ; 
    printf("quickshift: tau:     %g\n", tau) ;
    printf("quickshift: tR:      %d\n", tR) ;
  }

  /* -----------------------------------------------------------------
   *                                                                 n 
   * -------------------------------------------------------------- */

  /* If we are doing medoid shift, initialize n to the inner product of the
   * image with itself
   */
  if (n) { 
    for (i2 = 0 ; i2 < N2 ; ++ i2) {
      for (i1 = 0 ; i1 < N1 ; ++ i1) {        
        n [i1 + N1 * i2] = inner(I,N1,N2,K,
                                 i1,i2,
                                 i1,i2) ;
      }
    }
  }
  
  unsigned int Etimer;
  cutilCheckError( cutCreateTimer(&Etimer) );
  cutilCheckError( cutResetTimer(Etimer) );
  cutilCheckError( cutStartTimer(Etimer) );

  /* -----------------------------------------------------------------
   *                                                 E = - [oN'*F]', M
   * -------------------------------------------------------------- */
  
  /* 
     D_ij = d(x_i,x_j)
     E_ij = exp(- .5 * D_ij / sigma^2) ;
     F_ij = - E_ij             
     E_i  = sum_j E_ij
     M_di = sum_j X_j F_ij

     E is the parzen window estimate of the density
     0 = dissimilar to everything, windowsize = identical
  */
  
  for (i2 = 0 ; i2 < N2 ; ++ i2) {
    for (i1 = 0 ; i1 < N1 ; ++ i1) {
      
      float Ei = 0;
      int j1min = VL_MAX(i1 - R, 0   ) ;
      int j1max = VL_MIN(i1 + R, N1-1) ;
      int j2min = VL_MAX(i2 - R, 0   ) ;
      int j2max = VL_MIN(i2 + R, N2-1) ;      
      
      /* For each pixel in the window compute the distance between it and the
       * source pixel */
      for (j2 = j2min ; j2 <= j2max ; ++ j2) {
        for (j1 = j1min ; j1 <= j1max ; ++ j1) {
          float Dij = distance(I,N1,N2,K, i1,i2, j1,j2) ;          
          /* Make distance a similarity */ 
          float Fij = exp(- Dij / (2*sigma*sigma)) ;

          /* E is E_i above */
          Ei += Fij;
          
          if (M) {
            /* Accumulate votes for the median */
            int k ;
            M [i1 + N1*i2 + (N1*N2) * 0] += j1 * Fij ;
            M [i1 + N1*i2 + (N1*N2) * 1] += j2 * Fij ;
            for (k = 0 ; k < K ; ++k) {
              M [i1 + N1*i2 + (N1*N2) * (k+2)] += 
                I [j1 + N1*j2 + (N1*N2) * k] * Fij ;
            }
          } 
          
        } /* j1 */ 
      } /* j2 */
      /* Normalize */
      E [i1 + N1 * i2] = Ei / ((j1max-j1min)*(j2max-j2min));
      
      /*E [i1 + N1 * i2] = Ei ; */

    }  /* i1 */
  } /* i2 */
  
  cutilCheckError( cutStopTimer(Etimer) );
  float ETime = cutGetTimerValue(Etimer);
  printf("ComputeE: %fms\n", ETime);

  unsigned int Ntimer;
  cutilCheckError( cutCreateTimer(&Ntimer) );
  cutilCheckError( cutResetTimer(Ntimer) );
  cutilCheckError( cutStartTimer(Ntimer) );
 
  /* -----------------------------------------------------------------
   *                                               Find best neighbors
   * -------------------------------------------------------------- */
  
  if (medoid) {
    
    /* 
       Qij = - nj Ei - 2 sum_k Gjk Mik
       n is I.^2
    */
    
    /* medoid shift */
    for (i2 = 0 ; i2 < N2 ; ++i2) {
      for (i1 = 0 ; i1 < N1 ; ++i1) {
        
        float sc_best = 0  ;
        /* j1/j2 best are the best indicies for each i */
        float j1_best = i1 ;
        float j2_best = i2 ; 
        
        int j1min = VL_MAX(i1 - R, 0   ) ;
        int j1max = VL_MIN(i1 + R, N1-1) ;
        int j2min = VL_MAX(i2 - R, 0   ) ;
        int j2max = VL_MIN(i2 + R, N2-1) ;      
        
        for (j2 = j2min ; j2 <= j2max ; ++ j2) {
          for (j1 = j1min ; j1 <= j1max ; ++ j1) {            
            
            float Qij = - n [j1 + j2 * N1] * E [i1 + i2 * N1] ;
            int k ;

            Qij -= 2 * j1 * M [i1 + i2 * N1 + (N1*N2) * 0] ;
            Qij -= 2 * j2 * M [i1 + i2 * N1 + (N1*N2) * 1] ;
            for (k = 0 ; k < K ; ++k) {
              Qij -= 2 * 
                I [j1 + j2 * N1 + (N1*N2) * k] *
                M [i1 + i2 * N1 + (N1*N2) * (k + 2)] ;
            }
            
            if (Qij > sc_best) {
              sc_best = Qij ;
              j1_best = j1 ;
              j2_best = j2 ;
            }
          }
        }

        /* map_i is the linear index of j which is the best pair (in matlab
         * notation
         * gaps_i is the score of the best match
         */
        map [i1 + N1 * i2] = j1_best + N1 * j2_best ; /*+ 1 ; */
        gaps[i1 + N1 * i2] = sc_best ;
      }
    }  

  } else {
    
    /* Quickshift assigns each i to the closest j which has an increase in the
     * density (E). If there is no j s.t. Ej > Ei, then gaps_i == inf (a root
     * node in one of the trees of merges).
     */
    for (i2 = 0 ; i2 < N2 ; ++i2) {
      for (i1 = 0 ; i1 < N1 ; ++i1) {
        
        float E0 = E [i1 + N1 * i2] ;
        float d_best = INF ;
        float j1_best = i1   ;
        float j2_best = i2   ; 
        
        int j1min = VL_MAX(i1 - tR, 0   ) ;
        int j1max = VL_MIN(i1 + tR, N1-1) ;
        int j2min = VL_MAX(i2 - tR, 0   ) ;
        int j2max = VL_MIN(i2 + tR, N2-1) ;      
        
        for (j2 = j2min ; j2 <= j2max ; ++ j2) {
          for (j1 = j1min ; j1 <= j1max ; ++ j1) {            
            if (E [j1 + N1 * j2] > E0) {
              float Dij = distance(I,N1,N2,K, i1,i2, j1,j2) ;           
              if (Dij <= tau2 && Dij < d_best) {
                d_best = Dij ;
                j1_best = j1 ;
                j2_best = j2 ;
              }
            }
          }
        }
        
        /* map is the index of the best pair */
        /* gaps_i is the minimal distance, inf implies no Ej > Ei within
         * distance tau from the point */
        map [i1 + N1 * i2] = j1_best + N1 * j2_best ; /* + 1 ; */
        if (map[i1 + N1 * i2] != i1 + N1 * i2)
          gaps[i1 + N1 * i2] = sqrt(d_best) ;
        else
          gaps[i1 + N1 * i2] = d_best; /* inf */
      }
    }  
  }
  
  if (M) free(M) ;
  if (n) free(n) ;
  
  cutilCheckError( cutStopTimer(Ntimer) );
  float NTime = cutGetTimerValue(Ntimer);
  printf("ComputeN: %fms\n", NTime);

}
Example #25
0
VL_EXPORT
void vl_quickshift_process(VlQS * q)
{
  vl_qs_type const *I = q->image;
  int        *parents = q->parents;
  vl_qs_type *E = q->density;
  vl_qs_type *dists = q->dists; 
  vl_qs_type *M = 0, *n = 0 ;
  vl_qs_type sigma = q->sigma ;
  vl_qs_type tau = q->tau;
  vl_qs_type tau2 = tau*tau;
  
  int K = q->channels, d;
  int N1 = q->height, N2 = q->width;
  int i1,i2, j1,j2, R, tR;

  d = 2 + K ; /* Total dimensions include spatial component (x,y) */

  if (q->medoid) { /* n and M are only used in mediod shift */
    M = (vl_qs_type *) vl_calloc(N1*N2*d, sizeof(vl_qs_type)) ;
    n = (vl_qs_type *) vl_calloc(N1*N2,   sizeof(vl_qs_type)) ;
  }

  R = (int) ceil (3 * sigma) ;
  tR = (int) ceil (tau) ;
  
  /* -----------------------------------------------------------------
   *                                                                 n 
   * -------------------------------------------------------------- */

  /* If we are doing medoid shift, initialize n to the inner product of the
   * image with itself
   */
  if (n) { 
    for (i2 = 0 ; i2 < N2 ; ++ i2) {
      for (i1 = 0 ; i1 < N1 ; ++ i1) {        
        n [i1 + N1 * i2] = vl_quickshift_inner(I,N1,N2,K,
                                               i1,i2,
                                               i1,i2) ;
      }
    }
  }
  
  /* -----------------------------------------------------------------
   *                                                 E = - [oN'*F]', M
   * -------------------------------------------------------------- */
  
  /* 
     D_ij = d(x_i,x_j)
     E_ij = exp(- .5 * D_ij / sigma^2) ;
     F_ij = - E_ij             
     E_i  = sum_j E_ij
     M_di = sum_j X_j F_ij

     E is the parzen window estimate of the density
     0 = dissimilar to everything, windowsize = identical
  */
  
  for (i2 = 0 ; i2 < N2 ; ++ i2) {
    for (i1 = 0 ; i1 < N1 ; ++ i1) {
      
      int j1min = VL_MAX(i1 - R, 0   ) ;
      int j1max = VL_MIN(i1 + R, N1-1) ;
      int j2min = VL_MAX(i2 - R, 0   ) ;
      int j2max = VL_MIN(i2 + R, N2-1) ;      
      
      /* For each pixel in the window compute the distance between it and the
       * source pixel */
      for (j2 = j2min ; j2 <= j2max ; ++ j2) {
        for (j1 = j1min ; j1 <= j1max ; ++ j1) {
          vl_qs_type Dij = vl_quickshift_distance(I,N1,N2,K, i1,i2, j1,j2) ;          
          /* Make distance a similarity */ 
          vl_qs_type Fij = - exp(- Dij / (2*sigma*sigma)) ;

          /* E is E_i above */
          E [i1 + N1 * i2] -= Fij ;
          
          if (M) {
            /* Accumulate votes for the median */
            int k ;
            M [i1 + N1*i2 + (N1*N2) * 0] += j1 * Fij ;
            M [i1 + N1*i2 + (N1*N2) * 1] += j2 * Fij ;
            for (k = 0 ; k < K ; ++k) {
              M [i1 + N1*i2 + (N1*N2) * (k+2)] += 
                I [j1 + N1*j2 + (N1*N2) * k] * Fij ;
            }
          } 
          
        } /* j1 */ 
      } /* j2 */

    }  /* i1 */
  } /* i2 */
  
  /* -----------------------------------------------------------------
   *                                               Find best neighbors
   * -------------------------------------------------------------- */
  
  if (q->medoid) {
    
    /* 
       Qij = - nj Ei - 2 sum_k Gjk Mik
       n is I.^2
    */
    
    /* medoid shift */
    for (i2 = 0 ; i2 < N2 ; ++i2) {
      for (i1 = 0 ; i1 < N1 ; ++i1) {
        
        vl_qs_type sc_best = 0  ;
        /* j1/j2 best are the best indicies for each i */
        vl_qs_type j1_best = i1 ;
        vl_qs_type j2_best = i2 ; 
        
        int j1min = VL_MAX(i1 - R, 0   ) ;
        int j1max = VL_MIN(i1 + R, N1-1) ;
        int j2min = VL_MAX(i2 - R, 0   ) ;
        int j2max = VL_MIN(i2 + R, N2-1) ;      
        
        for (j2 = j2min ; j2 <= j2max ; ++ j2) {
          for (j1 = j1min ; j1 <= j1max ; ++ j1) {            
            
            vl_qs_type Qij = - n [j1 + j2 * N1] * E [i1 + i2 * N1] ;
            int k ;

            Qij -= 2 * j1 * M [i1 + i2 * N1 + (N1*N2) * 0] ;
            Qij -= 2 * j2 * M [i1 + i2 * N1 + (N1*N2) * 1] ;
            for (k = 0 ; k < K ; ++k) {
              Qij -= 2 * 
                I [j1 + j2 * N1 + (N1*N2) * k] *
                M [i1 + i2 * N1 + (N1*N2) * (k + 2)] ;
            }
            
            if (Qij > sc_best) {
              sc_best = Qij ;
              j1_best = j1 ;
              j2_best = j2 ;
            }
          }
        }

        /* parents_i is the linear index of j which is the best pair 
         * dists_i is the score of the best match
         */
        parents [i1 + N1 * i2] = j1_best + N1 * j2_best ;
        dists[i1 + N1 * i2] = sc_best ;
      }
    }  

  } else {
    
    /* Quickshift assigns each i to the closest j which has an increase in the
     * density (E). If there is no j s.t. Ej > Ei, then dists_i == inf (a root
     * node in one of the trees of merges).
     */
    for (i2 = 0 ; i2 < N2 ; ++i2) {
      for (i1 = 0 ; i1 < N1 ; ++i1) {
        
        vl_qs_type E0 = E [i1 + N1 * i2] ;
        vl_qs_type d_best = VL_QS_INF ;
        vl_qs_type j1_best = i1   ;
        vl_qs_type j2_best = i2   ; 
        
        int j1min = VL_MAX(i1 - tR, 0   ) ;
        int j1max = VL_MIN(i1 + tR, N1-1) ;
        int j2min = VL_MAX(i2 - tR, 0   ) ;
        int j2max = VL_MIN(i2 + tR, N2-1) ;      
        
        for (j2 = j2min ; j2 <= j2max ; ++ j2) {
          for (j1 = j1min ; j1 <= j1max ; ++ j1) {            
            if (E [j1 + N1 * j2] > E0) {
              vl_qs_type Dij = vl_quickshift_distance(I,N1,N2,K, i1,i2, j1,j2) ;
              if (Dij <= tau2 && Dij < d_best) {
                d_best = Dij ;
                j1_best = j1 ;
                j2_best = j2 ;
              }
            }
          }
        }
        
        /* parents is the index of the best pair */
        /* dists_i is the minimal distance, inf implies no Ej > Ei within
         * distance tau from the point */
        parents [i1 + N1 * i2] = j1_best + N1 * j2_best ;
        dists[i1 + N1 * i2] = sqrt(d_best) ;
      }
    }  
  }
  
  if (M) vl_free(M) ;
  if (n) vl_free(n) ;
}
Example #26
0
  void DSift::Extract(const float* gray_img, const uint32_t width,
                      const uint32_t height, vector<VlDsiftKeypoint>* frames,
                      vector<float>* descrs, uint32_t* dim)
  {
    if (frames != NULL)
      frames->clear();

    if (descrs == NULL || dim == NULL)
    {
      cerr << "NULL pointer for descriptors and dim" << endl;
      exit(-1);
    }
    descrs->clear();
    *dim = 0;

    const uint32_t max_sz = *(std::max_element(sizes_.begin(), sizes_.end()));
    const uint32_t len_img = width * height;

    if (!has_setup_)
      SetUp(width, height);
    else
    {
      if (width != width_ || height != height_)
      {
        cerr << "ERROR: Image size not matching!" << endl;
        exit(-1);
      }
    }

    for (size_t i = 0; i < sizes_.size(); ++i)
    {
      const uint32_t sz = sizes_[i];

      const int off = std::floor(1.5 * (max_sz - sz));
      vl_dsift_set_bounds(dsift_model_, bound_minx_ + std::max(0, off),
                          bound_miny_ + std::max(0, off),
                          std::min((int) width - 1, bound_maxx_),
                          std::min((int) height - 1, bound_maxy_));

      VlDsiftDescriptorGeometry geom;
      geom.numBinX = DEFAULT_NUM_BIN_X;
      geom.numBinY = DEFAULT_NUM_BIN_Y;
      geom.numBinT = DEFAULT_NUM_BIN_T;
      geom.binSizeX = sz;
      geom.binSizeY = sz;
      vl_dsift_set_geometry(dsift_model_, &geom);

      /*
       {
       int stepX;
       int stepY;
       int minX;
       int minY;
       int maxX;
       int maxY;
       vl_bool useFlatWindow;

       int numFrames = vl_dsift_get_keypoint_num(dsift_model_);
       int descrSize = vl_dsift_get_descriptor_size(dsift_model_);
       VlDsiftDescriptorGeometry g = *vl_dsift_get_geometry(dsift_model_);

       vl_dsift_get_steps(dsift_model_, &stepY, &stepX);
       vl_dsift_get_bounds(dsift_model_, &minY, &minX, &maxY, &maxX);
       useFlatWindow = vl_dsift_get_flat_window(dsift_model_);

       printf(
       "vl_dsift: bounds:            [minX,minY,maxX,maxY] = [%d, %d, %d, %d]\n",
       minX + 1, minY + 1, maxX + 1, maxY + 1);
       printf("vl_dsift: subsampling steps: stepX=%d, stepY=%d\n", stepX,
       stepY);
       printf(
       "vl_dsift: num bins:          [numBinT, numBinX, numBinY] = [%d, %d, %d]\n",
       g.numBinT, g.numBinX, g.numBinY);
       printf("vl_dsift: descriptor size:   %d\n", descrSize);
       printf("vl_dsift: bin sizes:         [binSizeX, binSizeY] = [%d, %d]\n",
       g.binSizeX, g.binSizeY);
       printf("vl_dsift: flat window:       %s\n", VL_YESNO(useFlatWindow));
       printf("vl_dsift: window size:       %g\n",
       vl_dsift_get_window_size(dsift_model_));
       printf("vl_dsift: num of features:   %d\n", numFrames);
       }
       */

      const float sigma = 1.0 * sz / magnif_;
      float* smooth_img = (float*) malloc(sizeof(float) * len_img);
      memset(smooth_img, 0, sizeof(float) * len_img);
      vl_imsmooth_f(smooth_img, width, gray_img, width, height, width, sigma,
                    sigma);

      vl_dsift_process(dsift_model_, smooth_img);

      free(smooth_img);

      const int num_key_pts = vl_dsift_get_keypoint_num(dsift_model_);
      const VlDsiftKeypoint* key_points = vl_dsift_get_keypoints(dsift_model_);
      *dim = vl_dsift_get_descriptor_size(dsift_model_);
      const float* features = vl_dsift_get_descriptors(dsift_model_);

      float* f = (float*) malloc(sizeof(float) * num_key_pts * (*dim));
      cblas_scopy(num_key_pts * (*dim), features, 1, f, 1);
      cblas_sscal(num_key_pts * (*dim), 512.0f, f, 1);

      for (uint32_t d = 0; d < num_key_pts; ++d)
      {
        const float norm = (key_points + d)->norm;
        if (norm < contr_thrd_)
        {
          // remove low contrast
          memset(f + d * (*dim), 0, sizeof(float) * (*dim));
        }
        else
        {
          for (uint32_t j = d * (*dim); j < (d + 1) * (*dim); ++j)
          {
            float tmp = VL_MIN(f[j], 255.0);
            if (!float_desc_)
              tmp = (int) tmp;
            f[j] = tmp;
          }
        }
      }

      if (i == 0)
      {
        if (frames != NULL)
          frames->reserve(num_key_pts * sizes_.size());

        descrs->reserve(num_key_pts * sizes_.size() * (*dim));
      }

      if (frames != NULL)
        frames->insert(frames->end(), key_points, key_points + num_key_pts);

      descrs->insert(descrs->end(), f, f + num_key_pts * (*dim));

      free(f);
    }
  }
/** @brief MEX driver.
 ** @param nout number of MATLAB output arguments.
 ** @param out MATLAB output arguments.
 ** @param nin number of MATLAB input arguments.
 ** @param in MATLAB input arguments.
 **/  
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{
  int M, N, NE ;
  double* Xpt ;
  double* Wpt ; 
  double* EDGESpt ;
  double* RESpt ;
  enum {X=0, W, EDGES} ;

  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */
  if (nin != 3) {
    mexErrMsgTxt("Three arguments required.");
  } else if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }

  if (!mxIsDouble(in[X]) || 
      !mxIsDouble(in[W]) ||
      !mxIsDouble(in[W])) {
    mexErrMsgTxt("The arguments must be real matrices.") ;
  }

  M = mxGetM(in[X]) ;
  N = mxGetN(in[X]) ;
  if( M != mxGetM(in[W]) ||
      N != mxGetN(in[W]) ) {
    mexErrMsgTxt("X and W must have the same dimension.") ;
  }

  if(VL_MIN( mxGetM(in[EDGES]), mxGetN(in[EDGES]) ) != 1) {
    mexErrMsgTxt("EDGES must be a vector.") ;
  }
  
  NE = VL_MAX(mxGetM(in[EDGES]), mxGetN(in[EDGES])) ;

  if(NE < 2) {
    mexErrMsgTxt("At least two edges are required.\n") ;
  }
  
  Xpt = mxGetPr(in[X]) ;
  Wpt = mxGetPr(in[W]) ;
  EDGESpt = mxGetPr(in[EDGES]) ;

  {
    double x = EDGESpt[0] ;
    int j ;
    int ok = 1 ; 
    for(j = 1 ; j < NE ; ++j) {
      ok &= (x < EDGESpt[j]) ;
      x = EDGESpt[j] ;
    }
    if(!ok) mexErrMsgTxt("EDGES must be increasing.") ;
  }

  /*if(nout == 0) return ;*/

  /* If the input is a vector, make it a column. */
  if(M == 1) {
    M = N ; 
    N = 1 ;
  }

  /* Alloc the result. */
  out[0] = mxCreateDoubleMatrix(NE, N, mxREAL) ;
  RESpt = mxGetPr(out[0]) ; 

  /** -----------------------------------------------------------------
   **                                                        Do the job
   ** -------------------------------------------------------------- */
  {
    pairs_t* pairs = mxMalloc(sizeof(pairs_t)*M) ;
    int e, i, j ;
    double c = 0 ;
    double* RESiterator = RESpt ;
    double* Xiterator = Xpt ;
    double* Witerator = Wpt ;

    for(j = 0 ; j < N ; ++j) {              
      e = 0;

      for(i = 0 ; i < M ; ++i) {
        pairs[i].x = *Xiterator++ ;
        pairs[i].w = *Witerator++  ;
      }

      qsort(pairs, M, sizeof(pairs_t), cmp_pairs) ;

      /* Head */
      for(i = 0 ; pairs[i].x < EDGESpt[e] ; ++i) ;

      /* Body */
      while(i < M) {
        c = 0 ;
        e += 1 ;
        if(e == NE) break ;

        for( ;  pairs[i].x < EDGESpt[e] && i < M ; ++i)
          c += pairs[i].w ;

        RESiterator[e-1] = c ;
      }

      /* Tail */
      c = 0 ;
      for( ; pairs[i].x == EDGESpt[NE-1] && i < M ; ++i)
        c += pairs[i].w ;
      RESiterator[NE-1] = c ;

      /* Next column */
      RESiterator += NE ;
    }
    
    mxFree(pairs) ;                      
  }
  return ;
}
Example #28
0
vector<vector<float> > Encoder::extractTunedDSIFT(Mat normMat, Mat landmarks){
	//eye, eyebrow, eye-band,  nose-ver, mouth, left face, right face, jaw, forehead, nose-hor
	//40x20x2, 40x20x2, 100x40, 40x60, 60x40, 40x60,40x60, 50x20, 100x40, 60x40
	vector<vector<float> > ret;
	//hard code max LBP size
	int tunedCellSize = 10;
	int tunedCols, tunedRows;

	vector<float> dsiftCode;
	for (int l = 0; l <= 2; l++){
		for (int i = 0; i < landmarks.cols; i++){
			switch (i){
			case 0:
			case 1:
			case 2:
			case 3:
				tunedCols = 30 + 10*l;
				tunedRows = 10 + 10*l;
				break;			
			case 4:
				tunedCols = 70 + 20*l;
				tunedRows = 30 + 10*l;	
				break;
			case 5:
				tunedCols = 30 + 10*l;
				tunedRows = 40 + 20*l;
				break;
			case 6:
				tunedCols = 40 + 20*l;
				tunedRows = 30 + 10*l;
				break;
			case 7:
			case 8:
				tunedCols = 30 + 10*l;
				tunedRows = 40 + 20*l;
				break;
			case 9:
				tunedCols = 40 + 10*l;
				tunedRows = 20;		
				break;
			case 10:
				tunedCols = 60 + 20*l;
				tunedRows = 30;		
				break;	
			case 11:
				tunedCols = 40 + 10*l;
				tunedRows = 20 + 10*l;		
				break;					
			default:
				cout<<"Wrong landmark size: "<<i<<endl;
				exit(1);
			}
			if (landmarks.at<float>(0, i) > tunedCols/2 && landmarks.at<float>(1, i) > tunedRows/2 && landmarks.at<float>(0, i) + tunedCols/2 < normMat.cols && landmarks.at<float>(1, i) + tunedRows/2 < normMat.rows){
				Mat roi(normMat, Rect(landmarks.at<float>(0, i) - tunedCols/2 , landmarks.at<float>(1, i) - tunedRows/2, tunedCols, tunedRows));
				vector<float> data;
				for (int j = 0; j < roi.cols; j++){
					for (int k = 0; k < roi.rows; k++){
						data.push_back((float)roi.at<unsigned char>(k, j)/255);
					}
				}

				//dsift
				int numFrames ;
				int descrSize ;
				VlDsiftKeypoint const *frames ;
				float const *descrs ;
				VlDsiftFilter *dsift ;
				VlDsiftDescriptorGeometry geom ;
				geom.numBinX = 2 ;
				geom.numBinY = 2 ;
				geom.numBinT = 4 ;
				geom.binSizeX = 4 ;
				geom.binSizeY = 4 ;
				dsift = vl_dsift_new (roi.rows, roi.cols) ;
				vl_dsift_set_geometry(dsift, &geom) ;
				vl_dsift_set_steps(dsift, 2, 2) ;
				vl_dsift_set_flat_window(dsift, 1) ;
				numFrames = vl_dsift_get_keypoint_num (dsift) ;
				descrSize = vl_dsift_get_descriptor_size (dsift) ;
				geom = *vl_dsift_get_geometry (dsift) ;
				vl_dsift_process (dsift, &data[0]) ;
				frames = vl_dsift_get_keypoints (dsift) ;
				descrs = vl_dsift_get_descriptors (dsift) ;	
				//cout<<"frames: "<<numFrames<<" descrs: "<<descrSize<<" cols: "<<roi.cols<<" rows: "<<roi.rows<<endl;
				float tranDescr[128];
				for (int f = 0; f < numFrames; f++){
					vl_dsift_transpose_descriptor (tranDescr, descrs + descrSize * f, geom.numBinT, geom.numBinX, geom.numBinY) ;
					for (int d = 0 ; d < descrSize ; d++) {
						tranDescr[d] = VL_MIN(512.0F * tranDescr[d], 255.0F) ;
						dsiftCode.push_back(tranDescr[d]);
						//cout<<tmpDescr[i]<<" ";
					}
				}
				//if (i != 0 && i != 2){
					ret.push_back(dsiftCode);
					dsiftCode.clear();			
				//}
				 vl_dsift_delete (dsift) ;
			}
			else{
				cout<<"Patch out of bound: "<<landmarks.at<float>(0, i)<<" "<<landmarks.at<float>(1, i)<<endl;
				cout<<"landmark: "<<i<<" Cols: "<<tunedCols<<" Rows: "<<tunedRows<<endl;
				imwrite("tmp/outOfBound.jpg", normMat);
				exit(1);
			}
		}
	}
	return ret;	
}