Example #1
0
void BBFind::squash(Map2 &map, float scaleMin, float scaleMax)
{
   // Overloaded to work on Map2 or Map3. Normalizes, but sets
   // initial min / max values to given arguments. If the given
   // range is larger than the data's range, the data is scaled
   // down proportionally. Otherwise, it just normalizes to the
   // given range.

   int mapWidth = (int)map[0].size();
   int mapHeight = (int)map.size();

   float maxVal = scaleMax;
   float minVal = scaleMin;

   for(int x = 0; x < mapWidth; x++)
   {
      for(int y = 0; y < mapHeight; y++)
      {
         float val = map[y][x];
         maxVal = val > maxVal ? val : maxVal;
         minVal = val < minVal ? val : minVal;
      }
   }
   float range = maxVal - minVal;
   #ifdef PV_USE_OPENMP_THREADS
      #pragma omp parallel for
   #endif
   for(int x = 0; x < mapWidth; x++)
   {
      for(int y = 0; y < mapHeight; y++)
      {
         map[y][x] = scaleMin + ((map[y][x] - minVal) / range) * scaleMax;
      }
   }
}
Example #2
0
float BBFind::sigmoidedRMS(const Map2 confMap, const Rectangle &bounds)
{
   // Takes the RMS of the given sub area and applies a sigmoid to
   // smoothly cap values at 1.0

	int mapWidth = confMap[0].size();
	int mapHeight = confMap.size();
	float sum = 0.0f;
	for(int x = 0; x < bounds.width; x++)
	{
		for(int y = 0; y < bounds.height; y++)
		{
			int _x = bounds.left() + x;
			int _y = bounds.top()  + y;
			if(_x < 0 || _x >= mapWidth || _y < 0 || _y >= mapHeight) continue;
			sum += pow(confMap[_y][_x], 2);
		}
	}
	float avg = sqrt(sum / (mapWidth*mapHeight));
	float e = exp(1);
	// This is a very easy curve that still soft caps at 1.0.
	// Combined with the increaseContrast function, it allows
   // values > 0.85 to bring the average up based on the contrast argument.
	return  (1.0f / (1.0f + pow(e,-e*avg)) - 0.5f) * 2.0f;
}
Example #3
0
BBFind::Map2 BBFind::scale(const Map2 &source, int newWidth, int newHeight, bool bilinear)
{
   // Rescales the map's dimensions using either
   // bilinear interpolation or nearest neighbor.

   Map2 result(newHeight);
   int sourceWidth = source[0].size();
   int sourceHeight = source.size();

   if(bilinear) // Bilinear scaling
   {
      for(int j = 0; j < newHeight; j++)
      {
         result[j].resize(newWidth);
         for(int i = 0; i < newWidth; i++)
         {
            float xSource = i / (float)(newWidth-1) * (sourceWidth-1);
            float ySource = j / (float)(newHeight-1) * (sourceHeight-1);

            int leftIndex   = (int)xSource;
            int rightIndex  = (int)ceil(xSource);
            int topIndex    = (int)ySource;
            int bottomIndex = (int)ceil(ySource);

            if(topIndex < 0)  topIndex = 0;
            if(leftIndex < 0) leftIndex = 0;
            if(rightIndex >= sourceWidth)   rightIndex = sourceWidth-1;
            if(bottomIndex >= sourceHeight) bottomIndex = sourceHeight-1;

            float xAlign = xSource - leftIndex;
            float yAlign = ySource - topIndex;

            float tl = source[topIndex][leftIndex]     * (1.0f - xAlign) * (1.0f - yAlign);
            float tr = source[topIndex][rightIndex]    * xAlign * (1.0f - yAlign);
            float bl = source[bottomIndex][leftIndex]  * (1.0f - xAlign) * yAlign;
            float br = source[bottomIndex][rightIndex] * xAlign * yAlign;
            result[j][i] = tl+tr+bl+br;
         }
      }
   }
   else // Nearest neighbor scaling, no interpolation
   {
      float xRatio = sourceWidth / (float)(newWidth);
      float yRatio = sourceHeight / (float)(newHeight);

      #ifdef PV_USE_OPENMP_THREADS
			#pragma omp parallel for
		#endif
      for(int j = 0; j < newHeight; j++)
      {
         result[j].resize(newWidth);
         for(int i = 0; i < newWidth; i++)
         {
            result[j][i] = source[(int)(j*yRatio)][(int)(i*xRatio)];
         }
      }
   }
   return result;
}
Example #4
0
BBFind::Map2 BBFind::applyThreshold(const Map2 confMap, float threshold)
{
   // Clips any values below threshold
   // TODO: Can this just modify the map in-place?
	int mapWidth = confMap[0].size();
	int mapHeight = confMap.size();
	Map2 resultMap = confMap;

   #ifdef PV_USE_OPENMP_THREADS
		#pragma omp parallel for
   #endif
   for(int x = 0; x < mapWidth; x++)
	{
		for(int y = 0; y < mapHeight; y++)
		{
         resultMap[y][x] = (confMap[y][x] >= threshold ? confMap[y][x] : 0.0f);
		}
	}
	return resultMap;
}
Example #5
0
BBFind::Map2 BBFind::makeEdgeDistanceMap(const Map2 confMap)
{
   // Modified Dijkstra map algorithm based on:
   // http://www.roguebasin.com/index.php?title=The_Incredible_Power_of_Dijkstra_Maps
   // The original algorithm finds nearest distance to a goal.
   // This modified version finds the larger distance, horizontal or vertical,
   // to a 0 confidence value (used to find object edges after threshold clipping)

	int mapWidth = confMap[0].size();
	int mapHeight = confMap.size();
	int maxVal = std::max(mapWidth, mapHeight);

   Map2 horizMap(mapHeight);
   Map2 vertMap(mapHeight);

   for(int y = 0; y < mapHeight; y++)
	{
      horizMap[y].resize(mapWidth);
      vertMap[y].resize(mapWidth);
		for(int x = 0; x < mapWidth; x++)
		{
         if(confMap[y][x] > 0)
         {
            horizMap[y][x] = maxVal;
            vertMap[y][x] = maxVal;
         }
      }
   }

   // Finds the shortest distance to 0 conf value in horizontal and vertical direction,
   // and stores the biggest one into result. This allows long, thin confidence chunks
   // to avoid clipping

   bool changed = true;
   while(changed)
   {
      changed = false;
      for(int y = 1; y < mapHeight-1; y++)
      {
         for(int x = 1; x < mapWidth-1; x++)
         {
            float lowest = horizMap[y][x];
            lowest = std::min(lowest, horizMap[y][x-1]);
            lowest = std::min(lowest, horizMap[y][x+1]);

            if(horizMap[y][x] > lowest+1)
            {
               horizMap[y][x] = lowest + 1;
               changed = true;
            }
         }
      }
   }

   changed = true;
   while(changed)
   {
      changed = false;
      for(int y = 1; y < mapHeight-1; y++)
      {
         for(int x = 1; x < mapWidth-1; x++)
         {
            float lowest = vertMap[y][x];
            lowest = std::min(lowest, vertMap[y-1][x]);
            lowest = std::min(lowest, vertMap[y+1][x]);

            if(vertMap[y][x] > lowest+1)
            {
               vertMap[y][x] = lowest + 1;
               changed = true;
            }
         }
      }
   }

   Map2 resultMap = horizMap;

   #ifdef PV_USE_OPENMP_THREADS
		#pragma omp parallel for
   #endif
   for(int y = 0; y < mapHeight; y++)
	{
		for(int x = 0; x < mapWidth; x++)
		{
         if(vertMap[y][x] > resultMap[y][x])
         {
            resultMap[y][x] = vertMap[y][x];
         }
      }
   }

	return resultMap;
}
Example #6
0
void intersectValues(Map const& map, Map2 const& map2, DotProductResult& dotResult) {
  if (map.size() < map2.size())
    intersectValues(map.begin(), map.end(), map2, dotResult);
  else
    intersectValues(map, map2.begin(), map2.end(), dotResult);
}