1) السيرفس دي بتعمل إيه بالظبط؟
السيرفس هدفها الأساسي:
تسجّل وجه موظف (Enrollment)
→ تاخد صورة الموظف، تطلع منها “بصمة وجه” رقمية اسمها Embedding Vector (مثلاً 512 رقم)، وتخزنها في قاعدة البيانات.
تتعرف على صاحب صورة جديدة (Search / Identify)
→ تيجي صورة جديدة (مثلاً من كاميرا حضور/انصراف أو موبايل)، السيرفس تطلع Embedding للصورة الجديدة وتقارنها مع اللي مخزّن في DB وتقول:
أقرب شخص/أشخاص للوجه ده
ودرجة التشابه (Score)
وهل التشابه كافي لقبول النتيجة ولا لأ (Threshold)
تتحقق من شخص محدد (Verify 1:1)
→ بدل ما تقول “مين ده؟”، تقول “هل ده الموظف رقم X ولا لأ؟”
وده أنضف وأأمن في سيناريو حضور/انصراف.
2) يعني إيه Embedding Vector؟
الـ Embedding هو:
تمثيل رقمي للوجه كـ سلسلة أرقام (مثلاً 512 Float)
الأرقام دي بتلخّص ملامح الوجه (المسافات/الأنماط) بطريقة تخلي:
صورتين لنفس الشخص → embeddings قريبين من بعض
صورتين لشخصين مختلفين → embeddings بعيدة عن بعض
أهم نقطة: إحنا مش بنخزن الصورة نفسها عشان نعرف الشخص
إحنا بنخزن “البصمة الرقمية” اللي بتطلع من الموديل.
3) السيرفس بتتكوّن من إيه؟ (المكونات الأساسية)
A) API Controller
بيستقبل Requests زي:
POST /faces/enroll?employeeCode=...
POST /faces/search
POST /faces/verify?employeeCode=...
B) Face Processing (Detect + Align)
قبل ما نطلع embedding لازم:
نعمل Face Detection: نحدد مكان الوجه في الصورة
نعمل Crop: نقص الوجه فقط
نعمل Align: نزبط اتجاه الوجه (يمين/شمال/ميل)
نعمل Resize: نخليها مثلاً 112×112 أو 160×160 حسب الموديل
ليه؟ لأن لو سيبت الصورة كاملة فيها خلفية/إضاءة/زوايا كتير، الدقة بتقل.
C) Embedding Extractor (ArcFace / ONNX Runtime)
دي خطوة “المخ”:
الصورة بعد القص والمحاذاة تدخل على موديل FaceNet/ArcFace (غالبًا ONNX)
الموديل يطلع float[] embedding
D) Normalization
بعد ما نطلع الـ embedding:
بنعمله L2 Normalize
يعني نخليه “طوله = 1” عشان المقارنة تبقى عادلة وثابتة.
E) Database (PostgreSQL + pgvector)
بنخزن الـ embedding في جدول زي:
employee_face_templates
وفيه عمود نوعه vector(512)
وبعدين نعمل بحث سريع جدًا باستخدام pgvector:
يجيب أقرب vectors للـ query vector
4) السيناريو رقم 1: Enrollment (تسجيل وجه موظف)
خطوة بخطوة:
الموظف يرفع صورة (أو الكاميرا تاخد صورة)
السيرفس تتحقق من الصورة:
هل هي Image؟
هل حجمها مناسب؟
Detect Face:
لو مفيش وجه → reject
لو أكتر من وجه → غالبًا reject أو تختار أكبر وجه (حسب policy)
Crop + Align + Resize
Run Model → Embedding Vector
Normalize
Save في DB:
employeeCode
embedding
createdAt
qualityScore (اختياري)
Response:
templateId
message “enrolled successfully”
ليه بنخزن أكتر من Template؟
عشان الموظف ممكن:
مرة بنضارة
مرة من غير
مرة إضاءة ضعيفة
مرة زاوية مختلفة
كل Template بيزود نسبة نجاح المطابقة.
5) السيناريو رقم 2: Search / Identify (مين ده؟ 1:N)
خطوة بخطوة:
تيجي صورة جديدة (مثلاً حضور)
نفس processing:
detect / crop / align / resize
استخراج embedding + normalize
نعمل Query على pgvector:
هات أقرب TopK (مثلاً 5 أو 10)
نحسب Score/Distance ونطبق شروط القبول:
لو أقرب نتيجة distance صغير كفاية → قبول
لو بعيد → “Unknown”
ممكن كمان نعمل “Margin Rule”:
لازم الفرق بين أول نتيجة وتاني نتيجة يكون واضح
عشان نقلل false positives
Output نموذج:
[ { employeeCode: 101, name: "Ahmed", score: 0.83 }, ... ]
مع قرار نهائي: “Matched / Not Matched”
6) السيناريو رقم 3: Verify (هل ده الشخص X؟ 1:1)
دي أفضل للحضور:
الصورة تتعمل لها embedding
بدل ما نجيب كل الموظفين، نجيب Templates الموظف X فقط
نقارن:
لو bestScore فوق threshold → true
غير كده → false
ليه Verify أفضل؟
لأن:
يقلل خطأ “اتعرف على موظف تاني”
أسرع
أمن أكتر
7) إزاي بنقيس التشابه؟ (Distance vs Similarity)
عندك طريقتين مشهورين:
A) Cosine Similarity / Cosine Distance
لو vectors normalized:
Cosine similarity قريب من 1 → نفس الشخص
قريب من 0 أو سلبي → مختلف
B) L2 (Euclidean) Distance
distance صغير → نفس الشخص
distance كبير → مختلف
اختيار threshold يتظبط بالتجربة على صور من بيئتك.
8) ليه استخدمنا pgvector؟
لسببين:
سرعة رهيبة في nearest neighbor search بدل ما تعمل المقارنة في Java على آلاف embeddings
تقدر تعمل Index (HNSW / IVFFLAT) وتخلي البحث lightning-fast حتى لو عندك 100 ألف موظف
9) طب السيرفس دي “مش” بتعمل إيه؟
مش “تفتح كاميرا” بنفسها (ده دور Frontend / Mobile)
مش بتضمن 100% دقة (الصور السيئة/الإضاءة/الزاوية تؤثر)
مش بتخزن “ملامح وجه قابلة للفهم” — هي مجرد أرقام
10) الحماية وجودة النتائج (Policies)
عشان الدقة والأمان:
ارفض الصور اللي:
مفيهاش وجه
فيها أكتر من وجه (حسب سيناريو الحضور)
الوجه صغير جدًا
Blur عالي
استخدم:
TopK + threshold
Margin rule
ويفضل:
Verify بدل Search في الحضور
11) أمثلة استخدام في مشروعك (HR/Attendance)
الموظف “يسجل وجهه” مرة واحدة (Enrollment)
عند الحضور:
Upload صورة → Verify employeeCode (أو Identify لو kiosk عام)
لو Verified:
تسجل Attendance record
لو Not Verified:
ترجع رسالة “Face not matched, please retry”