تطبيق كشف قائمة انتظار Vertex AI Vision

1. الأهداف

نظرة عامة

سيركّز هذا الدرس التطبيقي حول الترميز على إنشاء تطبيق Vertex AI Vision بشكل شامل لمراقبة حجم قائمة الانتظار باستخدام لقطات فيديو البيع بالتجزئة. سنستخدم الميزات المضمّنة في النموذج المتخصص والمدرّبة مسبقًا إحصاءات الإشغال لتسجيل الأشياء التالية:

  • احسب عدد الأشخاص الذين يقفون في قائمة الانتظار.
  • احسب عدد الأشخاص الذين يتلقون الخدمة في مكتب الخدمة.

المعلومات التي ستطّلع عليها

  • طريقة إنشاء تطبيق في Vertex AI Vision ونشره
  • كيفية إعداد بث لبروتوكول RTSP باستخدام ملف فيديو ونقل البث إلى Vertex AI Vision باستخدام برنامج vaictl من كمبيوتر Jupyter Notebook
  • كيفية استخدام نموذج "إحصاءات الإشغال" وميزاته المختلفة.
  • كيفية البحث عن فيديوهات في مساحة التخزين في Vertex AI Vision's Media Warehouse
  • كيفية ربط الناتج بأداة BigQuery، وكتابة طلب بحث SQL لاستخراج الإحصاءات من نتائج json للنموذج واستخدام النتائج لتصنيف الفيديو الأصلي وإضافة تعليقات توضيحية إليه

التكلفة:

وتبلغ التكلفة الإجمالية لتشغيل هذا التمرين على Google Cloud حوالي دولارين أمريكيين.

2. قبل البدء

إنشاء مشروع وتفعيل واجهات برمجة التطبيقات:

  1. في "وحدة تحكُّم Google Cloud"، وفي صفحة أداة اختيار المشاريع، اختَر أو أنشئ مشروعًا على Google Cloud. ملاحظة: إذا كنت لا تخطط للاحتفاظ بالموارد التي تنشئها في هذا الإجراء، يمكنك إنشاء مشروع بدلاً من اختيار مشروع حالي. بعد الانتهاء من هذه الخطوات، يمكنك حذف المشروع وإزالة جميع الموارد المرتبطة به. الانتقال إلى أداة اختيار المشروع
  2. تأكَّد من تفعيل الفوترة لمشروعك على السحابة الإلكترونية. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع.
  3. يمكنك تفعيل Compute Engine وVertex API و Notebook API وVision AI API. تفعيل واجهات برمجة التطبيقات

إنشاء حساب خدمة:

  1. في وحدة تحكُّم Google Cloud، انتقِل إلى صفحة إنشاء حساب خدمة. الانتقال إلى "إنشاء حساب خدمة"
  2. اختَر مشروعك.
  3. في حقل اسم حساب الخدمة، أدخِل اسمًا. تملأ وحدة التحكّم في Google Cloud حقل رقم تعريف حساب الخدمة بناءً على هذا الاسم. في حقل وصف حساب الخدمة، أدخِل وصفًا. على سبيل المثال، حساب الخدمة للبدء السريع.
  4. انقر على إنشاء ومتابعة.
  5. لمنح الإذن بالوصول إلى مشروعك، امنح حساب الخدمة الأدوار التالية:
  • الذكاء الاصطناعي (AI) > أداة تعديل Vision AI
  • Compute Engine > Compute Instance Admin (إصدار تجريبي)
  • BigQuery > مشرف BigQuery .

في قائمة اختيار دور، اختَر دورًا. للحصول على أدوار إضافية، انقر على إضافة دور آخر وأضِف كل دور إضافي.

  1. انقر على متابعة.
  2. انقر على تمّ للانتهاء من إنشاء حساب الخدمة. لا تغلِق نافذة المتصفّح. ستستخدمه في الخطوة التالية.

3- إعداد أداة جوبيتر نوتبوك

قبل إنشاء تطبيق في "إحصاءات الإشغال"، عليك تسجيل بث يمكن للتطبيق استخدامه لاحقًا.

في هذا البرنامج التعليمي، تقوم بإنشاء مثيل Jupyter Notebook يستضيف مقطع فيديو، وترسل بيانات بث الفيديو هذه من الدفتر. نحن نستخدم أداة جوبيتر نوتبوك لأنه يقدم لنا المرونة في تنفيذ أوامر واجهة الأوامر بالإضافة إلى تشغيل التعليمات البرمجية المخصصة قبل/بعد المعالجة في مكان واحد، الأمر الذي يعتبر أفضل من حيث إجراء التجارب السريعة. ونستخدم هذا الدفتر من أجل:

  1. تشغيل خادم rtsp كعملية في الخلفية
  2. تشغيل الأمر vaictl كعملية في الخلفية
  3. تنفيذ طلبات البحث ومعالجة الرمز البرمجي لتحليل نتائج إحصاءات الإشغال

إنشاء دفتر جوبيتر نوتبوك

تتمثل الخطوة الأولى في إرسال الفيديو من مثيل جوبيتر نوتبوك في إنشاء الدفتر باستخدام حساب الخدمة الخاص بنا الذي تم إنشاؤه في الخطوة السابقة.

  1. في وحدة التحكّم، انتقِل إلى صفحة Vertex AI. الانتقال إلى Vertex AI Workbench
  2. انقر على دفاتر الملاحظات المُدارة من قِبل المستخدم

65b7112822858dce.png

  1. انقر على دفتر ملاحظات جديد > Tensorflow Enterprise 2.6 (مع قناة الدعم الطويل الأمد (LTS) > بدون وحدات معالجة رسومات

dc156f20b14651d7.png

  1. يُرجى إدخال اسم دفتر ملاحظات جوبيتر. لمزيد من المعلومات، يُرجى الاطّلاع على اصطلاح تسمية الموارد.

b4dbc5fddc37e8d9.png

  1. انقر على خيارات متقدّمة
  2. الانتقال إلى أقسام الأذونات
  3. إزالة العلامة من المربّع استخدام حساب الخدمة التلقائي في Compute Engine
  4. أضِف عنوان البريد الإلكتروني لحساب الخدمة الذي تم إنشاؤه في الخطوة السابقة. وانقر على إنشاء.

ec0b9ef00f0ef470.png

  1. بعد إنشاء المثيل، انقر على OPEN JUPYTERLAB.

4. إعداد دفتر ملاحظات لبث الفيديو المباشر

قبل إنشاء تطبيق في "إحصاءات الإشغال"، عليك تسجيل بث يمكن للتطبيق استخدامه لاحقًا.

في هذا البرنامج التعليمي، سنستخدم مثيل جوبيتر نوتبوك لاستضافة مقطع فيديو، وإرسال بيانات بث الفيديو المباشر من الوحدة الطرفية للمفكرة.

تنزيل أداة سطر أوامر vaictl

  1. في مثيل Jupyterlab المفتوح، افتح مفكرة من مشغّل التطبيقات.

a6d182923ae4ada3.png

  1. نزِّل أداة سطر أوامر Vertex AI Vision (vaictl)، وأداة سطر أوامر خادم rtsp، وأداة open-cv باستخدام الأمر التالي في خلية ورقة الملاحظات:
!wget -q https://github.com/aler9/rtsp-simple-server/releases/download/v0.20.4/rtsp-simple-server_v0.20.4_linux_amd64.tar.gz
!wget -q https://github.com/google/visionai/releases/download/v0.0.4/visionai_0.0-4_amd64.deb
!tar -xf rtsp-simple-server_v0.20.4_linux_amd64.tar.gz
!pip install opencv-python --quiet
!sudo apt-get -qq remove -y visionai
!sudo apt-get -qq install -y ./visionai_0.0-4_amd64.deb
!sudo apt-get -qq install -y ffmpeg

5- نقل ملف فيديو للبث

بعد إعداد بيئة دفتر الملاحظات باستخدام أدوات سطر الأوامر المطلوبة، يمكنك نسخ نموذج ملف فيديو ثم استخدام vaictl لبث بيانات الفيديو إلى تطبيق إحصاءات الإشغال.

تسجيل بث جديد

  1. انقر على علامة تبويب "البث" في اللوحة اليمنى من Vertex AI Vision.
  2. انقر على زر التسجيل في أعلى الصفحة eba418e723916514.png.
  3. في اسم مصدر البيانات، أدخِل 'queue-stream'
  4. في المنطقة، اختر المنطقة نفسها المحددة أثناء إنشاء ورقة الملاحظات في الخطوة السابقة.
  5. انقر على تسجيل.

نسخ نموذج فيديو إلى جهازك الافتراضي

  1. في دفتر الملاحظات، انسخ فيديو نموذجي باستخدام الأمر wget التالي.
!wget -q https://github.com/vagrantism/interesting-datasets/raw/main/video/collective_activity/seq25_h264.mp4

بث فيديوهات من جهاز افتراضي ونقل البيانات إلى البث

  1. لإرسال ملف الفيديو المحلي هذا إلى مصدر بيانات إدخال التطبيق، استخدِم الأمر التالي في خلية ورقة الملاحظات. يجب عليك إجراء البدائل المتغيرة التالية:
  • PROJECT_ID: رقم تعريف مشروعك على Google Cloud.
  • LOCATION: معرّف موقعك الجغرافي على سبيل المثال، us-central1. لمزيد من المعلومات، يُرجى الاطّلاع على المواقع الجغرافية في السحابة الإلكترونية.
  • LOCAL_FILE: اسم ملف فيديو محلي. على سبيل المثال، seq25_h264 .mp4
PROJECT_ID='<Your Google Cloud project ID>'
LOCATION='<Your stream location>'
LOCAL_FILE='seq25_h264.mp4'
STREAM_NAME='queue-stream'
  1. بدء خادم rtsp-simple حيث نبث ملف الفيديو باستخدام بروتوكول rtsp
import os
import time
import subprocess

subprocess.Popen(["nohup", "./rtsp-simple-server"], stdout=open('rtsp_out.log', 'a'), stderr=open('rtsp_err.log', 'a'), preexec_fn=os.setpgrp)
time.sleep(5)
  1. استخدام أداة سطر أوامر ffmpeg لتكرار الفيديو في بث rtsp
subprocess.Popen(["nohup", "ffmpeg", "-re", "-stream_loop", "-1", "-i", LOCAL_FILE, "-c", "copy", "-f", "rtsp", f"rtsp://localhost:8554/{LOCAL_FILE.split('.')[0]}"], stdout=open('ffmpeg_out.log', 'a'), stderr=open('ffmpeg_err.log', 'a'), preexec_fn=os.setpgrp)
time.sleep(5)
  1. استخدِم أداة سطر أوامر vaictl لبث الفيديو من معرّف الموارد المنتظم (URI) لخادم rtsp إلى مجموعة بث Vertex AI Vision "ساحة المشاركات في قائمة انتظار". أنشأناه في الخطوة السابقة.
subprocess.Popen(["nohup", "vaictl", "-p", PROJECT_ID, "-l", LOCATION, "-c", "application-cluster-0", "--service-endpoint", "visionai.googleapis.com", "send", "rtsp", "to", "streams", "queue-stream", "--rtsp-uri", f"rtsp://localhost:8554/{LOCAL_FILE.split('.')[0]}"], stdout=open('vaictl_out.log', 'a'), stderr=open('vaictl_err.log', 'a'), preexec_fn=os.setpgrp)

قد يستغرق الأمر حوالي 100 ثانية بين بدء عملية نقل البيانات وظهور الفيديو في لوحة البيانات.

بعد توفُّر إمكانية عرض البث، يمكنك الاطّلاع على خلاصة الفيديو في علامة التبويب أحداث البث في لوحة بيانات Vertex AI Vision من خلال اختيار البث أثناء البث في قائمة الانتظار.

الانتقال إلى علامة التبويب "ساحات المشاركات"

1b7aac7d36552f29.png

6- إنشاء تطبيق

الخطوة الأولى هي إنشاء تطبيق يعالج بياناتك. يمكن اعتبار التطبيق مسارًا آليًا يربط ما يلي:

  • نقل البيانات: يتم نقل خلاصة فيديو إلى بث.
  • تحليل البيانات: يمكن إضافة نموذج الذكاء الاصطناعي (AI) (رؤية الكمبيوتر) بعد عملية النقل.
  • تخزين البيانات: يمكن تخزين نسختَين من خلاصة الفيديو (البث الأصلي والبث الذي تمت معالجته بواسطة نموذج الذكاء الاصطناعي) في مستودع وسائط.

يتم تمثيل التطبيق في وحدة تحكُّم Google Cloud في شكل رسم بياني.

إنشاء تطبيق فارغ

قبل أن تتمكن من تعبئة الرسم البياني للتطبيق، يجب أولاً إنشاء تطبيق فارغ.

أنشئ تطبيقًا في وحدة تحكُّم Google Cloud.

  1. انتقِل إلى وحدة التحكم في Google Cloud.
  2. افتح علامة التبويب التطبيقات في لوحة بيانات Vertex AI Vision. الانتقال إلى علامة التبويب "التطبيقات"
  3. انقر على الزر إنشاء. 21ecba7a23e9979e.png
  4. أدخِل تطبيق "قائمة الانتظار" كاسم للتطبيق واختَر منطقتك.
  5. انقر على إنشاء.

إضافة عُقد لمكوِّنات التطبيق

بعد إنشاء التطبيق الفارغ، يمكنك إضافة العُقد الثلاثة إلى الرسم البياني للتطبيق:

  1. عقدة النقل: مورد البث الذي يستوعب البيانات المُرسَلة من خادم فيديو rtsp الذي أنشأته في ورقة الملاحظات
  2. عقدة المعالجة: نموذج إحصاءات الإشغال الذي يعمل على البيانات التي تم نقلها.
  3. عقدة التخزين: مستودع الوسائط الذي يخزِّن الفيديوهات التي تمّت معالجتها ويعمل كمخزن للبيانات الوصفية. تتضمّن عمليات تخزين البيانات الوصفية معلومات إحصائية حول بيانات الفيديو التي تم نقلها ومعلومات استنتاجها من خلال نماذج الذكاء الاصطناعي.

أضف عُقدًا مكونات إلى تطبيقك في وحدة التحكم.

  1. افتح علامة التبويب التطبيقات في لوحة بيانات Vertex AI Vision. الانتقال إلى علامة التبويب "التطبيقات"

وسينقلك هذا إلى الرسم البياني لمسار المعالجة.

إضافة عقدة نقل بيانات

  1. لإضافة عقدة مصدر إدخال، حدِّد الخيار ساحات المشاركات في قسم الموصلات في القائمة الجانبية.
  2. في القسم المصدر ضمن قائمة بث التي تفتح، اختَر إضافة أحداث بث.
  3. في القائمة إضافة مصادر بيانات، اختَر بث مباشر في قائمة المحتوى التالي.
  4. لإضافة ساحة المشاركات إلى الرسم البياني للتطبيق، انقر على إضافة ساحات مشاركات.

إضافة عقدة معالجة بيانات

  1. لإضافة عقدة نموذج عدد الإشغال، حدِّد خيار إحصاءات الإشغال في قسم النماذج المتخصصة من القائمة الجانبية.
  2. اترك الاختيارات التلقائية الأشخاص. أزِل العلامة من المربّع بجانب المركبات إذا سبق أن تم اختيارها.

618b0c9dc671bae3.png

  1. في قسم "الخيارات المتقدمة"، انقر على إنشاء مناطق/خطوط نشطة 5b2f31235603e05d.png.
  2. ارسم المناطق النشطة باستخدام أداة "المضلّع" لحساب عدد الأشخاص في تلك المنطقة. تسمية المنطقة وفقًا لذلك

50281a723650491f.png

  1. انقر على سهم الرجوع في الأعلى.

2bf0ff4d029d29eb.png

  1. أضف إعدادات مدة الثبات لاكتشاف الازدحام من خلال النقر على مربع الاختيار.

c067fa256ca5bb96.png

إضافة عقدة لتخزين البيانات

  1. لإضافة عقدة وجهة الناتج (التخزين)، حدِّد الخيار VIsion AI Warehouse في قسم الموصِّلات من القائمة الجانبية.
  2. انقر على موصل Vertex AI Warehouse لفتح قائمته، ثم انقر على ربط المستودع.
  3. في القائمة ربط المستودع، انقر على إنشاء مستودع جديد. أدخِل اسمًا للمستودع المستودع في قائمة الانتظار، واترك مدة البقاء (TTL) لمدة 14 يومًا.
  4. النقر على الزر إنشاء لإضافة المستودع

7. ربط الإخراج بجدول BigQuery

عند إضافة موصِّل BigQuery إلى تطبيق Vertex AI Vision، سيتم نقل جميع نتائج طُرز التطبيقات المرتبطة إلى الجدول المستهدَف.

يمكنك إمّا إنشاء جدول BigQuery وتحديد ذلك الجدول عند إضافة موصِّل BigQuery إلى التطبيق، أو السماح لمنصة تطبيق Vertex AI Vision بإنشاء الجدول تلقائيًا.

إنشاء الجداول تلقائيًا

في حال السماح لمنصة تطبيق Vertex AI Vision بإنشاء الجدول تلقائيًا، يمكنك تحديد هذا الخيار عند إضافة عقدة موصِّل BigQuery.

تنطبق شروط الجدول ومجموعة البيانات التالية إذا كنت تريد استخدام إنشاء الجداول تلقائيًا:

  • مجموعة البيانات: اسم مجموعة البيانات التي تم إنشاؤها تلقائيًا هو visionai_dataset.
  • الجدول: اسم الجدول الذي يتم إنشاؤه تلقائيًا هو visionai_dataset.APPLICATION_ID.
  • خطأ أثناء المعالجة:
  • في حال توفُّر جدول يحمل الاسم نفسه ضمن مجموعة البيانات نفسها، لا يتم إنشاء الجدول تلقائيًا.
  1. افتح علامة التبويب التطبيقات في لوحة بيانات Vertex AI Vision. الانتقال إلى علامة التبويب "التطبيقات"
  2. اختَر عرض التطبيق بجانب اسم تطبيقك من القائمة.
  3. في صفحة أداة إنشاء التطبيقات، اختَر BigQuery من قسم الموصلات.
  4. اترك حقل مسار BigQuery فارغًا.

ee0b67d4ab2263d.png

  1. في البيانات الوصفية للمتجر من: اختَر "إحصاءات الإشغال" فقط وأزِل العلامة من المربّع "مصادر البيانات".

يُفترض أن يبدو الرسم البياني النهائي للتطبيق على النحو التالي:

da0a1a049843572f.png

8. نشر تطبيقك للاستخدام

بعد إنشاء تطبيقك الشامل الذي يضم جميع المكونات اللازمة، فإن الخطوة الأخيرة لاستخدام التطبيق هي نشره.

  1. افتح علامة التبويب التطبيقات في لوحة بيانات Vertex AI Vision. الانتقال إلى علامة التبويب "التطبيقات"
  2. اختَر عرض التطبيق بجانب التطبيق قائمة المحتوى التالي في القائمة.
  3. من صفحة استوديو YouTube، انقر على الزر نشر.
  4. في مربّع حوار التأكيد التالي، انقر على نشر. قد يستغرق اكتمال عملية النشر عدة دقائق. بعد انتهاء النشر، تظهر علامات اختيار خضراء بجانب العُقد. dc514d9b9f35099d.png

9. البحث عن محتوى الفيديو في مستودع التخزين

بعد نقل بيانات الفيديو إلى تطبيق المعالجة، يمكنك عرض بيانات الفيديو التي تم تحليلها والبحث في البيانات استنادًا إلى معلومات إحصاءات الإشغال.

  1. افتح علامة التبويب Warehouses في لوحة بيانات Vertex AI Vision. الانتقال إلى علامة التبويب "المستودعات"
  2. ابحث عن مستودع مستودع قائمة الانتظار في القائمة، وانقر على الاطّلاع على مواد العرض.
  3. في قسم عدد الأشخاص، اضبط قيمة الحد الأدنى على 1 وقيمة الحد الأقصى على 5.
  4. لفلترة بيانات الفيديو التي تمت معالجتها المخزّنة في مستودع الوسائط في Vertex AI Vision، انقر على بحث.

a0e5766262443d6c.png

طريقة عرض بيانات الفيديو المخزَّنة التي تتطابق مع معايير البحث في Google Cloud Console

10. التعليق التوضيحي على الإخراج وتحليله باستخدام جدول BigQuery

  1. في دفتر الملاحظات، قم بتهيئة المتغيرات التالية في الخلية.
DATASET_ID='vision_ai_dataset'
bq_table=f'{PROJECT_ID}.{DATASET_ID}.queue-app'
frame_buffer_size=10000
frame_buffer_error_milliseconds=5
dashboard_update_delay_seconds=3
rtsp_url='rtsp://localhost:8554/seq25_h264'
  1. سنلتقط الآن الإطارات من تدفق rtsp باستخدام التعليمة البرمجية التالية:
import cv2
import threading
from collections import OrderedDict
from datetime import datetime, timezone

frame_buffer = OrderedDict()
frame_buffer_lock = threading.Lock()

stream = cv2.VideoCapture(rtsp_url)
def read_frames(stream):
  global frames
  while True:
    ret, frame = stream.read()
    frame_ts = datetime.now(timezone.utc).timestamp() * 1000
    if ret:
      with frame_buffer_lock:
        while len(frame_buffer) >= frame_buffer_size:
          _ = frame_buffer.popitem(last=False)
        frame_buffer[frame_ts] = frame

frame_buffer_thread = threading.Thread(target=read_frames, args=(stream,))
frame_buffer_thread.start()
print('Waiting for stream initialization')
while not list(frame_buffer.keys()): pass
print('Stream Initialized')
  1. اسحب معلومات الطابع الزمني للبيانات والتعليقات التوضيحية من جدول bigquery وأنشئ دليلاً لتخزين صور الإطارات التي تم التقاطها:
from google.cloud import bigquery
import pandas as pd

client = bigquery.Client(project=PROJECT_ID)

query = f"""
SELECT MAX(ingestion_time) AS ts
FROM `{bq_table}`
"""

bq_max_ingest_ts_df = client.query(query).to_dataframe()
bq_max_ingest_epoch = str(int(bq_max_ingest_ts_df['ts'][0].timestamp()*1000000))
bq_max_ingest_ts = bq_max_ingest_ts_df['ts'][0]
print('Preparing to pull records with ingestion time >', bq_max_ingest_ts)
if not os.path.exists(bq_max_ingest_epoch):
   os.makedirs(bq_max_ingest_epoch)
print('Saving output frames to', bq_max_ingest_epoch)
  1. قم بإضافة التعليقات التوضيحية للإطارات باستخدام التعليمة البرمجية التالية:
import json
import base64
import numpy as np
from IPython.display import Image, display, HTML, clear_output

im_width = stream.get(cv2.CAP_PROP_FRAME_WIDTH)
im_height = stream.get(cv2.CAP_PROP_FRAME_HEIGHT)

dashdelta = datetime.now()
framedata = {}
cntext = lambda x: {y['entity']['labelString']: y['count'] for y in x}
try:
  while True:
    try:
        annotations_df = client.query(f'''
          SELECT ingestion_time, annotation
          FROM `{bq_table}`
          WHERE ingestion_time > TIMESTAMP("{bq_max_ingest_ts}")
         ''').to_dataframe()
    except ValueError as e: 
        continue
    bq_max_ingest_ts = annotations_df['ingestion_time'].max()
    for _, row in annotations_df.iterrows():
      with frame_buffer_lock:
        frame_ts = np.asarray(list(frame_buffer.keys()))
        delta_ts = np.abs(frame_ts - (row['ingestion_time'].timestamp() * 1000))
        delta_tx_idx = delta_ts.argmin()
        closest_ts_delta = delta_ts[delta_tx_idx]
        closest_ts = frame_ts[delta_tx_idx]
        if closest_ts_delta > frame_buffer_error_milliseconds: continue
        image = frame_buffer[closest_ts]
      annotations = json.loads(row['annotation'])
      for box in annotations['identifiedBoxes']:
        image = cv2.rectangle(
          image,
          (
            int(box['normalizedBoundingBox']['xmin']*im_width),
            int(box['normalizedBoundingBox']['ymin']*im_height)
          ),
          (
            int((box['normalizedBoundingBox']['xmin'] + box['normalizedBoundingBox']['width'])*im_width),
            int((box['normalizedBoundingBox']['ymin'] + box['normalizedBoundingBox']['height'])*im_height)
          ),
          (255, 0, 0), 2
        )
      img_filename = f"{bq_max_ingest_epoch}/{row['ingestion_time'].timestamp() * 1000}.png"
      cv2.imwrite(img_filename, image)
      binimg = base64.b64encode(cv2.imencode('.jpg', image)[1]).decode()
      curr_framedata = {
        'path': img_filename,
        'timestamp_error': closest_ts_delta,
        'counts': {
          **{
            k['annotation']['displayName'] : cntext(k['counts'])
            for k in annotations['stats']["activeZoneCounts"]
          },
          'full-frame': cntext(annotations['stats']["fullFrameCount"])
        }
      }
      framedata[img_filename] = curr_framedata
      if (datetime.now() - dashdelta).total_seconds() > dashboard_update_delay_seconds:
        dashdelta = datetime.now()
        clear_output()
        display(HTML(f'''
          <h1>Queue Monitoring Application</h1>
          <p>Live Feed of the queue camera:</p>
          <p><img alt="" src="{img_filename}" style="float: left;"/></a></p>
          <table border="1" cellpadding="1" cellspacing="1" style="width: 500px;">
            <caption>Current Model Outputs</caption>
            <thead>
              <tr><th scope="row">Metric</th><th scope="col">Value</th></tr>
            </thead>
            <tbody>
              <tr><th scope="row">Serving Area People Count</th><td>{curr_framedata['counts']['serving-zone']['Person']}</td></tr>
              <tr><th scope="row">Queueing Area People Count</th><td>{curr_framedata['counts']['queue-zone']['Person']}</td></tr>
              <tr><th scope="row">Total Area People Count</th><td>{curr_framedata['counts']['full-frame']['Person']}</td></tr>
              <tr><th scope="row">Timestamp Error</th><td>{curr_framedata['timestamp_error']}</td></tr>
            </tbody>
          </table>
          <p>&nbsp;</p>
        '''))
except KeyboardInterrupt:
  print('Stopping Live Monitoring')

9426ffe2376f0a7d.png

  1. إيقاف مهمة التعليق التوضيحي باستخدام الزر إيقاف في شريط قوائم ورقة الملاحظات

6c19cb00dcb28894.png

  1. يمكنك إعادة النظر في الإطارات الفردية باستخدام الرمز التالي:
from IPython.html.widgets import Layout, interact, IntSlider
imgs = sorted(list(framedata.keys()))
def loadimg(frame):
    display(framedata[imgs[frame]])
    display(Image(open(framedata[imgs[frame]]['path'],'rb').read()))
interact(loadimg, frame=IntSlider(
    description='Frame #:',
    value=0,
    min=0, max=len(imgs)-1, step=1,
    layout=Layout(width='100%')))

78b63b546a4c883b.png

11. تهانينا

تهانينا، لقد أنهيت التمرين المعملي.

إخلاء مساحة

لتجنُّب تحمُّل الرسوم المفروضة على حسابك على Google Cloud مقابل الموارد المُستخدَمة في هذا الدليل التوجيهي، يمكنك إما حذف المشروع الذي يحتوي على الموارد أو الاحتفاظ بالمشروع وحذف الموارد الفردية.

حذف المشروع

حذف موارد فردية

المراجع

https://cloud.google.com/vision-ai/docs/overview

https://cloud.google.com/vision-ai/docs/occupancy-count-tutorial

الترخيص

استطلاع

كيف استخدمت هذا البرنامج التعليمي؟

القراءة فقط قرأته وأكملت التدريبات

ما مدى فائدة هذا الدرس التطبيقي حول الترميز؟

مفيدة جدًا مفيدة نوعًا ما غير مفيد

ما مدى سهولة اتباع هذا الدرس التطبيقي حول الترميز؟

سهل معتدِلة صعب