void BinarySegmentation::binarize(Mat input,OutputArray output, vector<Scalar> samples) { bool first = true; Mat binarized(input.size(),CV_8U); for (Scalar sample : samples) { tuple<Scalar, Scalar> lowerUpper = bounds(sample); inRange(input, get<0>(lowerUpper),get<1>(lowerUpper), binarized); if (first) { binarized.copyTo(output); first = false; } else add(binarized, output, output); } }
void operator()(const hypergraph_type& source, hypergraph_type& target) { // first, copy... target = source; if (! source.is_valid()) return; phrase_type binarized(2); hypergraph_type::edge_type::node_set_type tails(2); // we will traverse source-side in order to avoid confusion with newly created nodes... removed_type removed(source.edges.size(), false); position_set_type positions; node_chart_type node_chart; label_chart_type label_chart; label_map.clear(); node_map.clear(); hypergraph_type::node_set_type::const_iterator niter_end = source.nodes.end(); for (hypergraph_type::node_set_type::const_iterator niter = source.nodes.begin(); niter != niter_end; ++ niter) { const hypergraph_type::node_type& node_source = *niter; hypergraph_type::node_type::edge_set_type::const_iterator eiter_end = node_source.edges.end(); for (hypergraph_type::node_type::edge_set_type::const_iterator eiter = node_source.edges.begin(); eiter != eiter_end; ++ eiter) { const hypergraph_type::edge_type& edge_source = source.edges[*eiter]; if (edge_source.tails.size() <= 2) continue; removed[edge_source.id] = true; // we will create nodes in a chart structure, and exhaustively enumerate edges symbol_set_type rhs_sorted(edge_source.rule->rhs); tail_set_type tails_sorted(edge_source.tails); // first, compute non-terminal spans... positions.clear(); int pos = 0; for (size_t i = 0; i != rhs_sorted.size(); ++ i) if (rhs_sorted[i].is_non_terminal()) { const int non_terminal_index = rhs_sorted[i].non_terminal_index(); tails_sorted[pos] = edge_source.tails[utils::bithack::branch(non_terminal_index == 0, pos, non_terminal_index - 1)]; rhs_sorted[i] = rhs_sorted[i].non_terminal(); positions.push_back(i); ++ pos; } if (positions.size() != edge_source.tails.size()) throw std::runtime_error("invalid edge: # of non-terminals and tails size do not match"); // seond, enumerate chart to compute node and edges... node_chart.clear(); node_chart.resize(positions.size() + 1, hypergraph_type::invalid); label_chart.clear(); label_chart.resize(positions.size() + 1); for (size_t i = 0; i != positions.size(); ++ i) { node_chart(i, i + 1) = tails_sorted[i]; label_chart(i, i + 1) = rhs_sorted[positions[i]]; } for (size_t length = 2; length < positions.size(); ++ length) for (size_t first = 0; first + length <= positions.size(); ++ first) { const size_t last = first + length; const symbol_set_type subrhs(rhs_sorted.begin() + positions[first], rhs_sorted.begin() + positions[last - 1] + 1); const tail_set_type subtails(tails_sorted.begin() + first, tails_sorted.begin() + last); std::pair<label_map_type::iterator, bool> result_label = label_map.insert(std::make_pair(subtails, symbol_type())); if (result_label.second) { const symbol_type::piece_type left = label_chart(first, last - 1).non_terminal_strip(); const symbol_type::piece_type right = label_chart(last - 1, last).non_terminal_strip(); if (length > 2) result_label.first->second = '[' + std::string(left.begin(), left.end() - 1) + '+' + right + "^]"; else result_label.first->second = '[' + std::string(left) + '+' + right + "^]"; } std::pair<node_map_type::iterator, bool> result_node = node_map.insert(std::make_pair(tail_symbol_pair_type(subtails, subrhs), 0)); if (result_node.second) result_node.first->second = target.add_node().id; const symbol_type lhs = result_label.first->second; const hypergraph_type::id_type head = result_node.first->second; node_chart(first, last) = head; label_chart(first, last) = lhs; // if newly created, then, create edges if (result_node.second) for (size_t middle = first + 1; middle != last; ++ middle) { // [first, middle) and [middle, last) tails.front() = node_chart(first, middle); tails.back() = node_chart(middle, last); const size_t middle_first = positions[middle - 1] + 1; const size_t middle_last = positions[middle]; binarized.clear(); binarized.push_back(label_chart(first, middle)); binarized.insert(binarized.end(), rhs_sorted.begin() + middle_first, rhs_sorted.begin() + middle_last); binarized.push_back(label_chart(middle, last)); hypergraph_type::edge_type& edge_new = target.add_edge(tails.begin(), tails.end()); edge_new.rule = rule_type::create(rule_type(lhs, binarized.begin(), binarized.end())); target.connect_edge(edge_new.id, head); } } // root... { const size_t first = 0; const size_t last = positions.size(); const hypergraph_type::id_type head = node_source.id; const symbol_type& lhs = edge_source.rule->lhs; node_chart(first, last) = head; label_chart(first, last) = lhs; for (size_t middle = first + 1; middle != last; ++ middle) { // [first, middle) and [middle, last) tails.front() = node_chart(first, middle); tails.back() = node_chart(middle, last); binarized.clear(); const size_t prefix_first = 0; const size_t prefix_last = positions[first]; binarized.insert(binarized.end(), rhs_sorted.begin() + prefix_first, rhs_sorted.begin() + prefix_last); binarized.push_back(label_chart(first, middle)); const size_t middle_first = positions[middle - 1] + 1; const size_t middle_last = positions[middle]; binarized.insert(binarized.end(), rhs_sorted.begin() + middle_first, rhs_sorted.begin() + middle_last); binarized.push_back(label_chart(middle, last)); const size_t suffix_first = positions[last - 1] + 1; const size_t suffix_last = rhs_sorted.size(); binarized.insert(binarized.end(), rhs_sorted.begin() + suffix_first, rhs_sorted.begin() + suffix_last); hypergraph_type::edge_type& edge_new = target.add_edge(tails.begin(), tails.end()); edge_new.rule = rule_type::create(rule_type(lhs, binarized.begin(), binarized.end())); edge_new.features = edge_source.features; edge_new.attributes = edge_source.attributes; target.connect_edge(edge_new.id, head); } } } } // further resize... removed.resize(target.edges.size(), false); hypergraph_type graph_removed; topologically_sort(target, graph_removed, filter(removed)); target.swap(graph_removed); }