Macademia'nın robotik ve mühendislik programı · ücretsiz seviye tespiti ve kişisel öğrenme yolu

12. ünite / 12

Video ve arka plan çıkarma: hareket, leke, iz ve sayım

VideoCapture döngüsü, kare farkı, kayan ortalama arka plan ve MOG2, maske temizliği, leke izleme ve çizgi sayacı.

Bu ünitenin sonunda

  • Bir video döngüsü kurup kare başına süreyi ölçmek
  • Kare farkı ile arka plan modeli arasındaki farkı açıklamak
  • Kayan ortalama ve MOG2'nin öğrenme oranını ayarlamak
  • Ön plan lekelerini en yakın komşuyla izleyip çizgiyi geçenleri bir kez saymak

Ders notları

Video, saniyede 25–60 karelik bir görüntü dizisidir; cv2.VideoCapture her read() çağrısında bir kare verir. Sabit bir kamerada hareket eden şeyleri bulmanın en ucuz yolu arka planı bilmek ve ondan farkı almaktır.

Kare farkı ve arka plan modeli

Kare farkı |ft − ft−1| hareketi bulur ama duran bir nesne hemen kaybolur ve tek renkli bir aracın yalnız ön ve arka kenarı çıkar. Kayan ortalama arka planı yavaşça öğrenir:

B ← (1 − α) · B + α · f    ön plan: |f − B| > eşik

α küçükse arka plan yavaş uyum sağlar (park eden araç uzun süre ön planda kalır), büyükse yavaş giden nesne arka plana karışır. Seçici güncelleme, ön plan piksellerinde çok küçük α kullanır. MOG2 her piksel için birkaç Gauss'luk bir karışım tutar: sallanan yaprak gibi çok kipli arka planları ve gölgeleri (ayrı bir gri değerle) tanır.

Maskeden sayıma

  1. Maskeyi açma/kapama ile temizle, bağlı bileşenleri (lekeleri) bul, küçükleri at.
  2. İzleme: her lekeyi bir önceki karedeki en yakın ize bağla; eşleşmeyen leke yeni iz, birkaç kare görünmeyen iz silinir.
  3. Sayım: bir izin önceki ve şimdiki merkezi çizginin iki yanındaysa +1; her iz yalnız bir kez sayılır.

Bu hat Gerçek Hayat Demoları'ndaki trafik sayacıyla aynı fonksiyonları kullanır.

Oyun alanı

Arka plan çıkarma ve sayım

Kayan ortalama arka plan modeli; her karede |kare − arka plan| eşiklenir, morfolojiyle temizlenir, lekeler bulunur ve en yakın komşuyla izlenir. Sayım çizgisini geçen her iz bir kez sayılır.

Kare, izler ve sayım çizgisi
Ön plan maskesi
Öğrenilen arka plan B
sayım → 0 ← 0 gerçek → 0 ← 0 aktif iz: 0 t = 0.0 s

Kendin dene

Trafik sahnesinde öğrenme oranını 0,002, 0,05 ve 0,3 yap ve araçların maskede nasıl göründüğünü karşılaştır. Seçici güncellemeyi kapatınca yavaş araçlara ne oluyor? Eşiği 10'a indir ve gürültüyü 15 yap: sayaç neden şaşıyor, morfolojiyle düzeltebiliyor musun? Bir dakikada iki yönde kaç araç geçtiğini yaz ve sahnedeki gerçek sayıyla karşılaştır.

Kod

Python: video döngüsü, kare farkı ve kayan ortalama
import cv2
import numpy as np

cap = cv2.VideoCapture('trafik.mp4')              # ya da 0: kamera
fps = cap.get(cv2.CAP_PROP_FPS) or 30
avg, prev = None, None
while True:
    ok, frame = cap.read()
    if not ok:
        break                                     # video bitti
    gray = cv2.GaussianBlur(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), (5, 5), 0)
    if avg is None:
        avg, prev = gray.astype(np.float32), gray
        continue
    diff = cv2.absdiff(gray, prev)                # kare farkı: yalnız hareketli kenarlar
    cv2.accumulateWeighted(gray, avg, 0.02)       # arka plan = kayan ortalama
    fg = cv2.absdiff(gray, cv2.convertScaleAbs(avg))
    _, mask = cv2.threshold(fg, 25, 255, cv2.THRESH_BINARY)
    prev = gray
    cv2.imshow('mask', mask)
    if cv2.waitKey(int(1000 / fps)) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
Python: sentetik videoda MOG2, lekeler ve çizgi sayımı
import cv2
import numpy as np

rng = np.random.default_rng(1)
H, W, LINE = 240, 320, 160                        # sayım çizgisi x = 160
bg = np.full((H, W, 3), 90, np.uint8)
cars = [(-40 - 90 * i, 20 + 44 * i, 3 + i % 2) for i in range(5)]   # (x, y, hız)
mog = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=25, detectShadows=False)
prev, count, last = {}, 0, None
for t in range(220):
    frame = bg.copy()
    for i, (x0, y, v) in enumerate(cars):
        x = int(x0 + v * t)
        cv2.rectangle(frame, (x, y), (x + 36, y + 22), (40, 160, 230), -1)
    frame = cv2.add(frame, rng.integers(0, 12, frame.shape, dtype=np.uint8))   # sensör gürültüsü
    fg = mog.apply(frame)
    fg = cv2.morphologyEx(fg, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))
    n, lab, stats, cent = cv2.connectedComponentsWithStats(fg)
    now = {}
    for k in range(1, n):
        if stats[k, cv2.CC_STAT_AREA] < 300:
            continue
        cx, cy = cent[k]
        lane = int(cy // 44)                      # basit izleme: şerit başına bir iz
        if lane in prev and prev[lane] < LINE <= cx:
            count += 1                            # çizgiyi soldan sağa geçti
        now[lane] = cx
    prev = now
    last = frame
print('sayılan araç:', count)
cv2.line(last, (LINE, 0), (LINE, H), (0, 0, 255), 2)
cv2.imwrite('cikti.png', np.hstack([last, cv2.cvtColor(fg, cv2.COLOR_GRAY2BGR)]))

Sık yapılan hatalar

  • Kameranın kendisi hareket ederken arka plan çıkarma kullanmak: tüm görüntü ön plan olur; önce görüntüyü sabitlemek (öznitelik + homografi) gerekir.
  • Öğrenme oranını çok büyük seçmek: duran ya da yavaş nesneler birkaç saniyede arka plana karışır.
  • Gölgeleri nesne saymak: MOG2'de detectShadows=True ile gölge 127 değerini alır; eşiği 200 yap.
  • Aynı izi her karede yeniden saymak: iz başına "sayıldı" bayrağı tut.

Yazılım mühendisliği bağlantısı

Video işleme gerçek zamanlı bir sistemdir: gecikme bütçesi ve kare düşürme politikası tasarımın parçasıdır.

  • Kare başına süreyi ölç, ortalamayı ve 99. yüzdeliği kaydet; 33 ms'yi aşan kareleri say.
  • Kayıtlı bir test videosu ve beklenen sayım değeri tut; değişikliklerde sayımın ±1 içinde kaldığını CI'da sına (tarayıcıdaki sahne de bu yüzden tohumlu ve deterministiktir).

Kendini sına

  1. Kayan ortalama arka planda α çok büyük seçilirse ne olur?

  2. Kare farkı yönteminin tek renkli, büyük bir araçta sorunu nedir?

  3. Çizgi sayacında bir aracın iki kez sayılmasını ne önler?

  4. MOG2'nin kayan ortalamaya göre üstünlüğü nedir?

Bu üniteden sonra bitirme projesinde

  • Demo ve rapor: Komut satırı aracı, performans ölçümü (G5), test tablosu, 5 dakikalık demo ve kısa rapor.
Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç