merge_by_appearance

merge_by_appearance#

rapidtools.processing.reid.merge_by_appearance(candidates: Sequence[ReidCandidate], crops: Mapping[str, Image], embedder: AppearanceEmbedder, max_distance_m: float = 6.0, min_similarity: float | None = None, require_different_sequence: bool = True) → list[list[str]][source]#

Group candidates that are close together and look alike.

Candidate pairs from pairs_to_compare() whose crops reach a cosine similarity of min_similarity are joined with union-find, most similar pairs first. A join that would put two candidates sharing a frame into one group is refused, so the shared-frame rule holds through chains as well. Each crop is embedded once; candidates without a crop stay alone.

Parameters:
  • candidates – Candidate records with unique keys.

  • crops – Best crop per candidate key; keys may be missing.

  • embedder – Produces unit-norm embeddings of the crops.

  • max_distance_m – Largest separation of two candidates to compare.

  • min_similarity – Cosine similarity at or above which a pair merges. None takes recommended_min_similarity() for the embedder’s backbone.

  • require_different_sequence – Only compare candidates from different capture sequences.

Returns:

list[list[str]] – Groups of candidate keys covering every candidate, singletons included, in first-appearance order.

Example

>>> groups = merge_by_appearance(
...     candidates, crops, AppearanceEmbedder()
... )
>>> [g for g in groups if len(g) > 1]
[['car-12', 'car-57']]