Trafik · Piksel işleme (OpenCV tarzı)
🚗 Trafik sayacı ve hız tahmini
Yukarıdan bakan kamerayla araç say, yönünü ve hızını ölç.
Belediyelerin trafik kameraları, otopark girişleri ve kavşak sayımları için klasik boru hattı: derin öğrenme bile gerekmez. Sabit kamerada yol değişmez, araçlar değişir; arka planı öğrenip çıkarırsak geriye hareket eden lekeler kalır. Lekeleri kareden kareye eşleyip bir çizgiyi geçenleri sayarız; piksel/metre kalibrasyonuyla hız da çıkar.
Durum: …
Örnek sahne: yukarıdan görülen dört şeritli yol; araçlar farklı hızlarla iki yönde akar. Arka plan çıkarma, lekeler ve izleme çizilen piksellerden gerçekten hesaplanır.
Nasıl çalışıyor?
- Küçültme ve gri ton: kare 320×240'a küçültülür ve gri tona çevrilir (hız için).
- Arka plan modeli: seçici koşan ortalama. Araç olmayan piksellerde arka plan += 0,05 × (kare − arka plan); araç üstündeki piksellerde 0,002 ile (araçlar arka plana karışmasın).
- Ön plan maskesi: |kare − arka plan| > 28 olan pikseller beyaz. 4-komşulu bağlı bileşenler; 25 pikselden küçük lekeler gürültü sayılır.
- İzleme: her iz, önceki karedeki konumuna 30 px içindeki en yakın lekeyle eşlenir; 8 kare görünmeyen iz silinir.
- Sayma ve hız: iz merkezi sayma çizgisini geçince yönüne göre sayılır. Hız = son ~1 sn'deki yer değiştirme (px) × kalibrasyon (m/px) ÷ süre × 3,6 → km/sa. Sınırı aşan araç kırmızı işaretlenir.
Kendin dene
Örnek sahnede her aracın gerçek hızı yanında yazar: kalibrasyonu 0,08 ya da 0,12 m/px yaparak ölçülen hızın nasıl kaydığını gör (sahne 0,10 m/px ile çizildi: kesik çizgiler 3 m, aralar 6 m). Sayma çizgisini taşı. Kamera modunda kamerayı sabit tut ve önünden bir nesne geçir: hareket eden her şey leke olur.
Python karşılığı (OpenCV / MediaPipe)
import cv2, numpy as npcap = cv2.VideoCapture("yol.mp4") # sabit kameraMPP, LINE_Y, FPS = 0.10, 144, cap.get(cv2.CAP_PROP_FPS) or 30bg, tracks, next_id, count = None, {}, 1, {"asagi": 0, "yukari": 0} # down / upwhile cap.isOpened():ok, frame = cap.read()if not ok: breakg = cv2.cvtColor(cv2.resize(frame, (320, 240)), cv2.COLOR_BGR2GRAY).astype(np.float32)if bg is None: bg = g.copy()mask = (np.abs(g - bg) > 28).astype(np.uint8)bg += np.where(mask, 0.002, 0.05) * (g - bg) # seçici koşan ortalaman, labels, stats, cents = cv2.connectedComponentsWithStats(mask, connectivity=4)blobs = [tuple(cents[i]) for i in range(1, n) if stats[i, cv2.CC_STAT_AREA] >= 25]new = {}for (cx, cy) in blobs: # en yakın iztid = min(tracks, key=lambda k: np.hypot(*np.subtract(tracks[k][-1], (cx, cy))), default=None)if tid is None or np.hypot(*np.subtract(tracks[tid][-1], (cx, cy))) > 30 or tid in new:tid, next_id = next_id, next_id + 1hist = tracks.get(tid, []) + [(cx, cy)]if len(hist) > 1 and (hist[-2][1] < LINE_Y) != (hist[-1][1] < LINE_Y):count["asagi" if hist[-1][1] > hist[-2][1] else "yukari"] += 1k = hist[-min(len(hist), int(FPS)):]kmh = abs(k[-1][1] - k[0][1]) * MPP / (len(k) / FPS) * 3.6print(f"arac {tid}: {kmh:.0f} km/sa")new[tid] = hist[-60:]tracks = new
🔒 Kamera görüntüsü yalnız bu cihazda işlenir; hiçbir yere gönderilmez ve kaydedilmez. Sekmeden ya da sayfadan çıkınca kamera kapanır.