إستعادة الصور – الجزء الخامس
part fiveImage Retrieval –
مقدمة:
بسم إلله الرحمن الرحيم
في هذا الجزء من المقالة سوف نقوم بإستعراض وتوضيح نوع جديد من أنواع إستعادة الصور ألا وهو المسمى إستعادة الصور بدلالة المحتوى والذي يستخدم بشكل أساسي في عمليات البحث أو الإستعلام في قواعد البيانات عن صورة معينة أو في محركات البحث بواسطة الصور, حيث إنَّ هذه التقنية أصبحت من أهم التقنيات في هذا المجال وقد أجريت عليها تحسينات كثيرة ساهمت في زيادة كفائتها.
إسترجاع الصور بدلالة المحتوى
(Content-based image retrieval)
في العقود الماضية أدى التقدم الكبير في تقنيات الحاسوب والوسائط المتعددة (multimedia) إلى إنتاج الصور الرقمية ومستودعات الصور (image repositories) الكبيرة الرخيصة حيث ازداد نتيجة لهذا حجم مجموعات الصور (image collections) بسرعة كبيرة ، بما في ذلك المكتبات الرقمية والصور الطبية وغيرها.
لمواجهة هذا النمو السريع ، يلزم تطوير أنظمة لاسترجاع الصور تعمل على نطاق واسع, حيث إنَّ الهدف الأساسي هو بناء نظام قوي يقوم بإنشاء قواعد بيانات للصور وإدارتها والاستعلام عنها بطريقة دقيقة.
1 – تكون الصور ذات أبعاد كثيرة (huge dimensions) ونحن نعلم إن الصور لكي تكون مفهومة من قبل الإنسان يجب أن لاتزيد أبعادها عن ثلاثة أبعاد.
2 – هناك الكثير من البكسلات المتكررة في الصورة الواحدة.
لذلك نقوم بتدريب نموذج على مهمة تصنيف الأشياء الموجودة في الصور (object classification) ونستخدم المزايا والخصائص (features) التي يقوم بإستخلاصها من الصور المدخلة للإستعلام لإنجاز المهمة, حيث نقوم بتمرير صورة الاستعلام وقاعدة البيانات الخاصة بالأهداف إلى النموذج للحصول على الميزات. إنَّ النماذج المدربة يمكن أيضًا تسميتها بالمشفرات (Encoders) لأنها تقوم بتشفير المعلومات التي تخص الصور المستخدمة في المهمة المعينة, وهذه المشفرات (النماذج المدربة) يجب أن تكون قادرة على إستخلاص وإلتقاط الخصائص المحلية (غير التفصيلية) وكذلك الخصائص الشاملة (التفصيلية).
إنَّ إستخدام الطرق التقليدية في عملية البحث بواسطة الصور مثل الأسلوب المسمى بالقوة الغاشمة (brute-force) أو أسلوب المسح الخطي (linear scan) سوف يستغرق وقتاً ويكون بطيئاً, لذا قام الباحثون بإبتكار طرق أخرى, وفيما يلي بعض تلك الطرق المستخدمة في عملية الإستعلام السريع:
1 – التجزئة الحساسة للمنطقة (Locality sensitive hashing (LSH)) : تقوم هذه الطريقة بإسقاط الميزات (features) على فضاءها الفرعي, حيث يقوم بتقديم قائمة بالخصائص المرشحة (القريبة من خصائص الصورة المستعلم عنها) ويقوم لاحقاً بعملية الإنتقاء الدقيق للخاصية أو الميزة (fine-feature ranking). وهذه التقنية تعتبر إحدى تقنيات تقليل الأبعاد (dimensionality reduction technique).
2 – التجزئة ذات الفهرسة المتعددة (Multi-index hashing) : تقوم هذه الطريقة على تجزئة الخصائص (features) مما يجعلها أسرع. تستخدم هنا تقنية (hamming distance) لجعل الحسابات أسرع.
هاتين الطريقتين تعتبران أسرع من الطرق التقليدية وتنفذان بذاكرة (ram memory) أقل ويمكن مقايضة السرعة مع الدقة (accuracy), وكذلك فإنَّ هاتين الطريقتين لاتلتقطان الفرق في الدلالة (semantic difference).
كذلك يمكن إعادة ترتيب نتائج المطابقات للحصول على نتائج أفضل بناءً على طلب الإستعلام والبحث, وبالتالي يمكن على ضوء ذلك ترتيب الصور المطلوبة, وتستخدم في عملية إعادة ترتيب الخصائص أحد الأساليب التالية:
1 – التحقق الهندسي (Geometric verification): وهي عملية مطابقة بين الأشكال الهندسية مع الصور المستهدفة والحصول على الأشكال الهندسية التي تطابق كل صورة.
2 – توسيع الإستعلام (Query expansion): وهي عملية توسيع قائمة الصور المستهدفة (خصائصها قريبة من خصائص الصورة المطلوب الإستعلام عنها), ومن ثمَّ يتم البحث في هذه القائمة بشكل تفصيلي وشامل.
3 – ردود الفعل ذات الصلة (Relevance feedback): هذه الطريقة تحصل على ردود الفعل من الاستخدام وإرجاع النتائج. بناءً على إدخال المستخدم ، سيتم إعادة الترتيب.
هذه الأساليب الثلاثة قد تم تطويرها أساساً في مجال النصوص (texts) ولكن ظهر إنه من الممكن أن تستخدم في مجال الصور.
بناء مسار الإسترجاع (Building the retrieval pipeline):
تسمى الخطوات اللازمة للحصول على أفضل التطابقات من الصور المستهدفة (الموجودة في قاعدة البيانات) لصورة الإستعلام باسم مسار الاسترجاع (retrieval pipeline), حيث إنَّه يحتوي على خطوات أو مكونات متعددة. من أحد الخطوات المهمة هي إستخراج خصائص كل صورة من الصور الموجودة في قاعدة البيانات وتخزينها كبيانات إضافية بمعزل عن عملية الإستعلام (offline).
لإجراء عملية الإستعلام تؤخذ الصورة المستعلم عنها وتستخلص منها الخصائص المهمة ومقارنتها مع جميع الخصائص للصور المستهدفة وحساب درجة التشابه مع كل واحدة. بعدها يتم ترتيب الصور المستهدفة حسب درجة تشابه خصائصها مع خصائص صورة الإستعلام. والصورة التالية توضح مسار الإسترجاع كما ذكرناه:
لكي تتم عملية الإستعلام وإظهار النتائج في وقت معقول يجب أن تكتمل خطوات إستخراج الخصائص بسرعة لذلك يمكن إستخدام خاصية (Serving) من مكتبة (TensorFlow), حيث إننا نستطيع إختيار الخصائص المناسبة لنوع التطبيق. على سبيل المثال يمكننا إختيار الطبقات الأولية (initial layers) من النموذج المدرب إذا كانت عملية التطابق المطلوبة مستندة الى البنية الأساسية للصورة (texture-based matching).
ويمكن إستخدام الطبقات المتأخرة (later layers) من النموذج إذا كانت عملية المطابقة مستندة إلى مستوى كائن (object level) موجود في الصورة, وسوف نرى في الفقرة التالية كيفية إستخراج الخصائص من الصورة بإستخدام نموذج مدرب على عملية التصنيف (classification).
وسوف نقوم بإستخدام خوارزمية إزالة الضوضاء المبتنية على خوارزمية التشفير الذاتي (Autoencoder) وكما موضح في الرسم الآتي:
والآن سوف نقوم بإنشاء مشروع نوضح من خلاله كيفية عمل هذه الخوارزمية (أي خوارزمية إسترجاع الصور بدلالة المحتوى), حيث يتكون مشروعنا من خطوتين هما:
الخطوة الأولى: إنشاء تطبيق مبني على أساس خوارزمية تقليل الضوضاء والذي هو مبني على خوارزمية التشفير الذاتي (Autoencoder), حيث نقوم هذه المرة بإنشاء تطبيق أكثر دقة وذلك بإستخدام شبكة عصبية ذات طبقات إلتفافية (Convolutional Neural Network) وكما يلي:
شرح الكود:
الأسطر من (1) لغاية (3): إستدعاء المكتبات التي نحتاجها في كتابة الأكواد.
الأسطر من (1) لغاية (6): إنشاء دالة تقوم بإضافة ضوضاء على بيانات كل مجموعة صور تمرر إليها. علماً بأنَّ الضوضاء يكون عشوائي.
السطر رقم (1): لتحميل مجموعة الصور (MNIST dataset) وتوزيعها إلى أربعة أقسام كما مر بنا في التطبيق السابق.
السطر رقم (3): تحويل نوع بيانات صور التدريب إلى (float32) وكذلك قسمتها على العدد (255).
السطر رقم (4): تحويل نوع بيانات صور الإختبار إلى (float32) وكذلك قسمتها على العدد (255).
السطر رقم (5): لتغيير شكل (Shape) مجموعة بيانات صور التدريب من ثلاثة أبعاد (60000, 28, 28) إلى أربعة أبعاد أي (60000, 28, 28, 1).
السطر رقم (6): لتغيير شكل (Shape) مجموعة بيانات صور الإختبار من ثلاثة أبعاد (10000, 28, 28) إلى أربعة أبعاد أي (10000, 28, 28, 1).
السطر رقم (7): إنشاء مجموعة بيانات للصور الخاصة بالتدريب عبارة عن نفس بيانات صور التدريب (x_train) مضافاً عليها ضوضاء (Noise).
السطر رقم (8): إنشاء مجموعة بيانات للصور الخاصة بالإختبار عبارة عن نفس بيانات صور الإختبار (x_test) مضافاً عليها ضوضاء (Noise).
الأسطر من (1) لغاية (17): بناء النموذج الذي سوف نقوم بتدريبه على مهمة تنفيذ خوارزمية ال (Denoising by autoencoder). حيث نستخدم أسلوب (Keras functional API), مع ملاحظة أننا أعطينا للطبقة (encoded) في السطر رقم (7) خاصية الإسم (name=’encoder’) لأننا سوف نحتاج هذه الخاصية لاحقاً.
الأسطر من (1) لغاية (3): لتجهيز النموذج وجعله جاهزاً لعملية التدريب عن طريق الدالة (compile) حيث نمرر لها بعض العناصر التي يجب توفرها في عملية التدريب مثل الخوارزمية المناسبة في عملية التحسين (Optimization) وقد إخترنا هنا الخوارزمية التي يطلق عليها (Adam), كذلك نمرر لها نوع الدالة التي تستخدم في عملية حساب الفقد (Loss function) وقد إخترنا الدالة المسماة (Binary Crossentropy).
الأسطر من (1) لغاية (5): للبدأ بعملية التدريب عن طريق الدالة (fit) حيث نقوم بتمرير المتطلبات التالية:
1 – بيانات التدريب, حيث إننا نستخدم بيانات الصور التي تم إضافة الضوضاء لها (x_train_noisy) كبيانات إدخال وبيانات الصور بدون ضوضاء (x_train) كبيانات إخراج بدل التسميات (Labels).
2 – عدد حقب التدريب (Epochs) (أي عدد مرات تكرار نفس بيانات التدريب).
3 – حجم دفعة التدريب الواحدة (Batch size).
4 – بيانات التأكد من صحة مسار التدريب (Validation data), وقد إستخدمنا هنا بيانات الإختبار.
السطر رقم (6): حفظ النموذج بعد إنتهاء عملية التدريب في ملف خاص لغرض إستخدامه في المراحل اللاحقة, حيث إنَّ عملية الحفظ تشمل هيكل النموذج (Graphs) وكذلك الأوزان (Weights).
السطر رقم (1): لمعرفة أداء النموذج بعد عملية التدريب وذلك بإدخال مجموعة صور الإختبار (x_test_noisy) وإيداع الصور الخارجة منه في متغير سميناه (decoded_images), حيث يتم إختيار مجموعة من هذه الصور لأجل إظهارها ومقارنتها مع مقابلاتها من الصور المدخلة إلى النموذج وذلك عن طريق الكود في الأسطر اللاحقة.
الأسطر من (3) لغاية (16): لأجل إظهار مجموعة من صور الإختبار التي أدخلناها للنموذج وكذلك نفس العدد من مجموعة الصور الخارجة من النموذج لغرض المقارنة ومعرضة أداء النموذج.
وبعد تنفيذ الكود كاملاً نحصل على الصورة التالية, وكذلك نشاهد ظهور الملف (‘autoencoder.h5’), حيث يكون موجوداً في مجلد المشروع.
الخطوة الثانية: إستخدام النموذج الذي انشأناه ودربناه في الخطوة الأولى.
حيث نقوم بتحميل نموذجنا الذي حفظناه في الملف (‘autoencoder.h5’) وكما موضح في الكود التالي:
الأسطر من (1) لغاية (6): لجلب المكتبات التي نحتاجها في التطبيق.
السطر رقم (1): لتحميل النموذج الخاص بنا والذي قمنا بتدريبه على مهمة إلغاء الضوضاء (Denoising), والذي قمنا بحفظه في الملف (autoencoder.h5), حيث إستخدمنا الدالة (load_model) لهذا الغرض.
السطر رقم (2): إنشاء نموذج جديد مستمد من النموذج الأصلي ولكن يحتوي على مرحلة التشفير (Encoder) فقط, حيث إستخدمنا أسلوب (Keras functional API) في إنشاء هذا النموذج الجديد وعن طريق الكلاس المسمى (Model). وقد إستخدمنا شكل طبقة الإدخال (Input layer) نفس تلك المستخدمة في النموذج الأصلي, وبالنسبة إلى طبقة الإخراج (Output layer) فقد إستخدمنا الطبقة (encoder) والتي قمنا بتسميتها سابقاً عند إنشاء النموذج الأصلي والتي تعتبر الطبقة النهائية من مرحلة التشفير (Encoder).
الأسطر من (1) لغاية (6): لتحميل مجموعة بيانات (MNIST dataset), وإجراء عملية تهيئة لها لتكون مناسبة لإستخدامها في هذا النموذج. حيث قمنا بإضافة بعد جديد لكل من بيانات صور التدريب (x_train) وكذلك بيانات صور الإختبار (x_test), وكذلك قمنا بتغيير نوع بياناتهما إلى نوع (float32).
لكي تتم عملية الإستعلام وإظهار النتائج في وقت معقول يجب أن تكتمل خطوات إستخراج الخصائص بسرعة لذلك يمكن إستخدام خاصية (Serving) من مكتبة (TensorFlow), حيث إننا نستطيع إختيار الخصائص المناسبة لنوع التطبيق. على سبيل المثال يمكننا إختيار الطبقات الأولية (initial layers) من النموذج المدرب إذا كانت عملية التطابق المطلوبة مستندة الى البنية الأساسية للصورة (texture-based matching).
ويمكن إستخدام الطبقات المتأخرة (later layers) من النموذج إذا كانت عملية المطابقة مستندة إلى مستوى كائن (object level) موجود في الصورة, وسوف نرى في الفقرة التالية كيفية إستخراج الخصائص من الصورة بإستخدام نموذج مدرب على عملية التصنيف (classification).
وسوف نقوم بإستخدام خوارزمية إزالة الضوضاء المبتنية على خوارزمية التشفير الذاتي (Autoencoder) وكما موضح في الرسم الآتي:
والآن سوف نقوم بإنشاء مشروع نوضح من خلاله كيفية عمل هذه الخوارزمية (أي خوارزمية إسترجاع الصور بدلالة المحتوى), حيث يتكون مشروعنا من خطوتين هما:
الخطوة الأولى: إنشاء تطبيق مبني على أساس خوارزمية تقليل الضوضاء والذي هو مبني على خوارزمية التشفير الذاتي (Autoencoder), حيث نقوم هذه المرة بإنشاء تطبيق أكثر دقة وذلك بإستخدام شبكة عصبية ذات طبقات إلتفافية (Convolutional Neural Network) وكما يلي:
شرح الكود:
الأسطر من (1) لغاية (3): إستدعاء المكتبات التي نحتاجها في كتابة الأكواد.
الأسطر من (1) لغاية (6): إنشاء دالة تقوم بإضافة ضوضاء على بيانات كل مجموعة صور تمرر إليها. علماً بأنَّ الضوضاء يكون عشوائي.
السطر رقم (1): لتحميل مجموعة الصور (MNIST dataset) وتوزيعها إلى أربعة أقسام كما مر بنا في التطبيق السابق.
السطر رقم (3): تحويل نوع بيانات صور التدريب إلى (float32) وكذلك قسمتها على العدد (255).
السطر رقم (4): تحويل نوع بيانات صور الإختبار إلى (float32) وكذلك قسمتها على العدد (255).
السطر رقم (5): لتغيير شكل (Shape) مجموعة بيانات صور التدريب من ثلاثة أبعاد (60000, 28, 28) إلى أربعة أبعاد أي (60000, 28, 28, 1).
السطر رقم (6): لتغيير شكل (Shape) مجموعة بيانات صور الإختبار من ثلاثة أبعاد (10000, 28, 28) إلى أربعة أبعاد أي (10000, 28, 28, 1).
السطر رقم (7): إنشاء مجموعة بيانات للصور الخاصة بالتدريب عبارة عن نفس بيانات صور التدريب (x_train) مضافاً عليها ضوضاء (Noise).
السطر رقم (8): إنشاء مجموعة بيانات للصور الخاصة بالإختبار عبارة عن نفس بيانات صور الإختبار (x_test) مضافاً عليها ضوضاء (Noise).
الأسطر من (1) لغاية (17): بناء النموذج الذي سوف نقوم بتدريبه على مهمة تنفيذ خوارزمية ال (Denoising by autoencoder). حيث نستخدم أسلوب (Keras functional API), مع ملاحظة أننا أعطينا للطبقة (encoded) في السطر رقم (7) خاصية الإسم (name=’encoder’) لأننا سوف نحتاج هذه الخاصية لاحقاً.
الأسطر من (1) لغاية (3): لتجهيز النموذج وجعله جاهزاً لعملية التدريب عن طريق الدالة (compile) حيث نمرر لها بعض العناصر التي يجب توفرها في عملية التدريب مثل الخوارزمية المناسبة في عملية التحسين (Optimization) وقد إخترنا هنا الخوارزمية التي يطلق عليها (Adam), كذلك نمرر لها نوع الدالة التي تستخدم في عملية حساب الفقد (Loss function) وقد إخترنا الدالة المسماة (Binary Crossentropy).
الأسطر من (1) لغاية (5): للبدأ بعملية التدريب عن طريق الدالة (fit) حيث نقوم بتمرير المتطلبات التالية:
1 – بيانات التدريب, حيث إننا نستخدم بيانات الصور التي تم إضافة الضوضاء لها (x_train_noisy) كبيانات إدخال وبيانات الصور بدون ضوضاء (x_train) كبيانات إخراج بدل التسميات (Labels).
2 – عدد حقب التدريب (Epochs) (أي عدد مرات تكرار نفس بيانات التدريب).
3 – حجم دفعة التدريب الواحدة (Batch size).
4 – بيانات التأكد من صحة مسار التدريب (Validation data), وقد إستخدمنا هنا بيانات الإختبار.
السطر رقم (6): حفظ النموذج بعد إنتهاء عملية التدريب في ملف خاص لغرض إستخدامه في المراحل اللاحقة, حيث إنَّ عملية الحفظ تشمل هيكل النموذج (Graphs) وكذلك الأوزان (Weights).
السطر رقم (1): لمعرفة أداء النموذج بعد عملية التدريب وذلك بإدخال مجموعة صور الإختبار (x_test_noisy) وإيداع الصور الخارجة منه في متغير سميناه (decoded_images), حيث يتم إختيار مجموعة من هذه الصور لأجل إظهارها ومقارنتها مع مقابلاتها من الصور المدخلة إلى النموذج وذلك عن طريق الكود في الأسطر اللاحقة.
الأسطر من (3) لغاية (16): لأجل إظهار مجموعة من صور الإختبار التي أدخلناها للنموذج وكذلك نفس العدد من مجموعة الصور الخارجة من النموذج لغرض المقارنة ومعرضة أداء النموذج.
وبعد تنفيذ الكود كاملاً نحصل على الصورة التالية, وكذلك نشاهد ظهور الملف (‘autoencoder.h5’), حيث يكون موجوداً في مجلد المشروع.
الخطوة الثانية: إستخدام النموذج الذي انشأناه ودربناه في الخطوة الأولى.
حيث نقوم بتحميل نموذجنا الذي حفظناه في الملف (‘autoencoder.h5’) وكما موضح في الكود التالي:
الأسطر من (1) لغاية (6): لجلب المكتبات التي نحتاجها في التطبيق.
السطر رقم (1): لتحميل النموذج الخاص بنا والذي قمنا بتدريبه على مهمة إلغاء الضوضاء (Denoising), والذي قمنا بحفظه في الملف (autoencoder.h5), حيث إستخدمنا الدالة (load_model) لهذا الغرض.
السطر رقم (2): إنشاء نموذج جديد مستمد من النموذج الأصلي ولكن يحتوي على مرحلة التشفير (Encoder) فقط, حيث إستخدمنا أسلوب (Keras functional API) في إنشاء هذا النموذج الجديد وعن طريق الكلاس المسمى (Model). وقد إستخدمنا شكل طبقة الإدخال (Input layer) نفس تلك المستخدمة في النموذج الأصلي, وبالنسبة إلى طبقة الإخراج (Output layer) فقد إستخدمنا الطبقة (encoder) والتي قمنا بتسميتها سابقاً عند إنشاء النموذج الأصلي والتي تعتبر الطبقة النهائية من مرحلة التشفير (Encoder).
الأسطر من (1) لغاية (6): لتحميل مجموعة بيانات (MNIST dataset), وإجراء عملية تهيئة لها لتكون مناسبة لإستخدامها في هذا النموذج. حيث قمنا بإضافة بعد جديد لكل من بيانات صور التدريب (x_train) وكذلك بيانات صور الإختبار (x_test), وكذلك قمنا بتغيير نوع بياناتهما إلى نوع (float32).
السطر رقم (1): للحصول على بيانات صور التدريب ولكن مشفرة بفعل نموذجنا الجديد والذي يتكون من مرحلة تشفير فقط, فكلما أدخلنا عليه بيانات صورة يقوم بإستخلاص الخصائص المهمة منها وهذه العملية تعتبر عملية تشفير للبيانات. إستخدمنا الدالة (predict) أي التوقع للحصول على هذه البيانات. هذه البيانات عبارة عن مصفوفة ذات الشكل (60000, 4, 4, 8).
السطر رقم (2): لتحويل شكل البيانات إلى مجموعة من المتجهات (Vectors) عددها (60000), وكل متجه يتكون من (128) عنصر أي (4 x 4 x 8 = 128).
السطر رقم (3): للحصول على بيانات صورة الإستعلام (Query image) المشفرة, حيث إخترنا أحدى صور مجموعة الإختبار (x_test) كصورة إستعلام.
السطر رقم (4): لتغيير شكل بيانات صورة الإستعلام المشفرة إلى متجه عدد عناصره (128) عنصر.
السطر رقم (1): للإعلان عن مصفوفة نوع (List) لنحفظ فيها المسافات بين كل متجه يمثل أحد صور بيانت (x_train) والمتجه الذي يمثل بيانات صورة الإستعلام.
السطر رقم (2): إنشاء حلقة تكرارية تتكرر بعدد متجهات مجموعة (x_train) أي (60000).
السطر رقم (3): لإيجاد المسافة الأقليديسية (Euclidean norm) بين كل متجه من متجهات مجموعة (x_train) والمتجه الذي يمثل صورة الإستعلام, حيث نقوم بطرح هذين المتجهين
(المتجه الذي يمثل صورة واحدة من صور قاعدة البيانات (x_train) – المتجه الذي يمثل صورة الإستعلام), ثم نقوم بإدخل حاصل الطرح على الدالة (linalg.norm) حيث تقوم هذه الدالة بأخد المربعات لجميع قيم عناصر المتجه الناتج من عملية الطرح, ثم تقوم بعملية جمع لهذه المربعات وبعد ذلك تقوم بإستخراج الجذر التربيعي لناتج الجمع وبذلك سوف نحصل على قيمة عددية واحدة تمثل المسافة الأقليديسية لأحد الصور مع صورة الإستعلام.
السطر رقم (4): حفظ كل نتيجة من نتائج حلقة التكرار في المصفوفة (distances).
السطر رقم (5): تحويل المصفوفة من نوع (List) إلى مصفوفة من نوع (Numpy) لكي نستطيع الإستفادة من الدوال التي توفرها لنا هذه المكتبة.
السطر رقم (1): لإستخلاص العدد الكلي لمتجهات البيانات المشفرة التابعة إلى (x_train), حيث إنَّ عددها هو (60000), حيث إن هذا العدد سوف نحتاجه لاحقاً.
السطر رقم (2): لتوليد مصفوفة من الأرقام المتسلسلة تبدأ من (0) وتنتهي بالعدد (59999) أي بعدد بيانات الصور الخاصة بمجموعة (x_train).
السطر رقم (3): أخذ نسخة من بيانات التسمية (Labels) في مجموعة التدريب (y_train) وتحويل نوعها إلى (Float32).
السطر رقم (4): عملية دمج كل من متجه المسافات (distances) مع المتجه الخاص ببيانات التسمية (labels), وإضافة لهما بعد (Dimension) جديد هو متجه الفهارس (learned_code_index), وبالنتيجة يصبح لدينا متجه جديد يضم هذه المتجهات الثلاثة.
السطر رقم (1): لتحديد عدد الصور التي سوف تعرض من بين مجموعة من الصور المشابهة لصورة الإستعلام (Query image). يمكن زيادة هذا الرقم حسب الرغبة مع مراعاة إجراء بعض التغييرات في الكود الخاص لعرض هذه الصور والذي سوف نكتبه لاحقاً.
السطر رقم (2): هذا الكود لغرض إعادة ترتيب عناصر المتجه (Vector) الذي يحتوي على المسافات (Distances), حيث يعاد ترتيب عناصره حسب القرب من بيانات صورة الإستعلام, حيث إن قيمة المسافة تكون صغيرة كلما كانت الصورة الأكثر شبهاً بصورة الإستعلام وتكبر هذه القيمة كلما كانت درجة الشبه أقل.
ولأجل التوضيح أكثر نقوم بتفكيك هذا السطر إلى مايلي:
الجملة (sorted_distance_with_labels[:, 0]) تعني إننا نستخلص المتجه الخاص بالمسافات (distances) فقط .
الجملة (sorted_distance_with_labels[:, 0].argsort()) تعني ترتيب قيم المسافات (distances) من القيمة الصغيرة فصاعداً ولكن عن طريق التسلسل (Index) لهذه المسافات.
وأخيراً الجملة النهائية تعني إن المتجه (sorted_distance_with_labels) سوف ترتب عناصره ترتيباً جديداً حسب قيمة المسافة حيث ترتب من القيمة الصغيرة (أي الأقرب لصورة الإستعلام) فصاعداً.
السطر رقم (4): لجلب المتجه الخاص بالتسميات (Labels) من المتجه السابق بعد الترتيب الجديد, حيث تم جلبه عن طريق تعينين مكانه في المتجه الرئيسي حيث ترتيب مكانه هو الثاني لذلك إستخدمنا الدليل ([:, 1]).
السطر رقم (5): لجلب المتجه الخاص بالتسلسل, حيث إستخدمنا الدليل ([:, 2]).
السطر رقم (6): إختيار أول عشرة عناصر من متجه التسلسل الذي حصلنا عليه من السطر السابق, حيث تكون عناصر هذا المتجه غير مرتبة لأنها تتبع لترتيب متجه المسافات (distances). علماً بأنَّ الرقم (10) قد حددناه سابقاً عن طريق المتغير (n_samples).إنَّ هذه العناصر العشرة يشير كل عنصر إلى تسلسل إحدى بيانات الصور ضمن مجموعة (x_train) والتي هي الأقرب من حيث المسافة لصورة الإستعلام.
السطر رقم (1): إختيار بيانات الصورة الأولى الأقرب لصورة الإستعلام (Query image), وذلك بإستخدام العنصر الأول من عناصر المتجه (kept_indexes) والذي يحوي عشرة عناصر فقط, حيث إستخدمنا قيمة هذا العنصر كدليل (Index) لمتجه بيانات الصور (x_train) لجلب الصورة المطلوبة.
السطر رقم (2): إنشاء حلقة تكرار تتكرر تسعة مرات.
السطر رقم (3): البدء بجلب بيانات الصور ذوات المسافات الأقرب لصورة الإستعلام , حيث نبدأ من الصورة التي دليلها هو العنصر الثاني من عناصر المتجه (kept_indexes), وبعدها الصورة التي يكون دليلها هوالعنصر الثالث من عناصر هذا المتجه, وهذا إلى أن تكتمل عشرة صور (الصورة الأولى أنشأناها في السطر الأول). إنَّ الدالة (np.hstack) تقوم بلصق الصور العشرة بحيث تصبح صورة واحدة ذات الشكل (28, 280, 1), حيث نلاحظ أنَّ عرض هذه الصورة يعادل عرض عشرة صور (28 x 10).
السطر رقم (5): للتخلص من البعد الثالث لكي تكون جاهزة للعرض في المرحلة اللاحقة.
السطر رقم (6): لإختيار بيانات صورة الإستعلام من بين مجموعة البيانات (x_test).
السطر رقم (7): للتخلص من البعد الثالث لبيانات صورة الإستعلام (Query image).
الأسطر من (1) لغاية (12): لأجل عرض صورة الإستعلام (Query image) وكذلك عرض مجموعة الصور القريبة الشبه لها وقد إخترنا عشرة صور كما مر بنا, وكذا وضعنا عنوان فوق صورة الإستعلام وكذلك فوق الصور الأخرى.
السطر رقم (1): لتحديد المساحة الكلية التي يتم عرض مجموعة الصور داخلها.
السطر رقم (2): لتعيين مكان عرض الصورة الأصلية (original_image), حيث إنها سوف تظهر في الصف الأول لأن تسلسلها (1), حيث الرقم الأول من اليسار يمثل عدد الصفوف والذي بعده يمثل عدد الأعمدة والذي بعده (الذي من اليمين) يمثل تسلسل الصورة.
السطر رقم (3): لعرض الصورة الأصلية.
السطر رقم (7): لتعيين موقع عرض الصورة التي تحوي جميع الصور المسترجعة والقريبة الشبه بالصورة الأصلية, حيث أعطيناها التسلسل (2) وبذلك سوف تظهر في الصف الثاني, لأن الصف الواحد يحتوي على عمود واحد فقط.
السطر رقم (8): لعرض الصورة التي تحوي جميع الصور المسترجعة (retrieved_images).
وبعد تنفيذ الكود نحصل على الصورة التالية:
وبهذا نكون قد إنتهينا من هذه المقالة بجميع أجزائها الخمسة, حيث إستعرضنا في هذا الجزء النوع الخامس من أنواع إستعادة الصور وهو إستعادة الصور بدلالة المحتوى (Content Based Image Retrieval), والذي يستخدم بشكل كبير في قواعد البيانات التي تحوي الصور وذلك للإستعلام عن الصور المطلوبة, كذلك تستخدم هذه التقنية في محركات البحث التي تستخدم الصور في عملية البحث.
أرجو أن أكون قد وفقت في المساهمة في توضيح هذا الموضوع.
ومن ألله تعالى نستمد العون والسداد.
المهندس حسن فنجان عداي
تعليقات
إرسال تعليق