Face Detection & Compare

SCRFD · ArcFace
SYSTEM ONLINE

Upload Foto

Deteksi semua wajah pada satu foto dengan SCRFD.

Hasil

Bounding box, score, dan landmark setiap wajah.

Belum ada hasil. Upload foto lalu klik Deteksi Wajah.

Bandingkan Dua Wajah

Upload dua foto (boleh banyak wajah). Sistem mendeteksi setiap wajah, lalu mencari pasangan paling mirip dengan ArcFace.

Foto 1
Foto 2

Info Algoritma & Threshold

Penjelasan rumus, threshold, dan referensi untuk metrik distance yang dipakai aplikasi.

Face Detector + ArcFace — pipeline 2 langkah

Pipeline app ini selalu 2 langkah: cari posisi wajah dulu, baru bandingkan identitas. Detector dan recognition adalah model berbeda dengan tugas berbeda.

SCRFD (detector aktif sekarang) bertugas menemukan posisi wajah di foto — output-nya bounding box + landmark mata/hidung/mulut. Detector tidak dipakai untuk membandingkan wajah.

ArcFace adalah model recognition yang mengubah tiap wajah jadi vektor 512-dimensi (embedding). Jarak antar embedding diukur untuk menentukan apakah dua wajah identitas yang sama.

Singkatnya: tab Detect pakai SCRFD (cari wajah), tab Compare pakai SCRFD + ArcFace (cari wajah lalu bandingkan).

Dua backend: SCRFD vs RetinaFace

App ini support 2 backend yang dipilih saat startup lewat env var FACE_BACKEND:

  • Backend onnx (default) — pakai SCRFD sebagai detector + ArcFace ONNX (bundle buffalo_l dari InsightFace).
  • Backend deepface — pakai RetinaFace sebagai detector + ArcFace TF/Keras (lib retina-face + deepface).

Keduanya dari lab penelitian yang sama (InsightFace, Jiankang Deng dkk). SCRFD adalah generasi penerus RetinaFace — dirilis 2021 dengan teknik sample & computation redistribution, akurasi sedikit lebih baik di kondisi sulit (WIDER Face hard set) dan lebih efisien per FLOP. Walau nama "RetinaFace" mengandung kata "retina", model ini tidak mendeteksi retina mata — itu hanya nama yang dipilih oleh penelitinya.

Untuk recognition (ArcFace) keduanya sama persis — yang beda hanya implementasi (ONNX vs TF/Keras). Embedding 512-dim yang dihasilkan kompatibel di kedua backend.

Embedding 512-dimensi itu isinya apa?

Embedding adalah daftar 512 angka hasil "perasan" model ArcFace dari satu wajah. Bayangkan setiap wajah diringkas jadi satu deret angka panjang seperti ini:

Contoh embedding (sebagian)
[ 0.0214, −0.1183, 0.0457, −0.0921, 0.1304, …, −0.0066, 0.0812 ]
Total ada 512 angka seperti di atas. Tiap angka biasanya kecil (rentang ±1) dan tidak punya arti yang bisa dibaca manusia.

Tiap angka itu mewakili apa? Tidak ada label seperti "lebar hidung", "warna mata", atau "jarak antar mata". Angka-angka itu adalah fitur abstrak yang ditemukan sendiri oleh neural network selama training — kombinasi pola tepi, tekstur kulit, bentuk geometris, dan relasi antar bagian wajah, yang oleh model dianggap berguna untuk membedakan satu orang dengan orang lain.

Analogi sederhana: bayangkan 512 "juri" yang masing-masing memberi nilai pada wajah dari sudut pandang yang berbeda. Juri ke-1 mungkin sensitif pada pola alis + dahi, juri ke-2 pada tekstur pipi, dst. — tapi sudut pandang tiap juri tidak bisa diterjemahkan ke bahasa manusia. Yang penting: dua foto orang yang sama akan menghasilkan 512 nilai yang mirip, dan dua foto orang yang berbeda akan menghasilkan pola nilai yang berbeda.

Yang bukan disimpan di embedding: embedding bukan foto, bukan kompresi gambar, dan tidak bisa dibalik untuk merekonstruksi wajah aslinya secara persis. Ia hanya menyimpan "ciri pembeda identitas" yang cukup untuk verifikasi — bukan rambut, bukan ekspresi, bukan latar, bukan pencahayaan (idealnya).

Kenapa 512 angka? Itu pilihan arsitektur ArcFace. Lebih sedikit dimensi → kurang ekspresif, susah membedakan jutaan orang. Lebih banyak → mahal komputasi tanpa banyak peningkatan akurasi. 512 dianggap sweet spot oleh para peneliti.

Bagaimana cara membandingkan? Kita ambil dua embedding (vektor 512 angka), lalu hitung jarak-nya pakai rumus seperti Cosine atau Euclidean. Kalau jaraknya kecil → wajah mirip. Kalau jaraknya besar → wajah beda. Threshold-nya dikalibrasi per backend — lihat bagian "Threshold per backend" di bawah.

Rumus tiap algoritma

Untuk dua vektor embedding ArcFace 512-dimensi a dan b:

Cosine Distance
d = 1 − a · b ‖a‖ × ‖b‖
Mengukur sudut antar vektor. Range ~[0, 2]. Metrik utama untuk verifikasi ArcFace.
Euclidean
d = √Σ (aᵢ − bᵢ)²
Jarak garis lurus antar dua titik. Sensitif terhadap panjang (magnitudo) vektor.
Euclidean L2
a' = a ‖a‖ , b' = b ‖b‖
d = √Σ (a'ᵢ − b'ᵢ)²
Sama dengan Euclidean, tapi vektor di-normalize jadi panjang 1 dulu. Range [0, 2].
Manhattan (L1)
d = Σ |aᵢ − bᵢ|
Total selisih absolut tiap dimensi. Untuk 512-dim, nilainya jadi besar.
Chebyshev (L∞)
d = max |aᵢ − bᵢ|
Selisih terbesar di antara semua dimensi. Nilainya cenderung kecil.

Bedanya Euclidean dan Euclidean L2?

Bedanya cuma satu: ada langkah normalisasi sebelum hitung jarak.

  • Euclidean (raw) — sensitif magnitudo. Kalau panjang embedding kebetulan besar (karena pencahayaan, kualitas foto, dll), distance ikut besar walau arah-nya sebetulnya mirip.
  • Euclidean L2 — vektor di-L2-normalize dulu jadi panjang 1, jadi yang dibandingkan cuma arah/sudut-nya.

ArcFace dilatih dengan angular margin loss — identitas wajah tersimpan di arah vektor, bukan panjangnya. Jadi Euclidean L2 biasanya lebih stabil untuk verifikasi wajah dibanding Euclidean biasa.

Secara matematis, Euclidean L2 dan Cosine sebenarnya membawa informasi yang sama (sudut antar vektor), dengan hubungan:

Euclidean_L2² = 2 × Cosine_distance

Itu sebabnya threshold DeepFace konsisten: Cosine 0.68 ↔ Euclidean L2 √(2 × 0.68) ≈ 1.166, dibulatkan jadi 1.13

Threshold per backend

Kedua backend menghasilkan ArcFace embedding 512-dim yang strukturnya sama, tapi threshold verifikasi-nya berbeda karena sumber kalibrasiya beda:

MetrikBackend onnx (InsightFace)Backend deepface
Cosine0.500.68
Euclidean4.15
Euclidean L21.13
Manhattan
Chebyshev
  • Backend deepface — threshold dipublikasikan resmi oleh serengil/deepface (deepface/config/threshold.py), hasil kalibrasi di dataset LFW. cosine 0.68 adalah nilai default untuk ArcFace.
  • Backend onnx — InsightFace tidak mempublikasikan threshold resmi. Nilai cosine 0.50 adalah best-practice komunitas yang banyak dipakai (lebih strict dari deepface karena embedding InsightFace cenderung ter-cluster lebih ketat). Metrik lain tidak ada nilai kalibrasi yang teruji, sehingga ditampilkan sebagai info saja.

Perbedaan threshold ini penting: dengan backend deepface cosine 0.65 dianggap MATCH, tapi dengan backend onnx (threshold 0.50) itu NO MATCH. Selalu perhatikan backend aktif saat menginterpretasi hasil.

Kenapa threshold tiap algoritma berbeda?

Karena tiap rumus menghasilkan skala angka yang berbeda — distance Manhattan untuk pasangan wajah yang sama bisa puluhan, sedangkan Chebyshev cuma di angka satuan. Threshold bukan dipilih sembarang — itu nilai kalibrasi hasil pengujian ArcFace pada dataset wajah berlabel (LFW dll) untuk cari batas optimal "orang sama" vs "orang beda" per metrik.

Kenapa Manhattan & Chebyshev cuma "INFO"?

Tidak ada threshold resmi (dari DeepFace maupun InsightFace) untuk dua metrik ini pada ArcFace, jadi tidak ada angka kalibrasi yang valid untuk memutuskan MATCH / NO MATCH. Keduanya tetap dihitung sebagai info tambahan, tapi tidak dipakai untuk verdict.

Metrik mana yang paling utama?

Cosine. Itu metrik yang paling stabil untuk embedding ArcFace (tidak sensitif magnitudo vektor). Verdict utama (MATCH / NO MATCH) di aplikasi ini selalu memakai cosine dengan threshold sesuai backend aktif.

Sumber & Referensi

Paper Model

  • ArcFace — Deng et al., "ArcFace: Additive Angular Margin Loss for Deep Face Recognition", CVPR 2019. arxiv.org/abs/1801.07698
  • SCRFD — Guo et al., "Sample and Computation Redistribution for Efficient Face Detection", ICLR 2022. (detector untuk backend onnx) arxiv.org/abs/2105.04714
  • RetinaFace — Deng et al., "RetinaFace: Single-stage Dense Face Localisation in the Wild", 2019. (detector untuk backend deepface) arxiv.org/abs/1905.00641
  • DeepFace framework — Serengil & Ozpinar, "LightFace: A Hybrid Deep Face Recognition Framework", ASYU 2020. ieeexplore.ieee.org/document/9259802

Repository GitHub

Threshold — sumber per backend

Dataset Evaluasi