برنامه تشخیص صف ویژن Vertex AI

۱. اهداف

نمای کلی

این آزمایشگاه کد بر ایجاد یک برنامه Vertex AI Vision به صورت سرتاسری برای نظارت بر اندازه صف با استفاده از فیلم‌های ویدئویی خرده‌فروشی تمرکز خواهد کرد. ما از ویژگی‌های داخلی مدل تخصصی از پیش آموزش‌دیده تجزیه و تحلیل اشغال برای ثبت موارد زیر استفاده خواهیم کرد:

  • تعداد افرادی که در صف ایستاده‌اند را بشمارید.
  • تعداد افرادی که در پیشخوان خدمات دریافت می‌کنند را بشمارید.

آنچه یاد خواهید گرفت

  • نحوه ایجاد یک برنامه در Vertex AI Vision و استقرار آن
  • نحوه تنظیم یک جریان RTSP با استفاده از یک فایل ویدیویی و وارد کردن جریان به Vertex AI Vision با استفاده از vaictl از Jupyter Notebook.
  • نحوه استفاده از مدل Occupancy Analytics و ویژگی‌های مختلف آن.
  • نحوه جستجوی ویدیوها در فضای ذخیره‌سازی شما در انبار رسانه Vertex AI Vision.
  • نحوه اتصال خروجی به BigQuery، نوشتن کوئری SQL برای استخراج اطلاعات از خروجی json مدل و استفاده از خروجی برای برچسب‌گذاری و حاشیه‌نویسی ویدیوی اصلی.

هزینه:

هزینه کل اجرای این آزمایشگاه در گوگل کلود حدود ۲ دلار است.

۲. قبل از شروع

یک پروژه ایجاد کنید و API ها را فعال کنید:

  1. در کنسول گوگل کلود، در صفحه انتخاب پروژه، یک پروژه گوگل کلود را انتخاب یا ایجاد کنید . توجه : اگر قصد ندارید منابعی را که در این روش ایجاد می‌کنید، نگه دارید، به جای انتخاب یک پروژه موجود، یک پروژه ایجاد کنید. پس از اتمام این مراحل، می‌توانید پروژه را حذف کنید و تمام منابع مرتبط با پروژه را حذف کنید. به انتخاب پروژه بروید
  2. مطمئن شوید که صورتحساب برای پروژه ابری شما فعال است. یاد بگیرید که چگونه بررسی کنید که آیا صورتحساب در یک پروژه فعال است یا خیر .
  3. فعال کردن موتور محاسباتی (Compute Engine)، رابط برنامه‌نویسی کاربردی ورتکس (Vertex API)، رابط برنامه‌نویسی کاربردی نوت‌بوک (Notebook API) و رابط برنامه‌نویسی کاربردی هوش مصنوعی بینایی (Vision AI API).

ایجاد حساب کاربری سرویس:

  1. در کنسول گوگل کلود، به صفحه ایجاد حساب کاربری سرویس بروید. به بخش ایجاد حساب کاربری سرویس بروید .
  2. پروژه خود را انتخاب کنید.
  3. در فیلد نام حساب سرویس ، یک نام وارد کنید. کنسول گوگل کلود فیلد شناسه حساب سرویس را بر اساس این نام پر می‌کند. در فیلد توضیحات حساب سرویس ، توضیحی وارد کنید. به عنوان مثال، حساب سرویس برای شروع سریع.
  4. روی ایجاد کلیک کنید و ادامه دهید .
  5. برای دسترسی به پروژه خود، نقش(های) زیر را به حساب سرویس خود اعطا کنید:
  • هوش مصنوعی بینایی > ویرایشگر هوش مصنوعی بینایی
  • موتور محاسباتی > مدیریت نمونه محاسباتی (بتا)
  • بیگ‌کوئری > بخش مدیریت بیگ‌کوئری.

در لیست «انتخاب یک نقش» ، یک نقش را انتخاب کنید. برای نقش‌های اضافی، روی «افزودن نقش دیگر» کلیک کنید و هر نقش اضافی را اضافه کنید.

  1. روی ادامه کلیک کنید.
  2. برای پایان ایجاد حساب کاربری سرویس، روی «انجام شد» کلیک کنید. پنجره مرورگر خود را نبندید. در مرحله بعدی از آن استفاده خواهید کرد.

۳. راه‌اندازی نوت‌بوک ژوپیتر

قبل از ایجاد یک برنامه در Occupancy Analytics، باید یک جریان (stream) ثبت کنید که بعداً توسط برنامه قابل استفاده باشد.

در این آموزش شما یک نمونه از Jupyter Notebook ایجاد می‌کنید که میزبان یک ویدیو است و داده‌های ویدیویی در حال پخش را از Notebook ارسال می‌کنید. ما از Jupyter Notebook استفاده می‌کنیم زیرا به ما انعطاف‌پذیری لازم برای اجرای دستورات shell و همچنین اجرای کد پردازش پیش‌/پس‌ سفارشی را در یک مکان واحد می‌دهد که برای آزمایش سریع بسیار مناسب است. ما از این Notebook برای موارد زیر استفاده خواهیم کرد:

  1. اجرای سرور rtsp به عنوان یک فرآیند پس‌زمینه
  2. دستور vaictl را به عنوان فرآیند پس‌زمینه اجرا کنید
  3. اجرای کوئری‌ها و پردازش کد برای تحلیل خروجی تحلیل اشغال

یک دفترچه یادداشت ژوپیتر ایجاد کنید

اولین قدم برای ارسال ویدیو از یک نمونه Jupyter Notebook، ایجاد نوت‌بوک با حساب کاربری سرویسی است که در مرحله قبل ایجاد کرده‌ایم.

  1. در کنسول، به صفحه Vertex AI بروید. به Vertex AI Workbench بروید.
  2. روی دفترچه‌های مدیریت‌شده توسط کاربر کلیک کنید

65b7112822858dce.png

  1. روی دفترچه یادداشت جدید > Tensorflow Enterprise 2.6 (with LTS) > بدون پردازنده‌های گرافیکی کلیک کنید

dc156f20b14651d7.png

  1. نام مورد نظر برای نوت‌بوک ژوپیتر را وارد کنید. برای اطلاعات بیشتر، به «قرارداد نامگذاری منابع» مراجعه کنید.

b4dbc5fddc37e8d9.png

  1. روی گزینه‌های پیشرفته کلیک کنید
  2. به پایین اسکرول کنید تا به بخش‌های مجوزها برسید .
  3. تیک گزینه «استفاده از حساب پیش‌فرض سرویس موتور محاسباتی» را بردارید.
  4. ایمیل حساب سرویس ایجاد شده در مرحله قبل را اضافه کنید و روی ایجاد کلیک کنید.

ec0b9ef00f0ef470.png

  1. پس از ایجاد نمونه، روی OPEN JUPYTERLAB کلیک کنید.

۴. یک نوت‌بوک برای پخش ویدیو تنظیم کنید

قبل از ایجاد یک برنامه در Occupancy Analytics، باید یک جریان (stream) ثبت کنید که بعداً توسط برنامه قابل استفاده باشد.

در این آموزش ما از نمونه Jupyter Notebook خود برای میزبانی یک ویدیو استفاده خواهیم کرد و شما داده‌های ویدیوی در حال پخش را از ترمینال Notebook ارسال می‌کنید.

ابزار خط فرمان vaictl را دانلود کنید

  1. در نمونه‌ی باز شده‌ی Jupyterlab، از لانچر، یک دفترچه یادداشت (Notebook) باز کنید.

a6d182923ae4ada3.png

  1. ابزار خط فرمان Vertex AI Vision (vaictl)، ابزار خط فرمان rtsp server و ابزار 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

۵. دریافت یک فایل ویدیویی برای پخش آنلاین

پس از تنظیم محیط نوت‌بوک خود با ابزارهای خط فرمان مورد نیاز، می‌توانید یک فایل ویدیویی نمونه را کپی کرده و سپس از vaictl برای پخش داده‌های ویدیویی به برنامه تجزیه و تحلیل اشغال خود استفاده کنید.

ثبت جریان جدید

  1. روی تب Streams در پنل سمت چپ Vertex AI Vision کلیک کنید.
  2. روی دکمه ثبت نام در بالا کلیک کنید eba418e723916514.png
  3. در قسمت نام جریان، عبارت «queue-stream» را وارد کنید.
  4. در قسمت region، همان ناحیه‌ای را که در مرحله قبل هنگام ایجاد دفترچه یادداشت انتخاب کرده‌اید، انتخاب کنید.
  5. روی ثبت نام کلیک کنید

یک ویدیوی نمونه را در ماشین مجازی خود کپی کنید

  1. در دفترچه یادداشت خود، یک ویدیوی نمونه را با دستور wget زیر کپی کنید.
!wget -q https://github.com/vagrantism/interesting-datasets/raw/main/video/collective_activity/seq25_h264.mp4

پخش ویدئو از ماشین مجازی و دریافت داده‌ها به جریان شما

  1. برای ارسال این فایل ویدیویی محلی به جریان ورودی برنامه، از دستور زیر در سلول نوت‌بوک خود استفاده کنید. باید جایگزینی‌های متغیر زیر را انجام دهید:
  • PROJECT_ID: شناسه پروژه Google Cloud شما.
  • مکان: شناسه مکان شما. برای مثال، us-central1. برای اطلاعات بیشتر، به مکان‌های ابری مراجعه کنید.
  • فایل محلی: نام فایل ویدیویی محلی. برای مثال، 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 به استریم 'queue-stream' مربوط به 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)

ممکن است بین شروع عملیات دریافت پیام vaictl و نمایش ویدیو در داشبورد حدود ۱۰۰ ثانیه طول بکشد.

پس از اینکه دریافت استریم در دسترس قرار گرفت، می‌توانید با انتخاب استریم queue-stream، فید ویدیو را در تب Streams در داشبورد Vertex AI Vision مشاهده کنید.

به برگه جریان‌ها بروید

۱b7aac7d36552f29.png

۶. یک برنامه کاربردی ایجاد کنید

اولین قدم ایجاد یک برنامه است که داده‌های شما را پردازش کند. یک برنامه را می‌توان به عنوان یک خط لوله خودکار در نظر گرفت که موارد زیر را به هم متصل می‌کند:

  • دریافت داده : یک فید ویدیویی به یک جریان داده ارسال می‌شود.
  • تجزیه و تحلیل داده‌ها : یک مدل هوش مصنوعی (بینایی رایانه‌ای) می‌تواند پس از مصرف اضافه شود.
  • ذخیره‌سازی داده‌ها : دو نسخه از فید ویدیویی (جریان اصلی و جریان پردازش‌شده توسط مدل هوش مصنوعی) می‌توانند در یک انبار رسانه ذخیره شوند.

در کنسول گوگل کلود، یک برنامه به صورت یک گراف نمایش داده می‌شود.

ایجاد یک برنامه خالی

قبل از اینکه بتوانید نمودار برنامه را پر کنید، ابتدا باید یک برنامه خالی ایجاد کنید.

یک برنامه در کنسول Google Cloud ایجاد کنید.

  1. به کنسول گوگل کلود بروید.
  2. برگه برنامه‌ها را از داشبورد Vertex AI Vision باز کنید. به برگه برنامه‌ها بروید
  3. روی دکمه‌ی ایجاد کلیک کنید. 21ecba7a23e9979e.png
  4. عبارت « queue-app» را به عنوان نام برنامه وارد کنید و منطقه خود را انتخاب کنید.
  5. روی ایجاد کلیک کنید.

اضافه کردن گره‌های کامپوننت برنامه

بعد از اینکه برنامه خالی را ایجاد کردید، می‌توانید سه گره را به گراف برنامه اضافه کنید:

  1. گره مصرف : منبع جریانی که داده‌های ارسالی از سرور ویدیویی rtsp که در نوت‌بوک ایجاد کرده‌اید را مصرف می‌کند.
  2. گره پردازش : مدل تحلیل اشغال که بر روی داده‌های دریافتی عمل می‌کند.
  3. گره ذخیره‌سازی : انبار رسانه‌ای که ویدیوهای پردازش‌شده را ذخیره می‌کند و به عنوان یک مخزن فراداده عمل می‌کند. مخازن فراداده شامل اطلاعات تحلیلی در مورد داده‌های ویدیویی دریافت‌شده و اطلاعات استنباط‌شده توسط مدل‌های هوش مصنوعی هستند.

گره‌های کامپوننت را در کنسول به برنامه خود اضافه کنید.

  1. برگه برنامه‌ها را از داشبورد Vertex AI Vision باز کنید. به برگه برنامه‌ها بروید

این شما را به تجسم نمودار خط لوله پردازش می‌برد.

یک گره دریافت داده اضافه کنید

  1. برای افزودن یک گره جریان ورودی، گزینه Streams را در بخش Connectors از منوی کناری انتخاب کنید.
  2. در بخش منبع (Source) از منوی استریم (Stream) که باز می‌شود، گزینه‌ی «افزودن استریم‌ها» (Add streams) را انتخاب کنید.
  3. در منوی افزودن جریان‌ها ، گزینه‌ی queue-stream را انتخاب کنید.
  4. برای افزودن جریان به نمودار برنامه، روی «افزودن جریان‌ها» کلیک کنید.

افزودن یک گره پردازش داده

  1. برای افزودن گره مدل شمارش اشغال، گزینه تحلیل اشغال را در بخش مدل‌های تخصصی از منوی کناری انتخاب کنید.
  2. گزینه‌های پیش‌فرض «افراد» را باقی بگذارید. اگر «وسایل نقلیه» از قبل انتخاب شده است، تیک آن را بردارید.

618b0c9dc671bae3.png

  1. در بخش گزینه‌های پیشرفته، روی ایجاد مناطق/خطوط فعال کلیک کنید. 5b2f31235603e05d.png
  2. با استفاده از ابزار چندضلعی، مناطق فعال را رسم کنید تا افراد موجود در آن منطقه را بشمارید. منطقه را بر اساس آن برچسب‌گذاری کنید.

50281a723650491f.png

  1. روی فلش برگشت در بالا کلیک کنید.

2bf0ff4d029d29eb.png

  1. با کلیک روی کادر انتخاب، تنظیمات مربوط به زمان توقف برای تشخیص ازدحام را اضافه کنید.

c067fa256ca5bb96.png

افزودن یک گره ذخیره‌سازی داده

  1. برای افزودن گره مقصد خروجی (ذخیره‌سازی)، گزینه VIsion AI Warehouse را در بخش Connectors از منوی کناری انتخاب کنید.
  2. برای باز کردن منوی Vertex AI Warehouse Connector روی آن کلیک کنید، سپس Connect warehouse را انتخاب کنید.
  3. در منوی «اتصال انبار» ، «ایجاد انبار جدید» را انتخاب کنید. نام صف انبار را «انبار» بگذارید و مدت زمان TTL را روی ۱۴ روز بگذارید.
  4. برای اضافه کردن انبار، روی دکمه ایجاد کلیک کنید.

۷. خروجی را به جدول 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. گزینه View app را که در کنار نام برنامه شما قرار دارد، از لیست انتخاب کنید.
  3. در صفحه سازنده برنامه، از بخش Connectors ، BigQuery را انتخاب کنید.
  4. فیلد مسیر BigQuery را خالی بگذارید.

ee0b67d4ab2263d.png

  1. در فراداده‌های فروشگاه از: فقط «تحلیل اشغال» را انتخاب کنید و تیک گزینه «جریان‌ها» را بردارید.

نمودار نهایی برنامه باید به شکل زیر باشد:

da0a1a049843572f.png

۸. برنامه خود را برای استفاده مستقر کنید

بعد از اینکه برنامه‌ی خود را به همراه تمام اجزای لازم ساختید، آخرین مرحله برای استفاده از برنامه، استقرار آن است.

  1. برگه برنامه‌ها را از داشبورد Vertex AI Vision باز کنید. به برگه برنامه‌ها بروید
  2. گزینه «مشاهده برنامه» را در کنار برنامه صف انتظار در لیست انتخاب کنید.
  3. از صفحه استودیو ، روی دکمه Deploy کلیک کنید.
  4. در کادر تأیید زیر، روی Deploy کلیک کنید. عملیات استقرار ممکن است چند دقیقه طول بکشد. پس از اتمام استقرار، علامت‌های سبز رنگ در کنار گره‌ها ظاهر می‌شوند. dc514d9b9f35099d.png

۹. جستجوی محتوای ویدیویی در انبار ذخیره‌سازی

پس از اینکه داده‌های ویدیویی را به برنامه پردازش خود وارد کردید، می‌توانید داده‌های ویدیویی تحلیل‌شده را مشاهده کنید و داده‌ها را بر اساس اطلاعات تحلیلی مربوط به حضور افراد جستجو کنید.

  1. برگه انبارها را از داشبورد Vertex AI Vision باز کنید. به برگه انبارها بروید
  2. انبار صف-انبار را در لیست پیدا کنید و روی مشاهده دارایی‌ها کلیک کنید.
  3. در بخش تعداد افراد ، مقدار حداقل (Min) را روی ۱ و مقدار حداکثر (Max ) را روی ۵ تنظیم کنید.
  4. برای فیلتر کردن داده‌های ویدیویی پردازش‌شده‌ی ذخیره‌شده در انبار رسانه‌ی Vertex AI Vision، روی جستجو کلیک کنید.

a0e5766262443d6c.png

نمایی از داده‌های ویدیویی ذخیره‌شده که با معیارهای جستجو در کنسول Google Cloud مطابقت دارد.

۱۰. حاشیه‌نویسی و تحلیل خروجی با استفاده از جدول BigQuery

  1. در Notebook، متغیرهای زیر را در سلول مقداردهی اولیه کنید.
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

۱۱. تبریک

تبریک می‌گویم، آزمایشگاه را تمام کردید!

تمیز کردن

برای جلوگیری از تحمیل هزینه به حساب گوگل کلود خود برای منابع استفاده شده در این آموزش، یا پروژه‌ای که شامل منابع است را حذف کنید، یا پروژه را نگه دارید و منابع تکی را حذف کنید.

پروژه را حذف کنید

حذف منابع تکی

منابع

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

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

مجوز

نظرسنجی

چطور از این آموزش استفاده کردید؟

فقط تا انتها بخوانید آن را بخوانید و تمرین‌ها را انجام دهید

این آزمایشگاه کد چقدر مفید بود؟

بسیار مفید نسبتاً مفید مفید نیست

دنبال کردن این کدلاگ چقدر آسان بود؟

آسان متوسط دشوار