إزاي OpenCASA بيحسب الأرقام؟ — قراءة السورس واللي استفدناه

فتحنا السورس الحقيقي لـOpenCASA (GPL، Java) واستخرجنا الخوارزمية الكاملة: المعايرة، السرعات، التنعيم، والتصنيف — وطبّقناها على محرّكنا وشُفنا النتيجة.

المصدر: calquezar/OpenCASA · Kinematics.java · Motility.java · SignalProcessing.java · MotilityParams.java  •  قراءة لفهم الفكرة (مش نسخ كود — احتراماً لـGPL)

1 الإعدادات الثابتة (هي دي «المعايرة» اللي إنت قلت عليها!)

من MotilityParams.java — القيم اللي بتتدخل مرة واحدة وتفضل ثابتة للجهاز:

الإعدادالقيمة الافتراضيةالمعنى
micronPerPixel0.481المعايرة — كل بكسل = 0.481 ميكرون (تتغيّر حسب قوة العدسة)
frameRate60إطار/ثانية (لتحويل المسافة لسرعة)
vclMin10 µm/sأقل من كده = ساكن (Immotile)
strProgressMotility85 %عتبة الاستقامة للتقدمية
vapProgressMotility120 µm/sعتبة سرعة المسار للتقدمية
wSize4نافذة التنعيم (moving average) لحساب VAP

✅ ردّ على سؤالك عن المعايرة

فعلاً زي ما قلت — المعايرة قيمة ثابتة تُدخَل (micronPerPixel). هي مرتبطة بقوة العدسة + الكاميرا. OpenCASA حاطط 0.481 افتراضي. فالمحرّك بتاعنا محتاج نفس الإعداد ده عشان يطلّع السرعات بـµm/s.

2 إزاي بيحسب كل بارامتر (المعادلات الفعلية من السورس)

// VCL — السرعة المنحنية: مجموع المسافات بين كل نقطتين متتاليتين
distance = Σ dist(point[i], point[i-1])
VCL = distance × micronPerPixel / ((n-1)/frameRate)   // µm/s

// VSL — السرعة المستقيمة: مسافة أول نقطة لآخر نقطة
VSL = dist(first, last) × micronPerPixel / ((n-1)/frameRate)

// VAP — السرّ! سرعة المسار المُنعَّم (مش الخام)
avgTrack = movingAverage(track, wSize=4)   // تنعيم المسار
VAP = VCL(avgTrack)                         // VCL بس على المسار المنعّم

LIN = VSL/VCL × 100      WOB = VAP/VCL × 100      STR = VSL/VAP × 100
ALH = متوسط/أقصى مسافة عمودية من النقطة الخام للمسار المنعّم
BCF = عدد مرات عبور المسار الخام للمسار المنعّم / الزمن   // Hz

🔑 أهم فكرة استفدناها

OpenCASA بينعّم المسار (moving average) ويحسب VAP منه، وبيصنّف التقدمية بـSTR=VSL/VAP و VAPمش الإزاحة الخام. ده اللي كان ناقصنا: إحنا كنا بنصنّف على الخام (jittery) فالتقدمية فشلت.

3 منطق التصنيف (من Motility.java)

// لكل مسار:
if (VCL < vclMin)                              → Immotile
else if (STR > 85% AND VAP > 120µm/s)          → Progressive
else                                           → Non-progressive

بسيطة وواضحة. بس بتعتمد كلياً على إن المسارات نضيفة ومُعايَرة — وده اللي بيفرّق.

4 طبّقناها على محرّكنا — النتيجة (بصراحة)

ضفنا التنعيم (moving average) + VAP + تصنيف STR + المعايرة (0.481) لمحرّكنا وأعدنا التشغيل على الحالتين:

الحالةالتقرير (PR)8 ثوانيمعادلات OpenCASAنافذة 1 ثانيةربط تنبّؤي
16436%2%1%0%0%
17635%5%2%1%0%

⚠️ جرّبنا ٤ طرق — كلها فشلت في التقدمية. التشخيص بقى قاطع

8 ثواني، معادلات OpenCASA، نافذة 1 ثانية، ربط تنبّؤي — كلها أعطت PR ≈ 0-2% مقابل 35%. يعني المشكلة مش النافذة ولا المعادلات — هي جودة الكشف والتتبّع:

  • كشف زائد: بنكشف نقط ساكنة كتير (ضوضاء brightfield) → معظم المسارات ساكنة → الساكن يطغى.
  • ربط ساذج: الحيوان المتحرك بيترِبط بنقطة ساكنة جنبه → مساره يتشوّه → الإزاحة المستقيمة تنهار → يتصنّف غير تقدمي.
  • سرعة مُقاسة واطية: متوسط VCL عندنا ~15µm/s بينما المرجع ~47 → بنقلّل السرعة الحقيقية (الحيوانات السريعة بتضيع أو بتتقاس بطيئة).

5 الخلاصة + الطريق الصحيح للأمام

اللي كسبناه من قراءة السورس

  • عرفنا المعايرة بالظبط: micronPerPixel + frameRate (قيمتين ثابتتين تتدخلوا).
  • عرفنا المعادلات الصحيحة (VCL/VSL/VAP/ALH/BCF) والعتبات (vclMin 10، STR 85%، VAP 120).
  • عرفنا أهم تقنية: تنعيم المسار (moving average) + تصنيف بـSTR — هنطبّقها صح.
  • عرفنا سبب فشلنا الحقيقي: نافذة طويلة + تتبّع ضعيف — مش الحسابات.

الطريق الصح (بعد ما النافذة فشلت، التركيز على التتبّع)

  1. كشف نضيف: فيديو phase-contrast 60fps (تباين عالي) — يقلّل الضوضاء الساكنة جذرياً. ده أهم مدخل.
  2. تتبّع احترافي: Kalman filter لكل حيوان + إسناد عام (Hungarian) + معالجة التقاطعات + رفض النقط الساكنة. ده قلب CASA واللي بياخد شهور.
  3. مراكز sub-pixel + معايرة حقيقية (micronPerPixel من العدسة).
  4. بعدها معادلات OpenCASA (فهمناها) تشتغل صح.

الحكم الصادق

محرّكنا الأولي وصل سقفه: يحسّ الحركة الكلية تقريبياً + يطلّع صورة توثيق، لكن PR/NP و kinematics محتاجين محرّك تتبّع مبني من الأول (مشروع CV حقيقي — أسابيع/شهور)، مش تعديلات. التركيز/الشكل/الحيوية أصلاً مش من فيديو الحركة. التوصية العملية: نكمّل بالبنل اليدوي (جاهز) + نستخدم المحرّك كـمساعد للحركة وتوثيق بصري بس، ولو عايزين CASA آلي كامل → مشروع منفصل بكاميرا 60fps phase-contrast ومهندس رؤية حاسوبية.

قانونياً

قرينا السورس لفهم الفكرة ونعيد تنفيذها بكودنا (clean-room) — الخوارزميات نفسها منشورة في معايير WHO. ده مسموح؛ الممنوع هو نسخ/لينك كود OpenCASA جوّه برنامجنا المغلق (GPL).