DEV Community

Cover image for ⚡ Lightning-Fast Face Recognition with InsightFace + SORT + Qdrant
Tejas Patil
Tejas Patil

Posted on

⚡ Lightning-Fast Face Recognition with InsightFace + SORT + Qdrant

Most face-recognition systems fail in real life.
Why? Because they try to recognize faces every single frame — slow, unstable, and guaranteed to misidentify people the moment they move their head.

The solution is not “more detection.”
The solution is SORT.

🚀 Why SORT Changes Everything

SORT (Simple Online & Real-Time Tracking) gives you:

  • Persistent IDs across frames
  • No flickering names when a person turns their head
  • High FPS (because you don’t detect every frame)
  • Stable embeddings (recognize once → reuse for multiple frames)

Think of SORT as the glue that holds your face-recognition pipeline together.

🔥 The Recognition Pipeline (Super Simple)
1️⃣ Detect faces only every N frames

if frame_id % 3 == 0:
    faces = face_app.get(frame)
Enter fullscreen mode Exit fullscreen mode

2️⃣ Use SORT to track faces between detections
tracked = tracker.update(detections)

3️⃣ Assign embeddings via IoU matching

for det_bbox, det_emb in last_face_map.items():
    if compute_iou(track_bbox, det_bbox) > 0.45:
        track_embeddings[track_id] = det_emb
Enter fullscreen mode Exit fullscreen mode

4️⃣ Search identity from Qdrant

hits = client.search(collection_name="faces", query_vector=embedding.tolist(), limit=1)
if hits and hits[0].score > 0.75:
    name = hits[0].payload["name"]
Enter fullscreen mode Exit fullscreen mode

5️⃣ Register new users instantly

if key=='r' and unknown_face:
    client.upsert("faces", [PointStruct(id=uuid4(), vector=emb.tolist(), payload={"name": name})])
Enter fullscreen mode Exit fullscreen mode

🎯 Why This Works So Damn Well
Traditional Method Our SORT Method
Detect every frame → low FPS Detect periodically → high FPS
Identity flickers Consistent identity
CPU overload Efficient
Recompute embeddings repeatedly Compute once per track

SORT turns your pipeline from “weak and jittery” to smooth, stable, and lightning fast.

🧠 InsightFace for Embeddings

InsightFace gives crisp 512-dimensional embeddings:

emb = normalize(face.embedding)

These vectors go straight into Qdrant to enable fast similarity search.

🗂️ Qdrant as the Face Database

Qdrant stores embeddings like a search engine:

client.create_collection(
    collection_name="faces",
    vectors_config=VectorParams(size=512, distance=Distance.COSINE)
)

Enter fullscreen mode Exit fullscreen mode

Querying is instant — even with tens of thousands of faces.

🔄 Putting It All Together

Your real-time loop becomes:

Detect → Track → Attach Embedding → Qdrant Search → Show Name

Instead of:

Detect → Recognize → Detect → Recognize → Detect → Recognize → (lag forever)
Enter fullscreen mode Exit fullscreen mode

🏁 Final Takeaway

The winning formula is simple:

InsightFace → reliable embeddings
SORT → stable tracking
Qdrant → lightning-fast comparison

Together, they create a recognition system that actually works in the real world —
fast, smooth, accurate, and scalable.

Top comments (0)