1. Hedefler
Genel Bakış
Bu kod laboratuvarında, perakende video görüntülerini kullanarak sıra boyutunu izlemek için uçtan uca bir Vertex AI Vision uygulaması oluşturmaya odaklanacağız. Aşağıdakileri yakalamak için önceden eğitilmiş özel model doluluk analizi yerleşik özelliklerini kullanacağız:
- Sırada bekleyen kişileri sayın.
- Tezgahta servis 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 Notebook'tan vaictl kullanarak akışı Vertex AI Vision'a besleme.
- Doluluk Analizi modelini ve farklı özelliklerini kullanma.
- Depolama alanınızdaki videoları Vertex AI Vision'un Medya Deposu'nda arama
- Çıktıyı BigQuery'ye bağlama, modelin JSON çıkışından analizleri ayıklamak için SQL sorgusu yazma ve orijinal videoyu etiketlemek ve not eklemek için çıkışı kullanma.
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şturun ve API'leri etkinleştirin:
- Google Cloud konsolunun proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun. Not: Bu prosedürde oluşturduğunuz kaynakları tutmayı düşünmüyorsanız mevcut bir projeyi seçmek yerine bir proje oluşturun. Bu adımları tamamladıktan sonra projenizi silerek projeyle ilişkili tüm kaynakları kaldırabilirsiniz. Proje seçiciye git
- Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını nasıl kontrol edeceğinizi öğrenin.
- Compute Engine, Vertex API, Notebook API ve Vision AI API'yi etkinleştirin. API'leri etkinleştirme
Bir 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, Hizmet hesabı kimliği alanını bu ada göre 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 Düzenleyici
- Compute Engine > Compute Örnek Yöneticisi (beta)
- BigQuery > BigQuery Yöneticisi'ne gidin.
Rol seçin listesinde bir rol seçin. Başka roller için Başka rol ekle'yi tıklayın ve her rolü ekleyin.
- Devam'ı tıklayın.
- Hizmet hesabını oluşturma işlemini tamamlamak için Bitti'yi tıklayın. Tarayıcı pencerenizi kapatmayın. Bu adı sonraki adımda kullanacaksınız.
3. Jupyter Not Defteri'ni ayarlama
Doluluk Analizleri'nde uygulama oluşturmadan önce, uygulama tarafından daha sonra kullanılabilecek bir akış kaydetmeniz gerekir.
Bu eğitimde, video barındıran bir Jupyter Notebook örneği oluşturur ve bu akıştaki video verilerini not defterinden gönderirsiniz. Kabuk komutlarını yürütme ve özel ön/son işleme kodunu tek bir yerde çalıştırma esnekliği sunduğu için jupyter not defteri kullanıyoruz. Bu da hızlı denemeler yapmak için çok uygun. Bu not defterini şu amaçlarla kullanacağız:
- rtsp sunucusunu arka plan işlemi olarak çalıştırma
- vaictl komutunu arka plan işlemi olarak çalıştırma
- Doluluk analizi çıktısı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şturulan hizmet hesabımızla not defterini oluşturmaktır.
- Konsolda Vertex AI sayfasına gidin. Vertex AI Workbench'e gidin
- Kullanıcı Tarafından Yönetilen Not Defterleri'ni tıklayın.
- Yeni Not Defteri > Tensorflow Enterprise 2.6 (LTS ile) > GPU'suz'u 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.
- İzinler Bölümleri'ne gidin.
- Compute Engine varsayılan hizmet hesabını kullan seçeneğinin işaretini kaldırın.
- Önceki adımda oluşturulan hizmet hesabı e-posta adresini ekleyin. Ardından Oluştur'u tıklayın.
- Örnek oluşturulduktan sonra JUPYTERLAB'İ AÇ'ı tıklayın.
4. Video yayınlamak için not defteri oluşturma
Doluluk Analizleri'nde uygulama oluşturmadan önce, uygulama tarafından daha sonra kullanılabilecek bir akış kaydetmeniz gerekir.
Bu eğitimde, bir videoyu barındırmak için Jupyter Notebook örneğimizi kullanacağız. Ardından, 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ı besleme
Not defteri ortamınızı gerekli komut satırı araçlarıyla ayarladıktan sonra bir örnek video dosyasını kopyalayıp video verilerini doluluk analizi uygulamanıza aktarmak için vaictl'i kullanabilirsiniz.
Yeni canlı yayın kaydetme
- Vertex AI Vision'un sol panelinde akışlar sekmesini tıklayın.
- En üstteki Kaydol düğmesini tıklayın
- Akış adı alanına "queue-stream" yazın.
- Bölgede, önceki adımda not defteri oluşturma işlemi sırasında seçilen aynı bölgeyi seçin.
- Kaydol'u tıklayın.
Sanal makinenize örnek bir video kopyalama
- Not defterinizde, aşağıdaki wget komutuyla örnek bir video kopyalayın.
!wget -q https://github.com/vagrantism/interesting-datasets/raw/main/video/collective_activity/seq25_h264.mp4
VM'den video aktarma ve yayınınıza veri besleme
- 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: Konum kimliğiniz. Örneğin, us-central1. Daha fazla bilgi için Cloud konumları konusuna bakın.
- LOCAL_FILE: Yerel bir video dosyasının 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 yayınladığı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)
- Videoyu rtsp akışında 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)
- Videoyu rtsp sunucu URI'sinden önceki adımda oluşturulan Vertex AI Vision akışımıza "queue-stream" yayınlamak 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 besleme işleminin başlatılması ile videonun kontrol panelinde görünmesi yaklaşık 100 saniye sürebilir.
Akış beslemesi kullanılabilir hale geldikten sonra, sıraya ekleme akışını seçerek video feed'ini Vertex AI Vision kontrol panelinin Akışlar sekmesinde görebilirsiniz.
6. Uygulama oluşturma
İlk adım, verilerinizi işleyen bir uygulama oluşturmaktır. Uygulamalar, aşağıdakileri birbirine bağlayan otomatik bir ardışık düzen olarak düşünülebilir:
- Veri besleme: Video feed'i bir akışa beslenir.
- Veri analizi: Beslemeden sonra bir yapay zeka(bilgisayar görüşü) modeli eklenebilir.
- Veri depolama: Video feed'inin iki sürümü (orijinal akış ve yapay zeka modeli tarafından işlenen akış) bir medya deposunda depolanabilir.
Google Cloud konsolunda uygulamalar bir grafik olarak gösterilir.
Boş uygulama oluşturma
Uygulama grafiğini doldurmadan önce ö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" yazın 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:
- Besin kaynağı düğümü: Not defterinde oluşturduğunuz bir rtsp video sunucusundan gönderilen verileri besleyen akış kaynağı.
- İşleme düğümü: Beslenen veriler üzerinde işlem yapan doluluk analizi modelidir.
- Depolama düğümü: İşlenen videoları depolayan ve meta veri deposu olarak hizmet veren medya ambarı. Meta veri depoları, beslenen 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 besleme 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çin.
- 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ışları uygulama grafiğine eklemek için Akış ekle'yi tıklayın.
Veri işleme düğümü ekleme
- Doluluk sayısı modeli düğümünü eklemek için yan menünün Özel modeller bölümünde doluluk analizi seçeneğini belirleyin.
- Varsayılan seçimleri Kişiler olarak bırakın. Seçiliyse Araçlar'ın işaretini kaldırın.
- Advanced Options (Gelişmiş Seçenekler) bölümünde Create Active Zones/Lines (Etkin Alt Bölge/Satır Oluştur) seçeneğini tıklayın.
- Poligon aracını kullanarak etkin bölgeleri çizerek bu bölgelerdeki kişileri sayın. Alt bölgeyi uygun şekilde etiketleyin
- Üstteki geri okunu tıklayın.
- Onay kutusunu tıklayarak tıklama süresine ilişkin ayarları ekleyerek tıklama sıklığını algılayın.
Veri depolama düğümü ekleme
- Çıkış hedefi (depolama) düğümünü eklemek için yan menünün Bağlantılar bölümünde VIsion AI Warehouse seçeneğini belirleyin.
- Vertex AI Depo Bağlayıcısı'nı tıklayarak menüsünü açın, Depoyu bağla'yı tıklayın.
- Depo bağla menüsünde Yeni depo oluştur'u seçin. Depoya sıra depolama alanı adını verin 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ı tüm uygulama modeli çıkışları hedef tabloya alınır.
Kendi BigQuery tablonuzu oluşturup uygulamaya BigQuery bağlayıcısı eklerken bu tabloyu belirtebilir veya Vertex AI Vision uygulama platformunun tabloyu otomatik olarak oluşturması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şturma özelliğini 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.
- 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.
- Meta verileri şuradan al: bölümünde yalnızca "dolgu oranı Analytics"'i seçin ve akışların işaretini kaldırın.
Nihai uygulama grafiği şu şekilde görünmelidir:
8. Uygulamanızı kullanıma sunma
Uçtan uca uygulamanızı gerekli tüm bileşenlerle derledikten sonra, uygulamayı kullanmanın son adımı uygulamayı dağıtmaktır.
- Vertex AI Vision kontrol panelinin Uygulamalar sekmesini açın. Uygulamalar sekmesine gidin
- Listede sıradaki uygulama uygulamasının yanında bulunan Uygulamayı görüntüle'yi seçin.
- Studio sayfasında Dağıt düğmesini tıklayın.
- Aşağıdaki onay iletişim kutusunda Dağıt'ı tıklayın. Dağıtma 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 deposunda video içeriği arama
Video verilerini işleme uygulamanıza aktardıktan sonra, analiz edilen video verilerini görüntüleyebilir ve verileri doluluk analizi bilgilerine göre arayabilirsiniz.
- Vertex AI Vision kontrol panelinin Depolar sekmesini açın. Depo sekmesine gidin
- Listede sıra-depo deposunu bulup Öğeleri görüntüle'yi tıklayın.
- Kişi sayısı bölümünde, Min. değerini 1 ve Maks. değerini 5 olarak ayarlayın.
- Vertex AI Vision'un Medya Deposu'nda depolanan işlenmiş video verilerini filtrelemek için Arama'yı tıklayın.
Google Cloud Console'daki arama ölçütleriyle eşleşen depolanan video verilerinin görünümü.
10. BigQuery tablosunu kullanarak çıkışı ek açıklamayla belirtme 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'
- Aşağıdaki kodu kullanarak rtsp akışından 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')
- BigQuery tablosundan veri zaman damgasını ve ek açıklama bilgilerini alın ve yakalanan kare resimlerini 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 not 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 kareleri tek tek tekrar 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ğiticide kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız kaynakları içeren projeyi silin veya projeyi saklayıp kaynakları tek tek silin.
Projeyi silme
Kaynakları tek tek silme
Kaynaklar
https://cloud.google.com/vision-ai/docs/overview
https://cloud.google.com/vision-ai/docs/occupancy-count-tutorial