Skip to main content

Lightweight visual Re-ID (HSV histogram fingerprint) and ROI-focused template matching for object tracking.

Project description

๐Ÿ” ghostfinder

Lightweight Visual Re-Identification & Template Tracker

CPU-friendly Re-ID using color histograms and template matching โ€” fast enough for edge devices.

Python OpenCV License Speed


โœจ Why ghostfinder?

Feature ghostfinder torchreid deep-person-reid
CPU-only (no GPU needed) โœ… โŒ โŒ
Edge device ready (RPi, Jetson) โœ… โŒ โŒ
< 0.5ms per comparison โœ… โŒ โŒ
Template matching fallback โœ… โŒ โŒ
Multi-feature scoring โœ… โœ… โœ…
ROI-constrained search โœ… โŒ โŒ
No training data needed โœ… โŒ โŒ
Lightweight (~300 lines total) โœ… โŒ โŒ

Deep learning Re-ID solutions are powerful but require GPUs and large models. ghostfinder is designed for real-time systems on resource-constrained hardware โ€” where you need to re-identify a target in under 1ms using only CPU.


๐Ÿ“ฆ Installation

pip install ghostfinder

Or install from source:

git clone https://github.com/ByIbos/ghostfinder.git
cd ghostfinder
pip install -e .

๐Ÿš€ Quick Start

Visual Re-Identification

import cv2
from ghostfinder import TargetReID

reid = TargetReID(similarity_threshold=0.55)

# While tracking the target:
reid.update_fingerprint(frame, (x1, y1, x2, y2))

# When target is lost and new detections appear:
best_id, score = reid.find_best_match(frame, all_boxes, all_ids)
if best_id is not None:
    print(f"Target re-identified as ID {best_id} (score: {score:.2f})")

Template Matching Fallback

from ghostfinder import TemplateTracker

tracker = TemplateTracker(match_threshold=0.45, search_margin=150)

# While detector is working:
tracker.update_template(frame, (x1, y1, x2, y2))

# When YOLO/detector fails to find the target:
result = tracker.search(frame, predicted_center=(320, 240))
if result:
    center = result['center']
    score = result['score']
    print(f"Template found at {center} (confidence: {score:.0%})")

Combined Pipeline (Re-ID + Template)

from ghostfinder import TargetReID, TemplateTracker

reid = TargetReID()
template = TemplateTracker()

def handle_target_lost(frame, boxes, ids, kalman_prediction):
    """
    3-layer recovery strategy:
    1. Try Re-ID (color fingerprint matching)
    2. Try Template Matching (visual search)
    3. Use Kalman prediction (coast on momentum)
    """
    # Layer 1: Re-ID
    match_id, score = reid.find_best_match(frame, boxes, ids)
    if match_id is not None:
        return ("REID", match_id, score)

    # Layer 2: Template
    result = template.search(frame, predicted_center=kalman_prediction)
    if result:
        return ("TEMPLATE", result['center'], result['score'])

    # Layer 3: Kalman (handled externally)
    return ("PREDICT", kalman_prediction, 0.0)

๐Ÿ”ง API Reference

TargetReID(similarity_threshold=0.55)

A visual fingerprinting system that stores the target's color histogram, aspect ratio, and area for comparison against new detections.

Methods

Method Returns Description
update_fingerprint(frame, box) None Store/update fingerprint from current crop
compare(frame, box) float Compare one box against fingerprint (0-1)
find_best_match(frame, boxes, ids) (id, score) Find best matching detection
reset() None Clear all stored data

Scoring Breakdown

Component Weight Metric
Color similarity 60% HSV histogram Bhattacharyya distance
Shape similarity 20% Aspect ratio difference
Size similarity 20% Area ratio (min/max)

TemplateTracker(match_threshold=0.45, search_margin=150)

A fallback tracker that stores the last known visual appearance and searches for it using cv2.matchTemplate within a constrained ROI.

Methods

Method Returns Description
update_template(frame, box) None Store current target appearance
search(frame, predicted_center) dict or None Search for template in frame
reset() None Clear all stored data

Search Result Dictionary

{
    'center': (cx, cy),                    # Match center point
    'box': (x1, y1, x2, y2),              # Bounding box
    'score': 0.72,                         # Correlation score (0-1)
    'search_region': (sx1, sy1, sx2, sy2)  # ROI that was searched
}

๐Ÿ“ How It Works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                ghostfinder Pipeline                    โ”‚
โ”‚                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€ TRACKING PHASE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  Target visible โ†’ update fingerprint        โ”‚  โ”‚
โ”‚  โ”‚    โ€ข HSV histogram (30ร—32 bins)             โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Aspect ratio (w/h)                     โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Area (wร—h)                             โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Template crop (grayscale)              โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                      โ”‚                            โ”‚
โ”‚                  Target Lost!                     โ”‚
โ”‚                      โ”‚                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€ RECOVERY PHASE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                                             โ”‚  โ”‚
โ”‚  โ”‚  Layer 1: Re-ID (TargetReID)                โ”‚  โ”‚
โ”‚  โ”‚    Compare all detections vs fingerprint     โ”‚  โ”‚
โ”‚  โ”‚    Score = 0.6ร—color + 0.2ร—shape + 0.2ร—size โ”‚  โ”‚
โ”‚  โ”‚    Match if score > threshold (0.55)         โ”‚  โ”‚
โ”‚  โ”‚                                             โ”‚  โ”‚
โ”‚  โ”‚  Layer 2: Template (TemplateTracker)         โ”‚  โ”‚
โ”‚  โ”‚    Search ROI = predicted_center ยฑ margin    โ”‚  โ”‚
โ”‚  โ”‚    cv2.matchTemplate (TM_CCOEFF_NORMED)     โ”‚  โ”‚
โ”‚  โ”‚    Match if correlation > threshold (0.45)   โ”‚  โ”‚
โ”‚  โ”‚                                             โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โšก Performance

Benchmarked on a Raspberry Pi 4B (no GPU):

Operation Time Notes
update_fingerprint() ~0.3ms Per frame
compare() (single box) ~0.4ms Per candidate
find_best_match() (10 boxes) ~3ms Worst case
search() (template) ~1-3ms Depends on ROI size

๐ŸŽฏ Use Cases

  • ๐Ÿš Drone Tracking โ€” Re-acquire target after occlusion
  • ๐Ÿ“น Surveillance โ€” Track individuals across camera blind spots
  • ๐Ÿค– Robot Vision โ€” Persistent object following
  • ๐Ÿญ Industrial โ€” Track parts on conveyor belts
  • ๐ŸŽฏ Sports Analytics โ€” Player tracking through crowds

๐Ÿ“œ License

MIT License โ€” use it anywhere, commercially or personally.


Built with โค๏ธ by ByIbos โ€” extracted from the Auto-ReID Drone Tracker project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ghostfinder-1.1.0.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ghostfinder-1.1.0-py3-none-any.whl (12.6 kB view details)

Uploaded Python 3

File details

Details for the file ghostfinder-1.1.0.tar.gz.

File metadata

  • Download URL: ghostfinder-1.1.0.tar.gz
  • Upload date:
  • Size: 12.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for ghostfinder-1.1.0.tar.gz
Algorithm Hash digest
SHA256 842475255e006b0188d54102c6c9c2cae68ce14b0cb2c0dd5c9afe21a82fde3f
MD5 fb208cac1becc42721acd7b7cd913d03
BLAKE2b-256 31946fefe50c6b114c077459ecfc02e7b403fcd66c3adfe0b84d2ba458adf3e8

See more details on using hashes here.

File details

Details for the file ghostfinder-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: ghostfinder-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for ghostfinder-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ca448496d36692a0baf023e126ab259a9e93a47076e7eb03d6bb1665c946cb9d
MD5 05c74ad23578b5f62500483622c72965
BLAKE2b-256 8f6c404c1c3304b526fa08b38c1cc06f7c26d407683c59f01e67cf5792df8efa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page