1. Tujuan
Ringkasan
Codelab ini akan berfokus pada pembuatan aplikasi Vertex AI Vision secara menyeluruh untuk memantau ukuran antrean menggunakan rekaman video retail. Kita akan menggunakan fitur bawaan model Khusus yang telah dilatih sebelumnya, yaitu Analisis hunian, untuk merekam hal-hal berikut:
- Hitung jumlah orang yang berdiri dalam antrean.
- Hitung jumlah orang yang dilayani di konter.
Yang akan Anda pelajari
- Cara membuat aplikasi di Vertex AI Vision dan men-deploy-nya
- Cara menyiapkan streaming RTSP menggunakan file video dan menyerap streaming ke Vertex AI Vision menggunakan vaictl dari Notebook Jupyter.
- Cara menggunakan model Analisis Hunian dan berbagai fiturnya.
- Cara menelusuri video di Media Warehouse Vertex AI Vision.
- Cara menghubungkan output ke BigQuery, menulis kueri SQL untuk mengekstrak insight dari output json model, dan menggunakan output untuk memberi label dan anotasi pada video asli.
Biaya:
Total biaya untuk menjalankan lab ini di Google Cloud adalah sekitar $2.
2. Sebelum Memulai
Buat project dan aktifkan API:
- Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud. Catatan: Jika Anda tidak berencana untuk menyimpan resource yang Anda buat dalam prosedur ini, buat project baru alih-alih memilih project yang ada. Setelah menyelesaikan langkah-langkah ini, Anda dapat menghapus project, sehingga semua resource yang terkait dengan project tersebut akan dihapus. Buka pemilih project
- Pastikan penagihan diaktifkan untuk project Cloud Anda. Pelajari cara memeriksa apakah penagihan telah diaktifkan pada suatu project.
- Aktifkan Compute Engine API, Vertex API, Notebook API, dan Vision AI API. Aktifkan API
Buat akun layanan:
- Di konsol Google Cloud, buka halaman Buat akun layanan. Buka Buat akun layanan
- Pilih project Anda.
- Di kolom Nama akun layanan, masukkan nama. Konsol Google Cloud akan mengisi kolom ID akun layanan berdasarkan nama ini. Di kolom Deskripsi akun layanan, masukkan deskripsi. Misalnya, Akun layanan untuk panduan memulai cepat.
- Klik Buat dan lanjutkan.
- Untuk memberikan akses ke project Anda, berikan peran berikut kepada akun layanan Anda:
- Vision AI > Vision AI Editor
- Compute Engine > Compute Instance Admin (beta)
- BigQuery > BigQuery Admin .
Di daftar Select a role, pilih peran. Untuk peran tambahan, klik Tambahkan peran lain, lalu tambahkan setiap peran tambahan.
- Klik Lanjutkan.
- Klik Selesai untuk menyelesaikan pembuatan akun layanan. Jangan tutup jendela browser Anda. Anda akan menggunakannya pada langkah berikutnya.
3. Menyiapkan Jupyter Notebook
Sebelum membuat Aplikasi di Analisis Hunian, Anda harus mendaftarkan streaming yang dapat digunakan nanti oleh Aplikasi.
Dalam tutorial ini, Anda akan membuat instance Jupyter Notebook yang menghosting video, dan Anda akan mengirim data video streaming tersebut dari notebook. Kami menggunakan notebook jupyter karena menawarkan fleksibilitas untuk menjalankan perintah shell serta menjalankan kode pra/pasca-pemrosesan kustom di satu tempat yang sangat baik untuk eksperimen cepat. Kita akan menggunakan notebook ini untuk:
- Menjalankan server rtsp sebagai proses latar belakang
- Menjalankan perintah vaictl sebagai proses latar belakang
- Menjalankan kueri dan kode pemrosesan untuk menganalisis output analisis hunian
Membuat Notebook Jupyter
Langkah pertama dalam mengirim video dari instance Jupyter Notebook adalah membuat notebook dengan akun layanan yang dibuat pada langkah sebelumnya.
- Di konsol, buka halaman Vertex AI. Buka Vertex AI Workbench
- Klik Notebook yang Dikelola Pengguna

- Klik New Notebook > Tensorflow Enterprise 2.6 (with LTS) > Without GPUs

- Masukkan nama untuk notebook jupyter. Untuk mengetahui informasi selengkapnya, lihat Konvensi penamaan resource.

- Klik OPSI LANJUTAN
- Scroll ke bawah ke Bagian Izin
- Hapus centang pada opsi Gunakan akun layanan default Compute Engine
- Tambahkan email Akun layanan yang dibuat pada langkah sebelumnya. Lalu, klik Buat.

- Setelah instance dibuat, klik OPEN JUPYTERLAB.
4. Menyiapkan Notebook untuk melakukan streaming video
Sebelum membuat Aplikasi di Analisis Hunian, Anda harus mendaftarkan streaming yang dapat digunakan nanti oleh Aplikasi.
Dalam tutorial ini, kita akan menggunakan instance Jupyter Notebook untuk menghosting video, dan Anda akan mengirimkan data video streaming tersebut dari terminal Notebook.
Download alat command line vaictl
- Di instance JupyterLab yang terbuka, Buka Notebook dari peluncur.

- Download alat command line Vertex AI Vision (vaictl), alat command line server rtsp, alat open-cv menggunakan perintah berikut di sel 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. Menyerap file video untuk streaming
Setelah menyiapkan lingkungan notebook dengan alat command line yang diperlukan, Anda dapat menyalin file video sampel, lalu menggunakan vaictl untuk melakukan streaming data video ke aplikasi analisis hunian Anda.
Mendaftarkan streaming baru
- Klik tab aliran di panel kiri Vertex AI Vision.
- Klik Tombol Daftar di bagian atas

- Di Nama aliran data, masukkan 'queue-stream'
- Di region, pilih region yang sama dengan yang dipilih saat pembuatan Notebook pada langkah sebelumnya.
- Klik Daftar.
Menyalin video contoh ke VM Anda
- Di notebook Anda, salin video contoh dengan perintah wget berikut.
!wget -q https://github.com/vagrantism/interesting-datasets/raw/main/video/collective_activity/seq25_h264.mp4
Streaming video dari VM dan menyerap data ke dalam streaming Anda
- Untuk mengirim file video lokal ini ke aliran input aplikasi, gunakan perintah berikut di sel notebook Anda. Anda harus melakukan penggantian variabel berikut:
- PROJECT_ID: Project ID Google Cloud Anda.
- LOCATION: ID lokasi Anda. Misalnya, us-central1. Untuk mengetahui informasi selengkapnya, lihat Lokasi cloud.
- LOCAL_FILE: Nama file video lokal. Misalnya,
seq25_h264.mp4.
PROJECT_ID='<Your Google Cloud project ID>'
LOCATION='<Your stream location>'
LOCAL_FILE='seq25_h264.mp4'
STREAM_NAME='queue-stream'
- Mulai rtsp-simple-server tempat kita melakukan streaming file video dengan protokol 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)
- Menggunakan alat command line ffmpeg untuk memutar video secara berulang dalam streaming 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)
- Gunakan alat command line vaictl untuk melakukan streaming video dari URI server rtsp ke streaming Vertex AI Vision 'queue-stream' yang dibuat pada langkah sebelumnya.
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)
Mungkin diperlukan waktu ~100 detik antara memulai operasi penyerapan vaictl dan video muncul di dasbor.
Setelah penyerapan stream tersedia, Anda dapat melihat feed video di tab Streams di dasbor Vertex AI Vision dengan memilih stream antrean-stream.

6. Membuat aplikasi
Langkah pertama adalah membuat aplikasi yang memproses data Anda. Aplikasi dapat dianggap sebagai pipeline otomatis yang menghubungkan hal berikut:
- Penyerapan data: Feed video diserap ke dalam aliran.
- Analisis data: Model AI(Computer Vision) dapat ditambahkan setelah penyerapan.
- Penyimpanan data: Dua versi feed video (streaming asli dan streaming yang diproses oleh model AI) dapat disimpan di gudang media.
Di konsol Google Cloud, aplikasi ditampilkan sebagai grafik.
Membuat aplikasi kosong
Sebelum dapat mengisi grafik aplikasi, Anda harus membuat aplikasi kosong terlebih dahulu.
Buat aplikasi di konsol Google Cloud.
- Buka konsol Google Cloud.
- Buka tab Applications di dasbor Vertex AI Vision. Buka tab Aplikasi
- Klik tombol Create.

- Masukkan ‘queue-app' sebagai nama aplikasi dan pilih wilayah Anda.
- Klik Buat.
Menambahkan node komponen aplikasi
Setelah membuat aplikasi kosong, Anda dapat menambahkan tiga node ke grafik aplikasi:
- Node penyerapan: Resource streaming yang menyerap data yang dikirim dari server video rtsp yang Anda buat di notebook.
- Node pemrosesan: Model analisis hunian yang bertindak berdasarkan data yang di-ingest.
- Node penyimpanan: Gudang media yang menyimpan video yang diproses, dan berfungsi sebagai penyimpanan metadata. Penyimpanan metadata mencakup informasi analisis tentang data video yang di-ingest, dan informasi yang disimpulkan oleh model AI.
Tambahkan node komponen ke aplikasi Anda di konsol.
- Buka tab Applications di dasbor Vertex AI Vision. Buka tab Aplikasi
Tindakan ini akan membawa Anda ke visualisasi grafik pipeline pemrosesan.
Menambahkan node penyerapan data
- Untuk menambahkan node input stream, pilih opsi Streams di bagian Connectors pada menu samping.
- Di bagian Sumber pada menu Aliran yang terbuka, pilih Tambahkan aliran.
- Di menu Add streams, pilih queue-stream.
- Untuk menambahkan aliran ke grafik aplikasi, klik Tambahkan aliran.
Menambahkan node pemrosesan data
- Untuk menambahkan node model jumlah hunian, pilih opsi analisis hunian di bagian Model khusus pada menu samping.
- Biarkan pilihan default Orang. Hapus centang Kendaraan jika sudah dicentang.

- Di bagian Advanced Options, Klik Create Active Zones/Lines

- Gambarkan zona aktif menggunakan alat Poligon untuk menghitung orang di zona tersebut. Beri label zona yang sesuai

- Klik Panah Kembali di bagian atas.

- Tambahkan setelan untuk waktu tunggu guna mendeteksi kemacetan dengan mengklik Kotak Centang.

Menambahkan node penyimpanan data
- Untuk menambahkan node tujuan output (penyimpanan), pilih opsi VIsion AI Warehouse di bagian Connectors pada menu samping.
- Klik Konektor Vertex AI Warehouse untuk membuka menunya, lalu klik Hubungkan warehouse.
- Di menu Connect warehouse, pilih Create new warehouse. Beri nama antrean gudang queue-warehouse, dan biarkan durasi TTL 14 hari.
- Klik tombol Buat untuk menambahkan gudang.
7. Menghubungkan Output ke Tabel BigQuery
Saat Anda menambahkan konektor BigQuery ke aplikasi Vertex AI Vision, semua output model aplikasi yang terhubung akan di-ingest ke tabel target.
Anda dapat membuat tabel BigQuery sendiri dan menentukan tabel tersebut saat menambahkan konektor BigQuery ke aplikasi, atau membiarkan platform aplikasi Vertex AI Vision membuat tabel secara otomatis.
Pembuatan tabel otomatis
Jika Anda mengizinkan platform aplikasi Vertex AI Vision membuat tabel secara otomatis, Anda dapat menentukan opsi ini saat menambahkan node konektor BigQuery.
Kondisi set data dan tabel berikut berlaku jika Anda ingin menggunakan pembuatan tabel otomatis:
- Set data: Nama set data yang dibuat secara otomatis adalah visionai_dataset.
- Tabel: Nama tabel yang dibuat secara otomatis adalah visionai_dataset.APPLICATION_ID.
- Penanganan error:
- Jika tabel dengan nama yang sama di bawah set data yang sama sudah ada, tidak ada pembuatan otomatis.
- Buka tab Applications di dasbor Vertex AI Vision. Buka tab Aplikasi
- Pilih Lihat aplikasi di samping nama aplikasi Anda dari daftar.
- Di halaman pembuat aplikasi, pilih BigQuery dari bagian Connectors.
- Biarkan kolom BigQuery path kosong.

- Di bagian Simpan metadata dari:, pilih hanya 'Analytics hunian' dan hapus centang pada aliran.
Grafik aplikasi akhir akan terlihat seperti ini:

8. Men-deploy aplikasi Anda untuk digunakan
Setelah Anda membuat aplikasi end-to-end dengan semua komponen yang diperlukan, langkah terakhir untuk menggunakan aplikasi adalah men-deploy-nya.
- Buka tab Applications di dasbor Vertex AI Vision. Buka tab Aplikasi
- Pilih Lihat aplikasi di samping aplikasi queue-app dalam daftar.
- Dari halaman Studio, klik tombol Deploy.
- Pada dialog konfirmasi berikut, klik Deploy. Operasi deployment mungkin memerlukan waktu beberapa menit hingga selesai. Setelah deployment selesai, tanda centang hijau akan muncul di samping node.

9. Menelusuri konten video di data warehouse penyimpanan
Setelah menyerap data video ke dalam aplikasi pemrosesan, Anda dapat melihat data video yang dianalisis, dan menelusuri data berdasarkan informasi analisis hunian.
- Buka tab Warehouses di dasbor Vertex AI Vision. Buka tab Gudang
- Temukan gudang antrean di daftar, lalu klik Lihat aset.
- Di bagian Jumlah orang, tetapkan nilai Min ke 1, dan nilai Maks ke 5.
- Untuk memfilter data video yang diproses dan disimpan di Media Warehouse Vertex AI Vision, klik Search.

Tampilan data video tersimpan yang cocok dengan kriteria penelusuran di Konsol Google Cloud.
10. Memberi Anotasi dan Menganalisis Output menggunakan Tabel BigQuery
- Di Notebook, lakukan inisialisasi variabel berikut di sel.
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'
- Sekarang kita akan merekam frame dari streaming rtsp menggunakan kode berikut:
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')
- Tarik stempel waktu data dan informasi anotasi dari tabel BigQuery, lalu buat direktori untuk menyimpan gambar frame yang diambil:
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)
- Anotasikan frame menggunakan kode berikut:
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')

- Hentikan tugas anotasi menggunakan tombol Hentikan di panel menu notebook

- Anda dapat melihat kembali frame satu per satu menggunakan kode berikut:
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. Selamat
Selamat, Anda telah menyelesaikan lab ini.
Pembersihan
Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.
Menghapus project
Menghapus resource satu per satu
Referensi
https://cloud.google.com/vision-ai/docs/overview
https://cloud.google.com/vision-ai/docs/occupancy-count-tutorial