يكشف النموذج آفات المادة البيضاء في صور الرنين التي قد تدل على التصلب المتعدد (MS) أو أمراض الأوعية الدموية الدماغية الصغيرة (SVD). النموذج لا يستطيع التمييز بينهما (في اختبار أعمى على 50 حالة MS و 50 حالة SVD رصد آفات في كل الحالات)، لذلك تظهر النتيجة Suspected MS / SVD، وتعرض الخطوة التالية الفحوصات التي تميّز بينهما.
نظام من موقعين منفصلين يعملان على نفس الجهاز ويستخدمان نفس قاعدة البيانات:
| المجلد | الموقع | الرابط | الوظيفة |
|---|---|---|---|
MRI-Scanner/ |
MRI Scanner | http://localhost:8000 | بيانات المريض، رفع صورة الرنين أو الكاميرا، تحليل الذكاء الاصطناعي، النتيجة والخطوة السريرية التالية |
Patient-Registry/ |
Patient Registry | http://localhost:8001 | الإحصائيات، سجل الفحوصات، البحث والفلترة، تفاصيل الفحص، الحذف، Export to Excel |
بدون PHP وبدون XAMPP وبدون MySQL — بايثون فقط.
كل موقع له ملف تشغيل خاص في مجلده:
| الموقع | ويندوز | يفتح في المتصفح |
|---|---|---|
| MRI Scanner | دبل كليك على MRI-Scanner\START-Windows.bat |
http://localhost:8000 |
| Patient Registry | دبل كليك على Patient-Registry\START-Windows.bat |
http://localhost:8001 |
| Raspberry Pi (الاثنين) | ./start-raspberry.sh |
— |
- أول مرة فقط: ثبّتي الاعتماديات بالأمر
python -m pip install -r requirements.txt(لموقع الفحص). موقع السجل لا يحتاج أي مكتبة — بايثون فقط. - شغّلي الموقعين كلٌّ من ملفه، وبأي ترتيب. موقع السجل يلتقط الفحوصات الجديدة تلقائياً متى ما كان شغّالاً.
- موقع السجل يُفتح وحده: لا يوجد أي رابط له في موقع الفحص.
- انتظري لين تصير الشارة فوق 🟢 AI model ready في موقع الفحص.
- لإيقاف الموقعين: سكّري النافذتين السوداوين.
- كل طبيب له رمز من 4 خانات (حروف إنجليزية A–Z أو أرقام 0–9). الحروف الصغيرة تتحول تلقائياً لكبيرة، وأي صيغة أخرى تُرفض.
الرمز فريد لكل الحسابات (حتى الموقوفة)، ولا يُحفظ أبداً كنص: يُحفظ هاش PBKDF2 مملّح + بصمة HMAC بمفتاح سري في
data/auth.key. لا يظهر الرمز في أي صفحة أو رد من السيرفر أو سجل. - رئيسة القسم: Hailah Alhejjei (Department Head، قسم Neurology) — تُنشأ تلقائياً مرة واحدة عند أول تشغيل. رمزها هو الرمز المتفق عليه في الفريق؛ الكود يحتوي هاشه فقط، لا الرمز نفسه.
- موقع الفحص: حقل Doctor PIN إلزامي مع كل فحص. السيرفر يتحقق من الرمز ويحدد الطبيب بنفسه (لا يقبل أي رقم طبيب من المتصفح)، ويحفظه كصاحب للفحص وللمريض الجديد. يُمسح الرمز من الصفحة بعد كل تحليل. موقع الفحص لا يعرض أي صورة محفوظة: صور النتيجة ترجع مع الرد للطبيب الذي أرسل الفحص فقط.
- موقع السجل: يفتح على شاشة الرمز قبل أي بيانات.
- الطبيب: يرى مرضاه وفحوصاته فقط (الجدول، الإحصائيات، الصور، التصدير، الحذف، والتحديث المباشر). السيرفر يفرض ذلك حتى لو غُيّر الرابط أو رقم الفحص.
- رئيسة القسم: ترى كل سجلات القسم مع اسم الطبيب لكل فحص، وقسم Doctor accounts لتسجيل طبيب جديد (الاسم + رمز فريد من 4 خانات) وإيقاف أو تفعيل دخول أي طبيب. الطبيب الجديد يقدر يدخل الموقعين فوراً. الإيقاف يُخرجه فوراً ويمنع رمزه في الموقعين.
- القفل (موقع السجل فقط): 3 رموز خاطئة متتالية تقفل دخول السجل 24 ساعة — حتى الرمز الصحيح يُرفض أثناء القفل.
العداد ووقت انتهاء القفل محفوظان في قاعدة البيانات (لا يتأثران بتحديث الصفحة أو فتح نافذة جديدة أو إعادة تشغيل السيرفر)،
والدخول الصحيح يصفّر العداد، وإضافة لذلك حد 10 محاولات في الدقيقة.
فك القفل إدارياً (من طرفية نفس الجهاز فقط): داخل مجلد
Patient-Registryشغّليpython server.py --reset-lockout. - موقع الفحص لا يقفل أبداً: الرمز الخاطئ يُرفض برسالة «Incorrect PIN» ويقدر الطبيب يعيد المحاولة فوراً (فقط حد 10 محاولات في الدقيقة ضد التخمين السريع).
- الخمول (موقع السجل): بعد 60 ثانية بدون نقر أو كتابة أو تمرير أو تحريك الماوس أو لمس، ترجع الصفحة لشاشة الرمز وتُمسح البيانات منها، والسيرفر نفسه ينهي الجلسة بعد 60 ثانية بدون نشاط. التحديث المباشر وطلبات الخلفية لا تمدد الجلسة.
- حسابات الفريق التجريبية: الملف
data/demo-accounts.json(الاسم والدور وهاش الرمز فقط) يضيف حسابات الفريق لأي نسخة من المشروع عند التشغيل إذا لم تكن موجودة — فتعمل رموز الفريق حتى لو كانت قاعدة البيانات المحلية قديمة. الحسابات الموجودة لا تتغير. - السجلات القديمة (قبل إضافة الأطباء) تبقى كما هي بدون صاحب ولا تُنسب لأي طبيب تلقائياً؛ تظهر لرئيسة القسم فقط باسم «Unassigned».
- في موقع الفحص اكتبي Patient name و Medical number و Doctor PIN — الثلاثة إلزامية.
- اختاري Upload (رفع صورة) أو Camera (ثم Start camera).
- اضغطي Run AI analysis (أو Capture & analyze مع الكاميرا).
- تظهر النتيجة (Suspected MS / SVD أو Low confidence أو Clear) مع نسبة الثقة، والخطوة السريرية التالية: فحوصات تشخيصية فقط (بدون أي علاج) تساعد على التمييز بين MS و SVD — البزل القطني (OCBs و κ-FLC في CSF تدعم MS)، ورنين بالصبغة للدماغ والحبل الشوكي (آفات الحبل الشوكي والمواقع النموذجية ترجّح MS)، وتقييم عوامل الخطر الوعائية (ضغط الدم، HbA1c، الدهون — تدعم SVD).
- يُحفظ الفحص تلقائياً، ويظهر فوراً في موقع السجل دون تحديث الصفحة مع إشعار «New scan received».
- زر العربية / English أعلى كل موقع يحوّل الواجهة كاملة إلى العربية (من اليمين لليسار) والعكس، ويتذكر اختيارك.
- كل الترجمات في ملف واحد:
static/i18n.js(نسخة في كل مجلد). لتعديل ترجمة: غيّري النص العربي أمام الجملة الإنجليزية فيAR، ثم انسخي الملف للمجلد الآخر. - ملف Excel المُصدَّر يبقى بالإنجليزية.
- كل موقع برنامج مستقل في مجلده، والاثنان يقرآن ويكتبان نفس قاعدة البيانات
data/smartscan.db. - موقع الفحص يكتب فقط: يحفظ الفحص والمريض، ولا يملك أي طريقة لقراءة السجل.
- موقع السجل يراقب قاعدة البيانات كل أقل من ثانية؛ أي فحص جديد أو محذوف يُرسل مباشرة لكل نافذة سجل مفتوحة
(Server-Sent Events على
/api/events).
- عنوان موقع الفحص لا يحتوي أي صفحة أو طلب للسجل (
/api/history،/api/patients، التصدير، الحذف،/mediaكلها غير موجودة فيه). - كل طلبات السجل (البيانات، الصور
/media، التصدير، الحذف، التحديث المباشر، إدارة الأطباء) تحتاج جلسة صالحة، والجلسة في كوكي HttpOnly / SameSite=Strict ويُحفظ هاشها فقط في قاعدة البيانات. - موقع الفحص لا يعرض أسماء المرضى المسجّلين؛ رسالة تعارض الرقم الطبي لا تكشف اسم صاحبه.
- الموقعان يستمعان إلى
localhostفقط، مع حماية CSRF وتحديد معدل الطلبات وسجل تدقيق (audit_log) ونسخ احتياطية يومية. - الصور والسجل محفوظان داخل
data/، والمجلد مرفوع على Git ببيانات تجريبية فقط (مرضى مختلقون) حتى يعمل المشروع مباشرة بعد التحميل. لا تضيفي بيانات مرضى حقيقيين — أي شيء فيdata/يُرفع مع المشروع. - هذه أداة مساعدة وليست تشخيصاً طبياً مستقلاً.
- الرقم الطبي هو المعرّف الفريد للمريض (جدول
patients). إذا كُتب رقم مسجّل باسم مختلف يُرفض الفحص. - منع تكرار صورة الرنين: نفس الصورة (نفس البايتات أو نفس البكسلات) لا يمكن ربطها بمريض آخر.
تُحفظ بصمتان SHA-256 (
source_sha256وpixel_sha256)، ولا يُحذف أو يُعدَّل سجل المريض الأصلي. إعادة رفع نفس الصورة لنفس المريض مسموحة. - موقع الفحص يُنشئ الجداول ويحدّثها عند التشغيل دون حذف أي سجل قديم.
- جداول الدخول:
doctors(الأطباء والدور والقسم وهاش الرمز)،auth_sessions(هاش رمز الجلسة)،auth_lockouts(عداد المحاولات ووقت القفل). عمودowner_doctor_idفيscansوpatientsيحدد صاحب السجل؛ يضيفه أي من الموقعين عند التشغيل، والسجلات القديمة تبقى NULL.
| الملف | الوظيفة |
|---|---|
MRI-Scanner/server.py |
سيرفر موقع الفحص: يستقبل الصور، يشغّل النموذج، يحفظ النتيجة |
MRI-Scanner/detector.py |
يحمّل النموذج مرة وحدة، ويحلل بنفس خطوات predict.py |
MRI-Scanner/lesion_yolo26s_photo.pt |
النموذج المستخدم: YOLO26s مدرَّب على شرائح FLAIR من MSLesSeg (75 مريضاً، أقنعة آفات من خبراء، تقسيم حسب المريض) مع محاكاة تصوير الورق المطبوع بالكاميرا (40 epoch، 640px). الأرقام على مرضى الاختبار في index.html |
MRI-Scanner/best.pt |
النموذج القديم YOLO11n (للرجوع فقط؛ أرقامه 99% كانت متأثرة بتسريب بين التدريب والتحقق) |
MRI-Scanner/predict.py |
أداة سطر أوامر مستقلة لاختبار صورة |
MRI-Scanner/static/ |
واجهة الفحص: index.html وapp.js وcommon.js وstyle.css والشعار |
Patient-Registry/server.py |
سيرفر موقع السجل: يعرض السجل، يراقب قاعدة البيانات، الحذف والتصدير |
Patient-Registry/export_xlsx.py |
ملف Excel منسّق (مكتبات بايثون القياسية فقط) |
Patient-Registry/static/ |
واجهة السجل: records.html وregistry.js وcommon.js وstyle.css والشعار |
MRI-Scanner/auth.py و Patient-Registry/auth.py |
حسابات الأطباء، الرموز، الجلسات، والقفل (نفس الملف في المجلدين — إذا عدّلتيه انسخيه للمجلد الآخر) |
tests/test_auth.py |
اختبارات الدخول والصلاحيات والقفل والخمول: python -m unittest tests.test_auth -v (3–5 دقائق، على مجلد بيانات مؤقت) |
MRI-Scanner/START-Windows.bat |
تشغيل موقع الفحص |
Patient-Registry/START-Windows.bat |
تشغيل موقع السجل |
start-raspberry.sh |
تشغيل الموقعين معاً على Raspberry Pi |
data/ |
مشترك، يُنشأ تلقائياً: قاعدة SQLite والصور والنسخ الاحتياطية |
- تحويل الصورة للرمادي، وتشغيل
lesion_yolo26s_photo.ptعليها بدون CLAHE بحجم 640 بكسل وبحد ثقةconf=0.25(أفضل F1 على مرضى التحقق). CLAHE يُستخدم لصورة العرض Enhanced فقط. - فحص البؤر (Focal check): أي صندوق يغطي أكثر من 15% من الصورة ليس آفة ويُتجاهل
(
MAX_LESION_AREAفيMRI-Scanner/detector.py)، ويُحفظ فيraw_resultللمراجعة. - إذا بقيت بؤر: النتيجة
Infectedمع أعلى نسبة ثقة. وإلا: النتيجةHealthy(تظهر Clear) دون اختلاق نسبة ثقة.
الفحوصات الجديدة تحمل inference_version = yolo26s-mslesseg-photo-v6؛ القديمة (yolo11n-...) حُللت بالنموذج السابق.
نتيجة Infected بثقة أقل من 50% تُعرض Low confidence ولا تُحوّل إلى سليمة. يمكن تغيير الحد من MIN_CONFIDENCE في MRI-Scanner/server.py.
- الشارة حمراء «Model unavailable»: ثبّتي
requirements.txtوتحققي من وجودMRI-Scanner/best.ptثم أعيدي التشغيل. - الكاميرا ما تشتغل: افتحي الموقع على
localhostواسمحي للمتصفح باستخدام الكاميرا، أو استخدمي «Upload». - المنفذ مشغول: كل سيرفر يجرب المنفذ التالي تلقائياً، والرابط الصحيح يطلع في نافذته السوداء.
- موقع السجل يقول «Reconnecting…»: تأكدي إن نافذة موقع السجل مفتوحة؛ الاتصال يرجع لحاله.
- دخول السجل مقفل 24 ساعة: انتظري انتهاء الوقت المعروض، أو من مجلد
Patient-Registryشغّليpython server.py --reset-lockout. - مجلد
data/: مرفوع على Git ببياناته التجريبية (حسابات الأطباء وبيانات المرضى المختلقة والصور) — استخدميه للبيانات التجريبية فقط. المفتاح السريdata/auth.keyلا يُرفع؛ كل نسخة تُنشئ مفتاحها تلقائياً وتبقى كل الرموز تعمل.