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); } } }
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; } }