1. Hedefler
Genel Bakış
Bu codelab'de, perakende video görüntülerini kullanarak sıra boyutunu izlemek için uçtan uca bir Vertex AI Vision uygulaması oluşturmaya odaklanılacaktır. Aşağıdaki bilgileri yakalamak için önceden eğitilmiş Specialized modeli Occupancy analytics'in yerleşik özelliklerini kullanacağız:
- Sırada bekleyen kişi sayısını hesaplayın.
- Tezgâhta hizmet alan kişi sayısını sayın.
Neler öğreneceksiniz?
- Vertex AI Vision'da uygulama oluşturma ve dağıtma
- Video dosyası kullanarak RTSP akışı oluşturma ve Jupyter not defterinden vaictl kullanarak akışı Vertex AI Vision'a aktarma
- Dolu/Boşluk Analizi modeli ve farklı özellikleri nasıl kullanılır?
- Vertex AI Vision'ın Media Warehouse'unda depolama alanınızdaki videoları arama
- Çıkışı BigQuery'ye bağlama, modelin JSON çıkışından analizler çıkarmak için SQL sorgusu yazma ve çıkışı kullanarak orijinal videoyu etiketleme ve ek açıklama ekleme
Maliyet:
Bu laboratuvarı Google Cloud'da çalıştırmanın toplam maliyeti yaklaşık 2 ABD dolarıdır.
2. Başlamadan Önce
Proje oluşturma ve API'leri etkinleştirme:
- Google Cloud Console'da, proje seçici sayfasında bir Google Cloud projesi oluşturun veya mevcut bir projeyi seçin. Not: Bu prosedürde oluşturduğunuz kaynakları saklamayı düşünmüyorsanız mevcut projeyi seçmek yerine yeni bir proje oluşturun. Bu adımları tamamladıktan sonra projenizi silerek projeyle ilişkili tüm kaynakları kaldırabilirsiniz. Proje seçiciye gitme
- Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını kontrol etmeyi öğrenin.
- Compute Engine, Vertex API, Notebook API ve Vision AI API'yi etkinleştirin. API'leri etkinleştirme
Hizmet hesabı oluşturun:
- Google Cloud Console'da Hizmet hesabı oluştur sayfasına gidin. Hizmet hesabı oluşturma sayfasına gidin
- Projenizi seçin.
- Hizmet hesabı adı alanına bir ad girin. Google Cloud Console, bu ada göre Hizmet hesabı kimliği alanını doldurur. Hizmet hesabı açıklaması alanına bir açıklama girin. Örneğin, hızlı başlangıç için hizmet hesabı.
- Oluştur ve devam et'i tıklayın.
- Projenize erişim izni vermek için hizmet hesabınıza aşağıdaki rolleri verin:
- Vision AI > Vision AI Editor
- Compute Engine > Compute Instance Admin (beta)
- BigQuery > BigQuery Yöneticisi'ni tıklayın.
Rol seçimi listesinde bir rol seçin. Ek roller için Başka rol ekle'yi tıklayın ve her ek rolü ekleyin.
- Devam'ı tıklayın.
- Hizmet hesabını oluşturmayı tamamlamak için Bitti'yi tıklayın. Tarayıcı pencerenizi kapatmayın. Bu ad sonraki adımda gereklidir.
3. Jupyter not defterini ayarlama
Doluluk Analizi'nde bir uygulama oluşturmadan önce, daha sonra uygulama tarafından kullanılabilecek bir akış kaydetmeniz gerekir.
Bu eğitimde, video barındıran bir Jupyter Notebook örneği oluşturacak ve bu akış video verilerini not defterinden göndereceksiniz. Kabuk komutlarını yürütmenin yanı sıra özel ön/son işleme kodunu tek bir yerde çalıştırma esnekliği sunduğu için Jupyter not defterini kullanıyoruz. Bu, hızlı denemeler için çok uygundur. Bu not defterini şu amaçlarla kullanırız:
- rtsp sunucusunu arka plan işlemi olarak çalıştırma
- vaictl komutunu arka plan işlemi olarak çalıştırma
- Dolu olma durumu analizleri çıkışını analiz etmek için sorgu ve işleme kodu çalıştırma
Jupyter not defteri oluşturma
Jupyter Notebook örneğinden video göndermenin ilk adımı, önceki adımda oluşturduğumuz hizmet hesabımızla not defterini oluşturmaktır.
- Konsolda Vertex AI sayfasına gidin. Vertex AI Workbench'e gitme
- Kullanıcı tarafından yönetilen not defterleri'ni tıklayın.

- New Notebook > Tensorflow Enterprise 2.6 (with LTS) > Without GPUs'u (Yeni Not Defteri > Tensorflow Enterprise 2.6 (LTS özellikli) > GPU'suz) tıklayın.

- Jupyter not defterinin adını girin. Daha fazla bilgi için Kaynak adlandırma kuralı başlıklı makaleyi inceleyin.

- GELİŞMİŞ SEÇENEKLER'i tıklayın.
- Aşağı kaydırarak İzin Bölümleri'ne gidin.
- Varsayılan Compute Engine hizmet hesabını kullan seçeneğinin işaretini kaldırın.
- Önceki adımda oluşturulan hizmet hesabı e-posta adresini ekleyin. Oluştur'u tıklayın.

- Örnek oluşturulduktan sonra JUPYTERLAB'İ AÇ'ı tıklayın.
4. Video yayınlamak için not defteri ayarlama
Doluluk Analizi'nde bir uygulama oluşturmadan önce, daha sonra uygulama tarafından kullanılabilecek bir akış kaydetmeniz gerekir.
Bu eğitimde, bir videoyu barındırmak için Jupyter Notebook örneğimizi kullanacağız ve bu akış video verilerini Notebook terminalinden göndereceksiniz.
vaictl komut satırı aracını indirin
- Açılan JupyterLab örneğinde, başlatıcıdan bir not defteri açın.

- Not defteri hücresinde aşağıdaki komutu kullanarak Vertex AI Vision (vaictl) komut satırı aracını, rtsp sunucusu komut satırı aracını ve open-cv aracını indirin:
!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. Akış için video dosyası alma
Not defteri ortamınızı gerekli komut satırı araçlarıyla kurduktan sonra örnek bir video dosyasını kopyalayabilir ve ardından video verilerini doluluk analizi uygulamanıza aktarmak için vaictl'yi kullanabilirsiniz.
Yeni bir akış kaydetme
- Vertex AI Vision'ın sol panelinde akışlar sekmesini tıklayın.
- En üstteki Kaydol düğmesini tıklayın

- Akış adı bölümüne "queue-stream" yazın.
- Bölge olarak, önceki adımda not defteri oluşturma sırasında seçilen bölgeyi seçin.
- Kaydol'u tıklayın.
VM'nize örnek video kopyalama
- Not defterinizde aşağıdaki wget komutuyla örnek bir videoyu kopyalayın.
!wget -q https://github.com/vagrantism/interesting-datasets/raw/main/video/collective_activity/seq25_h264.mp4
Sanal makineden video akışı yapma ve akışınıza veri aktarma
- Bu yerel video dosyasını uygulama giriş akışına göndermek için not defteri hücrenizde aşağıdaki komutu kullanın. Aşağıdaki değişken değişikliklerini yapmanız gerekir:
- PROJECT_ID: Google Cloud proje kimliğiniz.
- LOCATION: Yer kodunuz. Örneğin, us-central1. Daha fazla bilgi için Bulut konumları konusuna bakın.
- LOCAL_FILE: Yerel bir video dosyasının dosya adı. Örneğin,
seq25_h264.mp4.
PROJECT_ID='<Your Google Cloud project ID>'
LOCATION='<Your stream location>'
LOCAL_FILE='seq25_h264.mp4'
STREAM_NAME='queue-stream'
- Video dosyasını RTSP protokolüyle aktardığımız bir rtsp-simple-server başlatın
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)
- RTSP akışında videoyu döngüye almak için ffmpeg komut satırı aracını kullanma
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)
- Video akışını rtsp sunucusu URI'sinden önceki adımda oluşturulan Vertex AI Vision akışımız "queue-stream"e aktarmak için vaictl komut satırı aracını kullanın.
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 ingest işleminin başlatılması ile videonun kontrol panelinde görünmesi arasında yaklaşık 100 saniye geçebilir.
Akış alımı kullanıma sunulduktan sonra, kuyruk akışı akışını seçerek Vertex AI Vision kontrol panelinin Akışlar sekmesinde video feed'ini görebilirsiniz.

6. Uygulama oluşturma
İlk adım, verilerinizi işleyen bir uygulama oluşturmaktır. Uygulama, aşağıdakileri birbirine bağlayan otomatik bir ardışık düzen olarak düşünülebilir:
- Veri kullanımı: Video feed'i bir akışa alınır.
- Veri analizi: Veri alımından sonra bir yapay zeka(bilgisayarla görme) modeli eklenebilir.
- Veri depolama: Video feed'inin iki sürümü (orijinal yayın ve yapay zeka modeli tarafından işlenen yayın) bir medya deposunda saklanabilir.
Google Cloud Console'da bir uygulama grafik olarak gösterilir.
Boş bir uygulama oluşturma
Uygulama grafiğini doldurmadan önce boş bir uygulama oluşturmanız gerekir.
Google Cloud Console'da bir uygulama oluşturun.
- Google Cloud Console'a gidin.
- Vertex AI Vision kontrol panelinin Uygulamalar sekmesini açın. Uygulamalar sekmesine gidin
- Oluştur düğmesini tıklayın.

- Uygulama adı olarak "queue-app" girin ve bölgenizi seçin.
- Oluştur'u tıklayın.
Uygulama bileşeni düğümleri ekleme
Boş uygulamayı oluşturduktan sonra uygulama grafiğine üç düğüm ekleyebilirsiniz:
- Alım düğümü: Not defterinde oluşturduğunuz bir RTSP video sunucusundan gönderilen verileri alan akış kaynağı.
- İşleme düğümü: Alınan veriler üzerinde işlem yapan doluluk analizi modeli.
- Depolama düğümü: İşlenmiş videoları depolayan ve meta veri deposu olarak kullanılan medya deposu. Meta veri depoları, alınan video verileriyle ilgili analiz bilgilerini ve yapay zeka modelleri tarafından çıkarılan bilgileri içerir.
Konsolda uygulamanıza bileşen düğümleri ekleyin.
- Vertex AI Vision kontrol panelinin Uygulamalar sekmesini açın. Uygulamalar sekmesine gidin
Bu işlem sizi işleme ardışık düzeninin grafik görselleştirmesine yönlendirir.
Veri kullanımı düğümü ekleme
- Giriş akışı düğümü eklemek için yan menünün Bağlayıcılar bölümünde Akışlar seçeneğini belirleyin.
- Açılan Yayın menüsünün Kaynak bölümünde Yayın ekle'yi seçin.
- Akış ekle menüsünde queue-stream'i seçin.
- Akışı uygulama grafiğine eklemek için Akış ekle'yi tıklayın.
Veri işleme düğümü ekleme
- Dolu olma sayısı modeli düğümünü eklemek için yan menünün Özel modeller bölümünde Dolu olma analizi seçeneğini belirleyin.
- Varsayılan seçimleri Kişiler olarak bırakın. Zaten seçilmişse Araçlar'ın işaretini kaldırın.

- Gelişmiş Seçenekler bölümünde Etkin Bölgeler/Çizgiler Oluştur 'u
tıklayın. - Poligon aracını kullanarak etkin bölgeleri çizin. Bu bölgelerdeki kişi sayısı sayılır. Bölgeyi uygun şekilde etiketleyin

- En üstteki geri okunu tıklayın.

- Onay kutusunu tıklayarak bekleme süresiyle ilgili ayarlar ekleyip yoğunluğu tespit edin.

Veri depolama düğümü ekleme
- Çıkış hedefi (depolama) düğümünü eklemek için yan menünün Bağlayıcılar bölümünde VIsion AI Warehouse seçeneğini belirleyin.
- Menüsünü açmak için Vertex AI Warehouse bağlayıcısını, ardından Depoyu bağla'yı tıklayın.
- Depo bağla menüsünde Yeni depo oluştur'u seçin. Depoyu queue-warehouse olarak adlandırın ve TTL süresini 14 gün olarak bırakın.
- Depoyu eklemek için Oluştur düğmesini tıklayın.
7. Çıkışı BigQuery tablosuna bağlama
Vertex AI Vision uygulamanıza bir BigQuery bağlayıcısı eklediğinizde, bağlı uygulama modeli çıkışlarının tümü hedef tabloya aktarılır.
Kendi BigQuery tablonuzu oluşturup uygulamaya BigQuery bağlayıcısı eklerken bu tabloyu belirtebilir veya tablonun Vertex AI Vision uygulama platformu tarafından otomatik olarak oluşturulmasına izin verebilirsiniz.
Otomatik tablo oluşturma
Vertex AI Vision uygulama platformunun tabloyu otomatik olarak oluşturmasına izin verirseniz BigQuery bağlayıcı düğümünü eklerken bu seçeneği belirtebilirsiniz.
Otomatik tablo oluşturmayı kullanmak istiyorsanız aşağıdaki veri kümesi ve tablo koşulları geçerlidir:
- Veri kümesi: Otomatik olarak oluşturulan veri kümesi adı visionai_dataset'tir.
- Tablo: Otomatik olarak oluşturulan tablo adı visionai_dataset.APPLICATION_ID'dir.
- Hata işleme:
- Aynı veri kümesi altında aynı ada sahip bir tablo varsa otomatik oluşturma işlemi gerçekleşmez.
- Vertex AI Vision kontrol panelinin Uygulamalar sekmesini açın. Uygulamalar sekmesine gidin
- Listeden uygulamanızın adının yanındaki Uygulamayı görüntüle'yi seçin.
- Uygulama oluşturucu sayfasında Bağlayıcılar bölümünden BigQuery'yi seçin.
- BigQuery yolu alanını boş bırakın.

- Şu kaynaktan alınan mağaza meta verileri: bölümünde yalnızca "Doluluk analizi" seçeneğini belirleyin ve akışların işaretini kaldırın.
Son uygulama grafiği aşağıdaki gibi görünmelidir:

8. Uygulamanızı kullanıma sunma
Uçtan uca uygulamanızı gerekli tüm bileşenlerle oluşturduktan sonra, uygulamayı kullanmak için yapmanız gereken son adım dağıtmaktır.
- Vertex AI Vision kontrol panelinin Uygulamalar sekmesini açın. Uygulamalar sekmesine gidin
- Listede queue-app uygulamasının yanındaki Uygulamayı görüntüle'yi seçin.
- Studio sayfasında Dağıt düğmesini tıklayın.
- Açılan onay iletişim kutusunda Dağıt'ı tıklayın. Dağıtım işleminin tamamlanması birkaç dakika sürebilir. Dağıtım tamamlandıktan sonra düğümlerin yanında yeşil onay işaretleri görünür.

9. Depolama deposundaki video içeriklerini arama
Video verilerini işleme uygulamanıza aktardıktan sonra analiz edilen video verilerini görüntüleyebilir ve doluluk analizi bilgilerine göre verilerde arama yapabilirsiniz.
- Vertex AI Vision kontrol panelinin Warehouses (Depolar) sekmesini açın. Depolar sekmesine gidin
- Listede sıraya alma deposunu bulun ve Öğeleri görüntüle'yi tıklayın.
- Kişi sayısı bölümünde Min değerini 1, Maks değerini 5 olarak ayarlayın.
- Vertex AI Vision'ın Media Warehouse'unda depolanan işlenmiş video verilerini filtrelemek için Ara'yı tıklayın.

Google Cloud Console'da arama ölçütleriyle eşleşen depolanmış video verilerinin görünümü.
10. BigQuery tablosunu kullanarak çıkışı açıklama ve analiz etme
- Not defterinde, hücredeki aşağıdaki değişkenleri başlatın.
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'
- Şimdi aşağıdaki kodu kullanarak rtsp akışındaki kareleri yakalayacağız:
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')
- Veri zaman damgasını ve ek açıklama bilgilerini BigQuery tablosundan çekin ve yakalanan kare görüntülerini depolamak için bir dizin oluşturun:
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)
- Aşağıdaki kodu kullanarak karelere açıklama ekleyin:
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')

- Not defteri menü çubuğundaki Durdur düğmesini kullanarak ek açıklama görevini durdurun.

- Aşağıdaki kodu kullanarak tek tek kareleri yeniden ziyaret edebilirsiniz:
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. Tebrikler
Tebrikler, laboratuvarı tamamladınız.
Temizleme
Bu eğitimde kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini önlemek amacıyla kaynakları içeren projeyi silin veya projeyi koruyup tek tek kaynakları silin.
Projeyi silme
Tek tek kaynakları silme
Kaynaklar
https://cloud.google.com/vision-ai/docs/overview
https://cloud.google.com/vision-ai/docs/occupancy-count-tutorial