def build(matcher_config):
  """Builds a matcher object based on the matcher config.

  Args:
    matcher_config: A matcher.proto object containing the config for the desired
      Matcher.

  Returns:
    Matcher based on the config.

  Raises:
    ValueError: On empty matcher proto.
  """
  if not isinstance(matcher_config, matcher_pb2.Matcher):
    raise ValueError('matcher_config not of type matcher_pb2.Matcher.')
  if matcher_config.WhichOneof('matcher_oneof') == 'argmax_matcher':
    matcher = matcher_config.argmax_matcher
    matched_threshold = unmatched_threshold = None
    if not matcher.ignore_thresholds:
      matched_threshold = matcher.matched_threshold
      unmatched_threshold = matcher.unmatched_threshold
    return argmax_matcher.ArgMaxMatcher(
        matched_threshold=matched_threshold,
        unmatched_threshold=unmatched_threshold,
        negatives_lower_than_unmatched=matcher.negatives_lower_than_unmatched,
        force_match_for_each_row=matcher.force_match_for_each_row,
        use_matmul_gather=matcher.use_matmul_gather)
  if matcher_config.WhichOneof('matcher_oneof') == 'bipartite_matcher':
    matcher = matcher_config.bipartite_matcher
    return bipartite_matcher.GreedyBipartiteMatcher(matcher.use_matmul_gather)
  raise ValueError('Empty matcher.')
    def test_get_expected_matches_with_all_rows_be_default(self):
        similarity_matrix = tf.constant([[0.50, 0.1, 0.8], [0.15, 0.2, 0.3]])
        expected_match_results = [-1, 1, 0]

        matcher = bipartite_matcher.GreedyBipartiteMatcher()
        match = matcher.match(similarity_matrix)
        with self.test_session() as sess:
            match_results_out = sess.run(match._match_results)
            self.assertAllEqual(match_results_out, expected_match_results)
    def test_get_expected_matches_with_only_one_valid_row_at_bottom(self):
        similarity_matrix = tf.constant([[0.15, 0.2, 0.3], [0.50, 0.1, 0.8]])
        valid_rows = tf.constant([False, True], dtype=tf.bool)
        expected_match_results = [-1, -1, 0]

        matcher = bipartite_matcher.GreedyBipartiteMatcher()
        match = matcher.match(similarity_matrix, valid_rows)
        with self.test_session() as sess:
            match_results_out = sess.run(match._match_results)
            self.assertAllEqual(match_results_out, expected_match_results)
    def test_get_no_matches_with_zero_valid_rows(self):
        similarity_matrix = tf.constant([[0.50, 0.1, 0.8], [0.15, 0.2, 0.3]])
        valid_rows = tf.zeros([2], dtype=tf.bool)
        expected_match_results = [-1, -1, -1]

        matcher = bipartite_matcher.GreedyBipartiteMatcher()
        match = matcher.match(similarity_matrix, valid_rows)
        with self.test_session() as sess:
            match_results_out = sess.run(match._match_results)
            self.assertAllEqual(match_results_out, expected_match_results)
def create_target_assigner(reference,
                           stage=None,
                           negative_class_weight=1.0,
                           use_matmul_gather=False):
    """Factory function for creating standard target assigners.

  Args:
    reference: string referencing the type of TargetAssigner.
    stage: string denoting stage: {proposal, detection}.
    negative_class_weight: classification weight to be associated to negative
      anchors (default: 1.0)
    use_matmul_gather: whether to use matrix multiplication based gather which
      are better suited for TPUs.

  Returns:
    TargetAssigner: desired target assigner.

  Raises:
    ValueError: if combination reference+stage is invalid.
  """
    if reference == 'Multibox' and stage == 'proposal':
        similarity_calc = sim_calc.NegSqDistSimilarity()
        matcher = bipartite_matcher.GreedyBipartiteMatcher()
        box_coder = mean_stddev_box_coder.MeanStddevBoxCoder()

    elif reference == 'FasterRCNN' and stage == 'proposal':
        similarity_calc = sim_calc.IouSimilarity()
        matcher = argmax_matcher.ArgMaxMatcher(
            matched_threshold=0.7,
            unmatched_threshold=0.3,
            force_match_for_each_row=True,
            use_matmul_gather=use_matmul_gather)
        box_coder = faster_rcnn_box_coder.FasterRcnnBoxCoder(
            scale_factors=[10.0, 10.0, 5.0, 5.0])

    elif reference == 'FasterRCNN' and stage == 'detection':
        similarity_calc = sim_calc.IouSimilarity()
        # Uses all proposals with IOU < 0.5 as candidate negatives.
        matcher = argmax_matcher.ArgMaxMatcher(
            matched_threshold=0.5,
            negatives_lower_than_unmatched=True,
            use_matmul_gather=use_matmul_gather)
        box_coder = faster_rcnn_box_coder.FasterRcnnBoxCoder(
            scale_factors=[10.0, 10.0, 5.0, 5.0])

    elif reference == 'FastRCNN':
        similarity_calc = sim_calc.IouSimilarity()
        matcher = argmax_matcher.ArgMaxMatcher(
            matched_threshold=0.5,
            unmatched_threshold=0.1,
            force_match_for_each_row=False,
            negatives_lower_than_unmatched=False,
            use_matmul_gather=use_matmul_gather)
        box_coder = faster_rcnn_box_coder.FasterRcnnBoxCoder()

    else:
        raise ValueError('No valid combination of reference and stage.')

    return TargetAssigner(similarity_calc,
                          matcher,
                          box_coder,
                          negative_class_weight=negative_class_weight)