Example #1
0
void GetWindows(const cv::Mat& integral_image, std::vector<Shape::Rectangle>& rectangles, const float threshold, const float dist_threshold, std::vector<Shape::Rectangle>& windows, bool append)
{
  // Init windows.
  if (windows.capacity() < rectangles.size()) windows.reserve(rectangles.size());
  if (!append) windows.clear();

  // Create disjoint set vector.
  DisjointSetVector<Shape::Rectangle> disjoint_set(rectangles);

  // Compute edges.
  std::vector<Edge > edges;
  GetEdges<integral_type, mean_type>(integral_image, disjoint_set, edges);

  // Sort edges.
  std::sort(edges.begin(), edges.end());

  // Merge nodes.
  for (std::vector<Edge >::iterator edge = edges.begin(); edge != edges.end(); edge++)
  {
    edge->Union((Edge::weight_type)threshold);
  }

  // Get segments.
  std::vector<std::vector<std::vector<Shape::Rectangle>::iterator> > sparse_segments(disjoint_set.size());
  for (DisjointSetVector<Shape::Rectangle>::iterator node = disjoint_set.begin(); node != disjoint_set.end(); node++)
  {
    DisjointSetVector<Shape::Rectangle>::pointer root = node->FindRoot();
    const size_t id = root - &*disjoint_set.begin();
    sparse_segments[id].push_back(node->value());
  }

  size_t min_area = (integral_image.rows - 1) * (integral_image.cols - 1) / 400;
  for (std::vector<std::vector<std::vector<Shape::Rectangle>::iterator> >::iterator sparse_segment = sparse_segments.begin(); sparse_segment != sparse_segments.end(); sparse_segment++)
  {
    if (!sparse_segment->size() || (sparse_segment->size() == 1 && RectangleArea(*(*sparse_segment)[0]) < min_area)) continue;
    Shape::Rectangle window = {integral_image.cols, integral_image.rows, 0, 0};
    for (std::vector<std::vector<Shape::Rectangle>::iterator>::iterator rectangle = sparse_segment->begin(); rectangle != sparse_segment->end(); rectangle++)
    {
      const Shape::Rectangle& r = **rectangle;
      window.x1 = std::min(window.x1, r.x1);
      window.y1 = std::min(window.y1, r.y1);
      window.x2 = std::max(window.x2, r.x2);
      window.y2 = std::max(window.y2, r.y2);
    }
    windows.push_back(window);
  }

  // Also include nearby windows.
  if (dist_threshold <= 0) return;
  const int end = windows.size();
  for (int i1 = 0; i1 < end; i1++)
  {
    for (int i2 = i1 + 1; i2 < end; i2++)
    {
      const Shape::Rectangle& window1 = windows[i1];
      const Shape::Rectangle& window2 = windows[i2];

      // No need to merge inside windows.
      if (IsRectangleInside(window1, window2) || IsRectangleInside(window2, window1) || NormalizedRectangleDist(window2, window1) > 0.5) continue;
      Shape::Rectangle window = {std::min(window1.x1, window2.x1), std::min(window1.y1, window2.y1), std::max(window1.x2, window2.x2), std::max(window1.y2, window2.y2)};
      windows.push_back(window);
    }
  }
}
Example #2
0
void GetWindows(const cv::Mat& integral_image, std::vector<Shape::Rectangle>& rectangles, std::vector<float>& thresholds, const float dist_threshold, std::vector<Shape::Rectangle>& windows)
{
  // Init windows.
  if (windows.capacity() < rectangles.size()) windows.reserve(rectangles.size());
  windows.clear();

  // Create disjoint set vector.
  DisjointSetVector<Shape::Rectangle> disjoint_set(rectangles);

  // Compute edges.
  std::vector<Edge > edges;
  GetEdges<integral_type, mean_type>(integral_image, disjoint_set, edges);

  // Sort edges.
  std::sort(edges.begin(), edges.end());

  // Sort threshold.
  std::sort(thresholds.begin(), thresholds.end());

  // Merge nodes.
  std::vector<std::vector<std::vector<Shape::Rectangle>::iterator> > sparse_segments(disjoint_set.size());
  std::vector<size_t> sparse_segment_sizes(disjoint_set.size(), 0);
  std::vector<Edge > unmerged_edges;
  unmerged_edges.reserve(edges.size());
  const size_t min_area = (integral_image.rows - 1) * (integral_image.cols - 1) / 400;

  std::vector<Shape::Rectangle> small_windows;
  if (dist_threshold > 0) small_windows.reserve(rectangles.size());
  for (int k = 0; k < thresholds.size(); k++)
  {
    const float threshold = thresholds[k];
    std::vector<Edge >& merging = k & 1 ? unmerged_edges : edges;
    std::vector<Edge >& unmerged = k & 1 ? edges : unmerged_edges;
    unmerged.clear();
    for (std::vector<Edge >::iterator edge = merging.begin(); edge != merging.end(); edge++)
    {
      if (!edge->Union((Edge::weight_type)threshold))
      {
        unmerged.push_back(*edge);
      }
    }

    // Get segments.
    for (DisjointSetVector<Shape::Rectangle>::iterator node = disjoint_set.begin(); node != disjoint_set.end(); node++)
    {
      DisjointSetVector<Shape::Rectangle>::pointer root = node->FindRoot();
      const size_t id = root - &*disjoint_set.begin();
      sparse_segments[id].push_back(node->value());
    }

    // Get windows.
    std::vector<size_t>::iterator sparse_segment_size = sparse_segment_sizes.begin();
    for (std::vector<std::vector<std::vector<Shape::Rectangle>::iterator> >::iterator sparse_segment = sparse_segments.begin(); sparse_segment != sparse_segments.end(); sparse_segment++, sparse_segment_size++)
    {
      if (sparse_segment->size() && sparse_segment->size() != *sparse_segment_size)
      {
        if (sparse_segment->size() != 1 || RectangleArea(*(*sparse_segment)[0]) > min_area)
        {
          Shape::Rectangle window = {integral_image.cols, integral_image.rows, 0, 0};
          for (std::vector<std::vector<Shape::Rectangle>::iterator>::iterator rectangle = sparse_segment->begin(); rectangle != sparse_segment->end(); rectangle++)
          {
            const Shape::Rectangle& r = **rectangle;
            window.x1 = std::min(window.x1, r.x1);
            window.y1 = std::min(window.y1, r.y1);
            window.x2 = std::max(window.x2, r.x2);
            window.y2 = std::max(window.y2, r.y2);
          }
          windows.push_back(window);
        }
        else if (!k && dist_threshold > 0)
        {
          Shape::Rectangle window = {integral_image.cols, integral_image.rows, 0, 0};
          for (std::vector<std::vector<Shape::Rectangle>::iterator>::iterator rectangle = sparse_segment->begin(); rectangle != sparse_segment->end(); rectangle++)
          {
            const Shape::Rectangle& r = **rectangle;
            window.x1 = std::min(window.x1, r.x1);
            window.y1 = std::min(window.y1, r.y1);
            window.x2 = std::max(window.x2, r.x2);
            window.y2 = std::max(window.y2, r.y2);
          }
          small_windows.push_back(window);
        }
      }
      *sparse_segment_size = sparse_segment->size();
      sparse_segment->clear();
    }
  }

  // Also include nearby windows.
  if (dist_threshold <= 0) return;
  const int end = windows.size();
  for (int i1 = 0; i1 < end; i1++)
  {
    for (int i2 = i1 + 1; i2 < end; i2++)
    {
      const Shape::Rectangle& window1 = windows[i1];
      const Shape::Rectangle& window2 = windows[i2];

      // No need to merge inside windows.
      if (IsRectangleInside(window1, window2) || IsRectangleInside(window2, window1) || NormalizedRectangleDist(window2, window1) > dist_threshold) continue;
      Shape::Rectangle window = {std::min(window1.x1, window2.x1), std::min(window1.y1, window2.y1), std::max(window1.x2, window2.x2), std::max(window1.y2, window2.y2)};
      windows.push_back(window);
    }

    for (std::vector<Shape::Rectangle>::iterator small_window = small_windows.begin(); small_window != small_windows.end(); small_window++)
    {
      const Shape::Rectangle& window1 = windows[i1];
      const Shape::Rectangle& window2 = *small_window;

      // No need to merge inside windows.
      if (IsRectangleInside(window1, window2) || IsRectangleInside(window2, window1) || NormalizedRectangleDist(window2, window1) > dist_threshold) continue;
      Shape::Rectangle window = {std::min(window1.x1, window2.x1), std::min(window1.y1, window2.y1), std::max(window1.x2, window2.x2), std::max(window1.y2, window2.y2)};
      windows.push_back(window);
    }
  }
}
   int run_test_case( int casenum__ ) {
      long long starttime__ = get_time();
      switch( casenum__ ) {
      case 0: {
         string known[]            = {"NN",  "NN"};
         int expected__            = 3;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
      case 1: {
         string known[]            = {"YNY",  "NYN",  "YNY"};
         int expected__            = 1;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
      case 2: {
         string known[]            = {"YY",  "YY",  "YY",  "YY"};
         int expected__            = 0;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
      case 3: {
         string known[]            = {"NNNNNNNNNN"};
         int expected__            = 10;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
      case 4: {
         string known[]            = {"NNYYYNN",  "NNNNNYN",  "YYNNNNY",  "NNNYNNN",  "YYNNNNY"};
         int expected__            = 2;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }

      // custom cases

/*
      case 5: {
         string known[]            = ;
         int expected__            = ;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
*/
/*
      case 6: {
         string known[]            = ;
         int expected__            = ;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
*/
/*
      case 7: {
         string known[]            = ;
         int expected__            = ;

         return verify_case( casenum__, starttime__, expected__, RectangleArea().minimumQueries( vector <string>( known, known + ( sizeof known / sizeof(string) ) ) ) );
      }
*/
      default:
         return -1;
      }
   }