المقدّمة
خلال الآونة الأخيرة أصبحت عمليّة تحقيق التّباعد الاجتماعيّ في الأماكن العامّة والمغلقة هاجساً كبيراً، ولاسيما مع ضرورة الحماية من انتقال فيروس كوفيد-19 المنتشر في أرجاء العالم، لذلك توجّهت معظم الأبحاث إلى الاستفادة من تقنيّات الرؤية الحاسوبيّة لدراسة احتماليّة الازدحام في مكان ما، والعمل على حلّ هذه المشاكل وخصوصاً في المباني وضمن المكاتب، من خلال الكشف عن الكائنات المتعدّدة في حيّز ما وتتبّعها.
يعتبر تتبّع الكائنات المتعدّدة Multi-object Tracking، من أبرز مجالات البحث في الرؤية الحاسوبيّة، والتي لاتزال قيد الدّراسة والتّطوير. تعمل خوارزميّات تتبّع الكائنات المتعدّدة على تحديد مواقع الكائنات المتحرّكة في إطارات الفيديو، وتتبّعهم من أجل جميع الإطارات التالية، بحيث نتعامل مع مقطع الفيديو على أنّه عبارة عن مجموعة من الإطارات (الصور) المتتالية.
فعلى سبيل المثال:
- من الممكن تتبّع حركة الأشخاص في مكان ما.
- تتبّع حركة السّيارات في الطّريق.
- تتبّع حركة اللّاعبين في الملعب.
- تتبّع حركة الكائنات الحيّة الدّقيقة في بيئة ما.
أمّا من أبرز تطبيقاته، فتتنوع في:
- مجالات الأمن.
- مراقبة توزّع مجموعة من الأشخاص في مبنًى بهدف دراسة تحقيق التّباعد الاجتماعيّ
- التّحقّق من توازن المساحات المشغولة.
أما من أبرز المشاكل التي تواجه مسألة التّتبع فهي:
- التّغير المفاجئ في شكل الكائنات.
- تداخل الكائنات في موقع ما، كأن يقف كائن خلف أو أمام كائن آخر.
- السّرعة في التّتبع بما يتوافق مع عدد إطارات الفيديو في الثّانية، وبالتّالي إمكانيّة الاستفادة منها في تطبيقات الزّمن الحقيقيّ Real time.
اعتمدت المقالة المنشورة السّابقة في المدوّنة [1] على centroid tracking، وكانت المشكلة الأساسيّة فيها بأنّها كانت تحتاج إلى تشغيل كاشف للكائنات من أجل كلّ إطار في الفيديو، وهو ما يُعتبر من الأمور غير المجدِية، نظراً للزّمن الكبير نسبيّاً الذي يحتاجه تشغيل الكاشفات من أجل كلّ إطار، وبذلك فمن غير الممكن الاعتماد على هذه الطّريقة في التّطبيقات التي يُعتبر زمن التّنفيذ عاملاً مهماً فيها (تطبيقات الزمن الحقيقي).
يمكن حلّ هذه المشكلة عن طريق تطبيق كاشف الكائنات ولمرّة واحدة ومن ثَمّ تتبّع هذه الكائنات من أجل كلّ إطار من الإطارات، وبذلك يصبح من الممكن الحصول على النّتائج المطلوبة وبسرعة أعلى.
بالاستفادة من التقنيّات الموجودة في المكتبة المفتوحة للرؤية الحاسوبيّة، سنعمل على كشف الكائنات الموجودة في مقطع فيديو بهدف تتبّعها في الإطارات التالية.
تدعم المكتبة المفتوحة للرؤية الحاسوبيّة مجموعة من الخوارزميّات (التقنيّات) المتعدّدة والمخصّصة لتتبّع الكائنات، وتتيح الأمر للمستخدمين بالاختيار من ضمن هذه التقنيّات المجهّزة ضمن هذه المكتبة. سيتمّ في الفقرة التّالية استعراض أهمّ هذه الخوارزميّات.
خوارزميّات تتبّع الكائنات في المكتبة المفتوحة للرؤية الحاسوبية OpenCV
جُهزت المكتبة بثماني خوارزميّات مصمّمة لتتبّع الكائنات في الفيديو، وهي موضّحة في الشّكل (2):
- BOOSTING TRACKER تعزيز التعقب
تعتمد على تقنيّة Haar cascading المستخدمة في تطبيقات تعلّم الآلة، ولكن تعتبر من التّطبيقات القديمة نسبيّاً.
وكما في تقنيّة هار Haar فإنّها تحتاج إلى زمن تنفيذ كبير، وبالتّالي لا تصلح لتطبيقات الزّمن الحقيقيّ.
- Multiple Instance Learning) MIL Tracker) تعلّم النّماذج المتعدّدة
تعتمد هذه التّقنية على تدريب المتعقّب لفصل الكائنات المراد تعقّبها عن خلفيّة المشهد المدروس، وتُعتبر أفضل من الخوارزميّة السّابقة من ناحية معامل الدّقة accuracy، ولكن لا تخلو نتائجها من الأخطاء.
- KCF (Kernelized Correlation Filters) مرشّح الارتباط النووي
تعمل هذه التّقنيّة على تدريب مرشّح الارتباط على مناطق الصّورة التي تحتوي على الكائنات المراد تتبّعها بالإضافة إلى المناطق المجاورة لها والتي لا تحتوي هذه الكائنات، وذلك بهدف فحص المناطق القريبة من أجل الإطارات التّالية، والتي من المحتمل أن تحتوي على الكائنات فيها.
تُعدّ أفضل من الخوارزميّتين السّابقتين من ناحية السّرعة في الأداء، إلّا أنّها تفشل في حال التّداخل الكبير لعناصر الصّورة في المشهد.
- CSRT Tracker: Discriminative Correlation Filter مرشّح الارتباط المميّز
تعمل هذه التّقنيّة على أساس تدريب مرشّح الارتباط بمميّزات مستخلَصة من الصّورة، بهدف تعقّب الكائنات من خلال البحث في جوارات تموضعها في الإطار السابق[3]. ظهرت في إصدارات المكتبة المفتوحة للرؤية الحاسوبيّة الأحدث نوعاً ما (ابتداءً 3.4.2)، وتعتبر أعلى دقّة من التقنيّات السّابقة ولكن تعاني من بطءٍ في التنفيذ.
- MedianFlow Tracker متعقّبات التدفّق المتوسّط
من التّقنيّات ذات النتائج بنسبِ أخطاء مقبولة، ولكن يظهر ضعف هذه التّقنيّة في المشاهد ذات الكائنات التي لها حركات سريعة، أو المشاهد التي يتغيّر فيها المظهر العامّ.
- TLD tracker
من التّقنيّات التي تجمع بين ثلاثة مهامّ وهي التعقّب tracking، التعلّم learning، والكشف detection، عن طريق تتبّع الكائنات من إطار لإطار، والكشف عنه بناءً على المعلومات التي حصل عليها من مرحلة التعلّم. مع ذلك تُعتبر من التقنيّات غير المُوصى باستخدامها بسبب نتائج قيمة التنبّؤ الإيجابيّ الخاطئة(false-positive) الناتجة عنها.
- MOSSE Tracker الحدّ الأدنى لمجموع مربّعات الأخطاء
وهي اختصار Minimum Output Sum of Squared Error، من التّقنيّات السّريعة جداً، تستخدم في التّطبيقات التي تحتاج إلى سرعة عالية في التّنفيذ. أما من ناحية الدّقة فتتفوّق تقنيّتا CSRT أو KCF عليها. وأصبحت متوفّرة في إصدارات OpenCV 3.4.1
- GOTURN Tracker تتبّع الكائنات الشّامل باستخدام شبكات الانحدار
وهي اختصار Generic Object Tracking Using Regression Networks، تعتمد في تتبّع الكائنات على تقنيّات التعلّم العميق المضمّن في OpenCV
يبين الجدول التّالي خوارزميّات التتبّع والإصدارات التي تتوفّر فيها.
MOSSE | 3.4 |
MedianFlow | 3.2 |
TLD | 3.2 |
MIL | 3.2 |
Boosting | 3.2 |
KCF | 3.2 |
CSRT | 3.4 |
بشكلٍ عامٍّ يمكن تطبيق أيّ تقنيّة من التقنيّات المستخدمة لتتبّع كائن واحد في مقطع فيديو، وذلك بهدف تتبّع مجموعة من الكائنات معاً، وذلك بعد إضافة بعض التّعديلات البسيطة على الكود البرمجيّ.
مراحل تتبّع الكائنات في مقطع فيديو
خلال هذه المقالة، سنعمل على تتبّع مجموعة من الكائنات في مقطع فيديو، باستخدام كلٍّ من OpenCV 3.2 أو أعلى مع لغة البرمجة بايثون 3.9 Python، وذلك وفق المراحل التالية:
المرحلة الأولى:
في البداية و لتنفيذ البرنامج المُرفق نحتاج إلى تنصيب مكتبة imutils:
وهي عبارة عن مكتبة من مجموعة توابع لإنجاز عمليّات معالجة الصّور الأساسيّة، مثل الانسحاب، التّدوير، تغيير حجم الصّورة، استخراج هيكل عناصر الصّور skeletonization، بالإضافة إلى إمكانيّة عرض صور Matplotlib بشكل أسهل باستخدام كلٍّ من المكتبة المفتوحة للرؤية الحاسوبيّة و بايثون.
وذلك بتنفيذ السّطر التالي:
pip install --upgrade imutils
المرحلة الثّانية:
يلي ذلك عملية استيراد الحزم اللّازمة لعمل الشّيفرة البرمجيّة
from imutils.video import VideoStream
import argparse
import imutils
import time
import cv2
المرحلة الثّالثة:
في البداية لابدّ من تعريف المعاملات (arguments) التي يحتاجها البرنامج، من خلال إنشاء محلّل لهذه المعاملات argument parser كما يلي:
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", type=str,
help="path to input video file")
ap.add_argument("-t", "--tracker", type=str, default="kcf",
help="OpenCV object tracker type")
args = vars(ap.parse_args())
وحسب الكود الموضّح سابقاً، نلاحظ بأنّنا عرفنا اثنين من المعاملات وهما
– –video
الفيديو المراد تعقّب الكائنات الموجودة ضمنه
– –tracker
خوارزميّة التعقّب المستخدمة، والتي هي واحدة من التّقنيّات السّبعة المذكورة في الفقرة (2)، مع العلم بأن تقنيّة التتبّع الافتراضيّة في هذا الكود هي kcf
المرحلة الرّابعة:
نعمل على تعريف قاموس dictionary، بهدف ربط اسم كلّ تقنيّة تتبّع، مع الاسم البرمجي للتابع المقابل لها في OpenCV.
OPENCV_OBJECT_TRACKERS = {
"csrt": cv2.TrackerCSRT_create,
"kcf": cv2.TrackerKCF_create,
"boosting": cv2.TrackerBoosting_create,
"mil": cv2.TrackerMIL_create,
"tld": cv2.TrackerTLD_create,
"medianflow": cv2.TrackerMedianFlow_create,
"mosse": cv2.TrackerMOSSE_create
}
ومن التقنيّات المقترحة للتتبّع بشكلٍ عامٍّ نجد:
- KCF، من التقنيّات السّريعة والدّقيقة.
- CSRT، أكثر دقّة من KCF، وفي الوقت ذاته تعدّ الأبطأ.
- MOSSE، هي الأسرع مقارنةً بباقي التقنيّات، ولكنّها الأقلّ دقّة.
المرحلة الخامسة:
تهدف هذه المرحلة إلى إنشاء كيانات جديدة بهدف تتبّعها
trackers = cv2.MultiTracker_create ()
من خلال الطريقة (method)، cv2.MultiTracker_create:
- يمكننا إضافة كيان جديد للتتبّع tracker object إلى الصنف multitracker.
- إجراء التعديلات على كافّة كيانات التتبّع المعرفة مُسبقاً.
المرحلة السّادسة:
بعد الانتهاء من عمليّات تعريف المتحوّلات وتهيئتها، تأتي مرحلة إنشاء كيان للفيديو المراد تتبّع الكائنات ضمنه، ويتم ذلك بطريقتين:
-إما أن يكون الفيديو مخزّن على وحدات التّخزين، وبالتّالي يتمّ تزويد الكود بمساره، فتتمّ قراءة الفيديو من هذا المسار
-أو أن يتمّ إرسال أمر للكاميرا لالتقاط الفيديو ومعالجته بشكلٍ مباشر.
if not args.get("video", False):
- print("[INFO] starting video stream...")
- vs = VideoStream(src=0).start()
- time.sleep(1.0)
- # otherwise, grab a reference to the video file
- else:
- vs = cv2.VideoCapture(args["video"])
المرحلة السابعة:
وهي المرحلة التي يتمّ من خلالها (ضمن حلقة while)
أولا: قراءة كلّ إطار frame من إطارات الفيديو وصولاً إلى آخر إطار، مع الأخذ بعين الاعتبار بأن نميّز بين حالتي (تسجيل مباشر للفيديو، فيديو مسجل مسبقاً)
while True:
frame = vs.read()
frame = frame[1] if args.get("video", False) else frame
if frame is None:
break
ثانيا: تصغير أبعاد كلّ إطار في الفيديو، بهدف تسريع عمليّات المعالجة، وقد اختيرت القيمة 600 بكسل لكونها قيمة مقبولة نسبيّاً، بحيث نحصل على إطارات بأبعاد صغيرة وفي الوقت ذاته نحافظ على تفاصيل الكائنات ضمنها.
frame = imutils.resize(frame, width=600)
ثالثا: من أجل كلّ إطار في الفيديو، يعمل كائن التتبّع على إعادة احداثيّات المستطيل المحيط بكل كائن من كائنات الإطار، ومن ثَمّ رسم مستطيل الإحاطة، بلون أخضر وثخانة =2، بهدف تمييزه وسهولة تتبّعه.
(success, boxes) = trackers.update(frame)
for box in boxes:
(x, y, w, h) = [int(v) for v in box]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
رابعاً: يلي ذلك عمليّة إظهار الإطار الحاليّ
cv2.imshow("Frame", frame)
خامساً:
بعد مرحلة عرض الإطار، تأتي الخطوة الأكثر أهميّة وهي تحديد الكائن المراد تتبّعه، وتتم عمليّة التحديد من خلال المستخدم وبشكل مباشر، وذلك عن طريق تحديد المحرف المختار من لوحة المفاتيح كما يلي:
–s: وتعني اختيار select، بحيث يُرسم إطار يحيط بالكائن وذلك عن طريق استخدام الماوس، يلي ذلك تأكيد الاختيار بالضغط على مفتاح الدّخول (انتر) enter، أو المسافة space.
أما لإلغاء الاختيار فيمكن الضغط على مفتاح الهروب esc. كما وتتيح الخوارزميّة إمكانيّة تتبّع أكثر من كائن بآنٍ واحد من خلال رسم إطارات تحيط بكلّ كائنٍ على حدة.
key = cv2.waitKey(1) & 0xFF
if key == ord("s"):
box = cv2.selectROI("Frame", frame, fromCenter=False,
showCrosshair=True)
tracker = OPENCV_OBJECT_TRACKERS[args["tracker"]]()
trackers.add(tracker, frame, box)
– q: وتستخدم لإيقاف التّنفيذ
elif key == ord("q"):
break
تنتهي حلقة while، في الحالات التالية :
- عند انتهاء الفيديو، وبالتالي لا يوجد أي إطارات جديدة تحتاج للقراءة.
- حدوث خلل أثناء تسجيل المشاهد مباشرةً من قبل الكاميرا.
3. ضغط زر q من قبل المستخدم.
if not args.get("video", False):
vs.stop()
else:
vs.release()
cv2.destroyAllWindows()
بعد حلقة while، يتم إيقاف تسجيل الفيديو، في حال كان التّسجيل يتم عن طريق الكاميرا مباشرة، أو أن يتمّ تحرير ملف الفيديو، يلي ذلك إغلاق لنافذة الإظهار.
تنفيذ الكود
في البداية لابدّ من وجود نسخة OpenCV 3.4 على الأقلّ، يلي ذلك عمليّة تنفيذ السّطر التّالي:
python FileName.py --video path\VideoName.mp4 --tracker OpenCV_Object_Tracker
بحيث يتمّ استبدال
- FileName.py: باسم ملف الكود
- Path\VideoName.mp4: مسار الفيديو المراد قراءته، متبوعاً باسم الفيديو وامتداده وإلّا وفي حال عدم وجود هذا البارامتر، يتم تسجيل الفيديو من الكاميرا مباشرةً.
- OpenCV_Object_Tracker: خوارزميّة من خوارزميّات التتبّع السّبع السّابقة وإلّا وفي حال عدم اختيار أي خوارزميّة فسيتمّ اعتماد الخوارزميّة الافتراضيّة و المحدّدة بالبرنامج السابق kcf.
النتائج
بتطبيق التقنيّات السبع السّابقة على مقطع فيديو، لمجموعة من الأشخاص في مشهد خارجيّ نلاحظ ما يلي:
أولاً: CSRT
بتطبيق هذه التّقنية حصلنا على أفضل النّتائج ولاسيما من ناحية تداخل الأشخاص، بنسبة خطأ مقبولة
ثانياً: KCF
من ناحية المقطع المدروس كانت النّتائج غير جيدة؛ بحيث أنّه بمجرّد انتقال الهدف من الموقع الحاليّ لم يعد بوسع التقنيّة أن تتبع الشخص
ثالثاً: Boosting
كذلك الأمر فقد فشلت في حالات تداخل الأشخاص.
رابعاً: MIL
لم تكن نتائجها جيّدة من ناحية تداخل الأشخاص
خامساً: TLD
سادساً: medianFlow
سابعاً: MOSSE
وبذلك نجد بأن تقنيّة مرشّح الارتباط المميّز، قد أحرزت أفضل النّتائج بالنسبة للمقطع المدروس.
عزيزي القارئ يمكنك الاطلاع على كامل الشيفرة البرمجية في مستودع الجيت هب الخاص بموقع الذكاء الاصطناعي باللغة العربية.
الخاتمة
تعرّفنا خلال المقالة على التقنيّات المستخدمة لتتبّع الأشخاص، في مقطع فيديو ضمن المكتبة المفتوحة للرؤية الحاسوبيّة، وذلك من خلال استعراض الشّيفرة البرمجيّة بلغة بايثون، وتنفيذه على مقطع فيديو لمجموعة من الأشخاص في مشهد خارجيّ ومن ثَمّ مقارنة النّتائج التي حصلنا عليها.
وقد توصّلنا إلى أنّ تقنيّة مرشّح الارتباط المميّز قد حققت أفضل النّتائج، وحيث أنّ هذا المجال يعتبر من المجالات قيد البحث والتّطوير، فمن الممكن خلال مقالات تالية أن نستعرض تقنيّات أخرى للتتبّع المتعدّد مع ضمان الحصول على أفضل النّتائج.
تعليق واحد
اذا ممكن كيف يمكن التواصل معك بخصوص cv2