1. วัตถุประสงค์
ภาพรวม
Codelab นี้จะมุ่งเน้นการสร้างแอปพลิเคชัน Vertex AI Vision แบบครบวงจรเพื่อตรวจสอบขนาดคิวโดยใช้วิดีโอฟุตเทจของธุรกิจค้าปลีก เราจะใช้ฟีเจอร์ในตัวของโมเดลเฉพาะทางที่ฝึกไว้ล่วงหน้า Occupancy analytics เพื่อบันทึกสิ่งต่อไปนี้
- นับจำนวนคนที่ยืนต่อคิว
- นับจำนวนผู้ที่รับบริการที่เคาน์เตอร์
สิ่งที่คุณจะได้เรียนรู้
- วิธีสร้างแอปพลิเคชันใน Vertex AI Vision และติดตั้งใช้งาน
- วิธีตั้งค่าสตรีม RTSP โดยใช้ไฟล์วิดีโอและนำเข้าสตรีมไปยัง Vertex AI Vision โดยใช้ vaictl จาก Jupyter Notebook
- วิธีใช้โมเดลข้อมูลวิเคราะห์การเข้าพักและฟีเจอร์ต่างๆ
- วิธีค้นหาวิดีโอใน Media Warehouse ของ Vertex AI Vision ที่จัดเก็บไว้
- วิธีเชื่อมต่อเอาต์พุตกับ BigQuery, เขียนการค้นหา SQL เพื่อดึงข้อมูลเชิงลึกจากเอาต์พุต JSON ของโมเดล และใช้เอาต์พุตเพื่อติดป้ายกำกับและใส่คำอธิบายประกอบวิดีโอต้นฉบับ
ค่าใช้จ่าย:
ค่าใช้จ่ายทั้งหมดในการเรียกใช้ Lab นี้ใน Google Cloud อยู่ที่ประมาณ $2
2. ก่อนที่คุณจะเริ่มต้น
สร้างโปรเจ็กต์และเปิดใช้ API
- ในคอนโซล Google Cloud ให้เลือกหรือสร้างโปรเจ็กต์ Google Cloud ในหน้าตัวเลือกโปรเจ็กต์ หมายเหตุ: หากไม่ต้องการเก็บทรัพยากรที่สร้างขึ้นในขั้นตอนนี้ ให้สร้างโปรเจ็กต์แทนการเลือกโปรเจ็กต์ที่มีอยู่ หลังจากทำตามขั้นตอนเหล่านี้แล้ว คุณจะลบโปรเจ็กต์ซึ่งเป็นการนำทรัพยากรทั้งหมดที่เชื่อมโยงกับโปรเจ็กต์นี้ออกได้ ไปที่ตัวเลือกโปรเจ็กต์
- ตรวจสอบว่าได้เปิดใช้การเรียกเก็บเงินสำหรับโปรเจ็กต์ Cloud แล้ว ดูวิธีตรวจสอบว่าได้เปิดใช้การเรียกเก็บเงินในโปรเจ็กต์แล้วหรือไม่
- เปิดใช้ Compute Engine, Vertex API, Notebook API และ Vision AI API เปิดใช้ API
สร้างบัญชีบริการ
- ในคอนโซล Google Cloud ให้ไปที่หน้าสร้างบัญชีบริการ ไปที่สร้างบัญชีบริการ
- เลือกโปรเจ็กต์
- ป้อนชื่อในช่องชื่อบัญชีบริการ คอนโซล Google Cloud จะกรอกข้อมูลในช่องรหัสบัญชีบริการตามชื่อนี้ ป้อนคำอธิบายในช่องคำอธิบายบัญชีบริการ เช่น บัญชีบริการสำหรับ Quickstart
- คลิกสร้างและต่อไป
- หากต้องการให้สิทธิ์เข้าถึงโปรเจ็กต์ ให้มอบบทบาทต่อไปนี้ให้กับบัญชีบริการ
- Vision AI > โปรแกรมแก้ไข Vision AI
- Compute Engine > ผู้ดูแลระบบอินสแตนซ์ Compute (เบต้า)
- BigQuery > ผู้ดูแลระบบ BigQuery
เลือกบทบาทในรายการเลือกบทบาท หากต้องการเพิ่มบทบาทอื่น ให้คลิกเพิ่มบทบาทอื่น แล้วเพิ่มบทบาทเพิ่มเติมแต่ละบทบาท
- คลิกต่อไป
- คลิกเสร็จสิ้นเพื่อสร้างบัญชีบริการให้เสร็จสมบูรณ์ อย่าปิดหน้าต่างเบราว์เซอร์ คุณจะต้องใช้รหัสนี้ในขั้นตอนถัดไป
3. ตั้งค่า Jupyter Notebook
ก่อนสร้างแอปในข้อมูลวิเคราะห์การเข้าพัก คุณต้องลงทะเบียนสตรีมที่แอปจะใช้ในภายหลังได้
ในบทแนะนำนี้ คุณจะสร้างอินสแตนซ์สมุดบันทึก Jupyter ที่โฮสต์วิดีโอ และส่งข้อมูลวิดีโอสตรีมมิงจากสมุดบันทึก เราใช้ Jupyter Notebook เนื่องจากมีความยืดหยุ่นในการรันคำสั่งเชลล์ รวมถึงรันโค้ดการประมวลผลก่อน/หลังที่กำหนดเองได้ในที่เดียว ซึ่งเหมาะอย่างยิ่งสำหรับการทดลองอย่างรวดเร็ว เราจะใช้ Notebook นี้เพื่อดำเนินการต่อไปนี้
- เรียกใช้เซิร์ฟเวอร์ rtsp เป็นกระบวนการเบื้องหลัง
- เรียกใช้คำสั่ง vaictl เป็นกระบวนการพื้นหลัง
- เรียกใช้การค้นหาและโค้ดการประมวลผลเพื่อวิเคราะห์เอาต์พุตการวิเคราะห์การเข้าพัก
สร้าง Jupyter Notebook
ขั้นตอนแรกในการส่งวิดีโอจากอินสแตนซ์ Jupyter Notebook คือการสร้าง Notebook ด้วยบัญชีบริการที่เราสร้างขึ้นในขั้นตอนก่อนหน้า
- ไปที่หน้า Vertex AI ในคอนโซล ไปที่ Vertex AI Workbench
- คลิก Notebook ที่ผู้ใช้จัดการ

- คลิกสมุดบันทึกใหม่ > Tensorflow Enterprise 2.6 (พร้อม LTS) > ไม่มี GPU

- ป้อนชื่อสำหรับ Jupyter Notebook ดูข้อมูลเพิ่มเติมได้ที่แบบแผนการตั้งชื่อทรัพยากร

- คลิกตัวเลือกขั้นสูง
- เลื่อนลงไปที่ส่วนสิทธิ์
- ยกเลิกการเลือกตัวเลือกใช้บัญชีบริการเริ่มต้นของ Compute Engine
- เพิ่มอีเมลบัญชีบริการที่สร้างขึ้นในขั้นตอนก่อนหน้า แล้วคลิกสร้าง

- เมื่อสร้างอินสแตนซ์แล้ว ให้คลิกเปิด JUPYTERLAB
4. ตั้งค่า Notebook เพื่อสตรีมวิดีโอ
ก่อนสร้างแอปในข้อมูลวิเคราะห์การเข้าพัก คุณต้องลงทะเบียนสตรีมที่แอปจะใช้ในภายหลังได้
ในบทแนะนำนี้ เราจะใช้อินสแตนซ์สมุดบันทึก Jupyter เพื่อโฮสต์วิดีโอ และคุณจะส่งข้อมูลวิดีโอสตรีมมิงจากเทอร์มินัลสมุดบันทึก
ดาวน์โหลดเครื่องมือบรรทัดคำสั่ง vaictl
- ในอินสแตนซ์ Jupyterlab ที่เปิดอยู่ ให้เปิด Notebook จากตัวเรียกใช้

- ดาวน์โหลดเครื่องมือบรรทัดคำสั่ง Vertex AI Vision (vaictl), เครื่องมือบรรทัดคำสั่งเซิร์ฟเวอร์ RTSP และเครื่องมือ OpenCV โดยใช้คำสั่งต่อไปนี้ในเซลล์ Notebook
!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. ส่งผ่านข้อมูลไฟล์วิดีโอสำหรับการสตรีม
หลังจากตั้งค่าสภาพแวดล้อมของ Notebook ด้วยเครื่องมือบรรทัดคำสั่งที่จำเป็นแล้ว คุณสามารถคัดลอกไฟล์วิดีโอตัวอย่าง แล้วใช้ vaictl เพื่อสตรีมข้อมูลวิดีโอไปยังแอปวิเคราะห์การเข้าพักได้
ลงทะเบียนสตรีมใหม่
- คลิกแท็บสตรีมในแผงด้านซ้ายของ Vertex AI Vision
- คลิกปุ่มลงทะเบียนที่ด้านบน

- ในชื่อสตรีม ให้ป้อน "queue-stream"
- ในภูมิภาค ให้เลือกภูมิภาคเดียวกันกับที่เลือกไว้ในขั้นตอนก่อนหน้าตอนสร้าง Notebook
- คลิกลงทะเบียน
คัดลอกวิดีโอตัวอย่างไปยัง VM
- ใน Notebook ให้คัดลอกวิดีโอตัวอย่างด้วยคำสั่ง wget ต่อไปนี้
!wget -q https://github.com/vagrantism/interesting-datasets/raw/main/video/collective_activity/seq25_h264.mp4
สตรีมวิดีโอจาก VM และส่งผ่านข้อมูลไปยังสตรีม
- หากต้องการส่งไฟล์วิดีโอในเครื่องนี้ไปยังสตรีมอินพุตของแอป ให้ใช้คำสั่งต่อไปนี้ในเซลล์ Notebook คุณต้องทำการแทนที่ตัวแปรต่อไปนี้
- 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'
- เริ่ม rtsp-simple-server ที่เราสตรีมไฟล์วิดีโอด้วยโปรโตคอล 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)
- ใช้เครื่องมือบรรทัดคำสั่ง 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)
- ใช้เครื่องมือบรรทัดคำสั่ง 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)
โดยอาจใช้เวลาประมาณ 100 วินาทีระหว่างการเริ่มการดำเนินการส่งผ่านข้อมูล vaictl กับการปรากฏของวิดีโอในแดชบอร์ด
หลังจากที่การส่งผ่านข้อมูลสตรีมพร้อมใช้งานแล้ว คุณจะดูฟีดวิดีโอได้ในแท็บสตรีมของแดชบอร์ด Vertex AI Vision โดยเลือกสตรีมคิวสตรีม

6. สร้างแอปพลิเคชัน
ขั้นตอนแรกคือการสร้างแอปที่ประมวลผลข้อมูล คุณอาจคิดว่าแอปเป็นไปป์ไลน์อัตโนมัติที่เชื่อมต่อสิ่งต่อไปนี้
- การนำเข้าข้อมูล: ระบบจะนำเข้าฟีดวิดีโอลงในสตรีม
- การวิเคราะห์ข้อมูล: คุณเพิ่มโมเดล AI(Computer Vision) ได้หลังจากการนำเข้า
- การจัดเก็บข้อมูล: คุณจัดเก็บฟีดวิดีโอ 2 เวอร์ชัน (สตรีมต้นฉบับและสตรีมที่โมเดล AI ประมวลผล) ไว้ในคลังสื่อได้
ในคอนโซล Google Cloud แอปจะแสดงเป็นกราฟ
สร้างแอปเปล่า
ก่อนที่จะสร้างกราฟแอป คุณต้องสร้างแอปที่ว่างเปล่าก่อน
สร้างแอปในคอนโซล Google Cloud
- ไปที่คอนโซล Google Cloud
- เปิดแท็บแอปพลิเคชันของแดชบอร์ด Vertex AI Vision ไปที่แท็บแอปพลิเคชัน
- คลิกปุ่มสร้าง

- ป้อน "queue-app'" เป็นชื่อแอป แล้วเลือกภูมิภาค
- คลิกสร้าง
เพิ่มโหนดคอมโพเนนต์ของแอป
หลังจากสร้างแอปพลิเคชันที่ว่างเปล่าแล้ว คุณจะเพิ่ม 3 โหนดลงในกราฟแอปได้
- โหนดการส่งผ่านข้อมูล: แหล่งข้อมูลสตรีมที่ส่งผ่านข้อมูลซึ่งส่งจากเซิร์ฟเวอร์วิดีโอ RTSP ที่คุณสร้างใน Notebook
- โหนดการประมวลผล: โมเดลข้อมูลวิเคราะห์การเข้าพักที่ดำเนินการกับข้อมูลที่นำเข้า
- โหนดพื้นที่เก็บข้อมูล: คลังสื่อที่จัดเก็บวิดีโอที่ประมวลผลแล้ว และทำหน้าที่เป็นที่เก็บข้อมูลเมตา ที่เก็บข้อมูลเมตาประกอบด้วยข้อมูลวิเคราะห์เกี่ยวกับข้อมูลวิดีโอที่นำเข้า และข้อมูลที่โมเดล AI อนุมาน
เพิ่มโหนดคอมโพเนนต์ลงในแอปในคอนโซล
- เปิดแท็บแอปพลิเคชันของแดชบอร์ด Vertex AI Vision ไปที่แท็บแอปพลิเคชัน
การดำเนินการนี้จะนำคุณไปยังการแสดงภาพกราฟของไปป์ไลน์การประมวลผล
เพิ่มโหนดการนำเข้าข้อมูล
- หากต้องการเพิ่มโหนดสตรีมอินพุต ให้เลือกตัวเลือกสตรีมในส่วนตัวเชื่อมต่อของเมนูด้านข้าง
- ในส่วนแหล่งที่มาของเมนูสตรีมที่เปิดขึ้น ให้เลือกเพิ่มสตรีม
- ในเมนูเพิ่มสตรีม ให้เลือก queue-stream
- หากต้องการเพิ่มสตรีมลงในกราฟแอป ให้คลิกเพิ่มสตรีม
เพิ่มโหนดการประมวลผลข้อมูล
- หากต้องการเพิ่มโหนดโมเดลการนับการเข้าพัก ให้เลือกตัวเลือกข้อมูลวิเคราะห์การเข้าพักในส่วนโมเดลเฉพาะทางของเมนูด้านข้าง
- ปล่อยให้การเลือกเริ่มต้นเป็นผู้คน ยกเลิกการเลือกยานพาหนะหากเลือกไว้แล้ว

- ในส่วนตัวเลือกขั้นสูง ให้คลิกสร้างโซน/เส้นที่ใช้งานอยู่

- วาดโซนตรวจจับกิจกรรมโดยใช้เครื่องมือรูปหลายเหลี่ยมเพื่อนับจำนวนคนในโซนนั้น ติดป้ายกำกับโซนตามนั้น

- คลิกลูกศรกลับที่ด้านบน

- เพิ่มการตั้งค่าเวลาในการเข้าชมเพื่อตรวจหาความหนาแน่นโดยคลิกช่องทําเครื่องหมาย

เพิ่มโหนดที่เก็บข้อมูล
- หากต้องการเพิ่มโหนดปลายทางเอาต์พุต (ที่เก็บข้อมูล) ให้เลือกตัวเลือก Vision AI Warehouse ในส่วนตัวเชื่อมต่อของเมนูด้านข้าง
- คลิกตัวเชื่อมต่อ Vertex AI Warehouse เพื่อเปิดเมนู แล้วคลิกเชื่อมต่อคลัง
- ในเมนูเชื่อมต่อคลัง ให้เลือกสร้างคลังใหม่ ตั้งชื่อคลังสินค้าว่า queue-warehouse และปล่อยให้ระยะเวลา TTL เป็น 14 วัน
- คลิกปุ่มสร้างเพื่อเพิ่มคลังสินค้า
7. เชื่อมต่อเอาต์พุตกับตาราง BigQuery
เมื่อเพิ่มเครื่องมือเชื่อมต่อ BigQuery ลงในแอป Vertex AI Vision ระบบจะนำเข้าเอาต์พุตโมเดลแอปที่เชื่อมต่อทั้งหมดไปยังตารางเป้าหมาย
คุณจะสร้างตาราง BigQuery ของตัวเองและระบุตารางนั้นเมื่อเพิ่มตัวเชื่อมต่อ BigQuery ลงในแอป หรือจะปล่อยให้แพลตฟอร์มแอป Vertex AI Vision สร้างตารางโดยอัตโนมัติก็ได้
การสร้างตารางอัตโนมัติ
หากคุณอนุญาตให้แพลตฟอร์มแอป Vertex AI Vision สร้างตารางโดยอัตโนมัติ คุณจะระบุตัวเลือกนี้ได้เมื่อเพิ่มโหนดตัวเชื่อมต่อ BigQuery
เงื่อนไขของชุดข้อมูลและตารางต่อไปนี้จะมีผลหากคุณต้องการใช้การสร้างตารางอัตโนมัติ
- ชุดข้อมูล: ชื่อชุดข้อมูลที่สร้างขึ้นโดยอัตโนมัติคือ visionai_dataset
- ตาราง: ชื่อตารางที่สร้างขึ้นโดยอัตโนมัติคือ visionai_dataset.APPLICATION_ID
- การจัดการข้อผิดพลาด
- หากมีตารางที่ใช้ชื่อเดียวกันภายใต้ชุดข้อมูลเดียวกัน ระบบจะไม่สร้างตารางโดยอัตโนมัติ
- เปิดแท็บแอปพลิเคชันของแดชบอร์ด Vertex AI Vision ไปที่แท็บแอปพลิเคชัน
- เลือกดูแอปข้างชื่อแอปพลิเคชันจากรายการ
- ในหน้าเครื่องมือสร้างแอปพลิเคชัน ให้เลือก BigQuery จากส่วนเครื่องมือเชื่อมต่อ
- เว้นช่อง BigQuery path ว่างไว้

- ในจัดเก็บข้อมูลเมตาจาก: ให้เลือกเฉพาะ "ข้อมูลวิเคราะห์การเข้าพัก" และยกเลิกการเลือกสตรีม
กราฟแอปสุดท้ายควรมีลักษณะดังนี้

8. ทำให้แอปพร้อมใช้งาน
หลังจากสร้างแอปแบบครบวงจรที่มีคอมโพเนนต์ที่จำเป็นทั้งหมดแล้ว ขั้นตอนสุดท้ายในการใช้แอปคือการติดตั้งใช้งาน
- เปิดแท็บแอปพลิเคชันของแดชบอร์ด Vertex AI Vision ไปที่แท็บแอปพลิเคชัน
- เลือกดูแอปข้างแอป queue-app ในรายการ
- จากหน้า Studio ให้คลิกปุ่มติดตั้งใช้งาน
- ในกล่องโต้ตอบการยืนยันต่อไปนี้ ให้คลิกทำให้ใช้งานได้ การดำเนินการทำให้ใช้งานได้อาจใช้เวลาหลายนาทีจึงจะเสร็จสมบูรณ์ หลังจากที่การติดตั้งใช้งานเสร็จสิ้น เครื่องหมายถูกสีเขียวจะปรากฏข้างโหนด

9. ค้นหาเนื้อหาวิดีโอในคลังเก็บข้อมูล
หลังจากนำเข้าข้อมูลวิดีโอลงในแอปประมวลผลแล้ว คุณจะดูข้อมูลวิดีโอที่วิเคราะห์แล้ว และค้นหาข้อมูลตามข้อมูลวิเคราะห์การเข้าพักได้
- เปิดแท็บคลังสินค้าของแดชบอร์ด Vertex AI Vision ไปที่แท็บคลังสินค้า
- ค้นหาคลังสินค้าในคิวในรายการ แล้วคลิกดูชิ้นงาน
- ในส่วนจำนวนคน ให้ตั้งค่าต่ำสุดเป็น 1 และค่าสูงสุดเป็น 5
- หากต้องการกรองข้อมูลวิดีโอที่ประมวลผลแล้วซึ่งจัดเก็บไว้ในคลังสื่อของ Vertex AI Vision ให้คลิกค้นหา

มุมมองของข้อมูลวิดีโอที่จัดเก็บไว้ซึ่งตรงกับเกณฑ์การค้นหาในคอนโซล Google Cloud
10. ใส่คำอธิบายประกอบและวิเคราะห์เอาต์พุตโดยใช้ตาราง BigQuery
- ใน 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'
- ตอนนี้เราจะจับภาพเฟรมจากสตรีม 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')
- ดึงข้อมูลการประทับเวลาและคำอธิบายประกอบจากตาราง 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)
- ใส่คำอธิบายประกอบเฟรมโดยใช้โค้ดต่อไปนี้
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> </p>
'''))
except KeyboardInterrupt:
print('Stopping Live Monitoring')

- หยุดงานคำอธิบายประกอบโดยใช้ปุ่มหยุดในแถบเมนูของ Notebook

- คุณกลับไปดูแต่ละเฟรมได้โดยใช้โค้ดต่อไปนี้
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%')))

11. ขอแสดงความยินดี
ยินดีด้วย คุณทำแล็บเสร็จแล้ว
ล้างข้อมูล
โปรดลบโปรเจ็กต์ที่มีทรัพยากรหรือเก็บโปรเจ็กต์ไว้และลบทรัพยากรแต่ละรายการเพื่อหลีกเลี่ยงการเรียกเก็บเงินจากบัญชี Google Cloud สำหรับทรัพยากรที่ใช้ในบทแนะนำนี้
ลบโปรเจ็กต์
ลบทรัพยากรแต่ละรายการ
แหล่งข้อมูล
https://cloud.google.com/vision-ai/docs/overview
https://cloud.google.com/vision-ai/docs/occupancy-count-tutorial