Görüntü İşleme ile Cisim Hız Tespiti
1. Giriş
Görüntü İşleme ile Cisim Hız Tespiti

1. Giriş
Merhaba, bu yazımda sabit kamera ile Görüntü işleme ile nesnelerin hızını nasıl hesapladığımızı göstermeye çalışacam. Bu yaklaşım, özellikle trafik izleme, spor analizleri ve endüstriyel otomasyon gibi alanlarda sıkça kullanılır.
Bu yazıda,
- Hız hesaplamasının mantığını,
- Gerekli formülleri,
- Perspektif dönüşümünü (kuş bakışı görünüm elde etmek için),
- Örnek bir Python + OpenCV uygulamasını birlikte inceleyeceğiz.
2. Temel Mantık
Bildiğiniz gibi hız yol/zaman ile bulunur. Görüntü işlemede de aynı mantıkla ilerlersek zamanın 1/FPS , yolun pixsel değişimi olduğu sonucuna varırız. yani burda m/s yerine px/s geçerlidir peki bunu nasıl m/s’ye çevirecez ?
Burada boyunu veya enini bildiğimiz nesneler bize yardım ediyor.


Buradaki koordinatları(x,y) bizim işlem yapmak istediğimiz yere çiziyoruz yolun enini bildiğimizi varsayarsak örnek 5 metre burada pixseller arasındaki farkı da bildiğimiz için metre-pixsel dönüşümünü rahatlıkla yapabiliriz.
Tam burada aklımıza şu soru gelebilir perspektif olarak bize yakın olan pixsel daha fazla yer kaplamıyor mu ? Aslında öyle bunun için Python kullanarak perspektif dönüşümü yapmamız gerek.

Kuş bakışı görüntüsüne çevirme

yol

yol kuş bakışı

Az önce verdiğimiz koordinatları getPerspectiveTransform fonksiyonu için float32ye çeviriyoruz. Perspektif görüntüsünün çevrçevesi için pts2'yi oluşturuyoruz. getPerspectiveTransform çizdiğimiz sınırlara kuş bakışı ile izler vaziyete geçer. t_frame ile perspektif görüntüsünü alabiliyoruz.
Bundan sonra yapacağımız şey klasik yol/zaman olacak burada kuş bakışı ile ilk (x,y) ve son (x,y) bildiğimiz için kare farkları ile alınan yolu buluruz.

pixel-metre dönüşümü

hızın metre/ px dönüşümü
3. Nesne Tespiti ve Takibi
Gerekli Kütüphaneler

Hazır olan herhangi bir nesne tespit modelini alıp kulanıyoruz. Tespit edilen her cismin orta noktasını baz alıyoruz.

Araç tespiti
Bu aşamada Kalman-Sort-Deepsort gibi takip algoritmaları kullanmak gerekebilir onlara da diğer yazımda ona yer verecem.
from ultralytics import YOLO
import cv2
import numpy as np
import math
# YOLO modelini yükle
model = YOLO("yolov8n.pt")
# Video dosyasını aç
cap = cv2.VideoCapture("araba.mp4")
# FPS ve boyut bilgilerini al
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# FPS geçerli değilse manuel düzelt
if fps <= 0 or fps > 120:
print("⚠️ FPS değeri hatalı okundu, varsayılan 30 olarak ayarlanıyor.")
fps = 30.0
print(f"Video boyutu: {width}x{height}")
print(f"FPS: {fps}")
# Görüntüleme boyutu
display_width = 960
display_height = 720
# --- Perspektif bölge noktaları ---
tl = (1062, 972)
bl = (1700, 972)
tr = (50, 1800)
br = (1730, 1800)
region_pts = np.array([tl, bl, br, tr], np.int32).reshape((-1, 1, 2))
# --- Perspektif dönüşümü hedef boyutu ---
bird_width, bird_height = 960, 720
src_pts = np.float32([tl, bl, br, tr])
dst_pts = np.float32([[0, 0], [0, bird_height], [bird_width, bird_height], [bird_width, 0]])
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
# 7.5 m genişlik referansı
real_width_m = 7.5
pixel_width = math.dist(bl, tl)
px_to_m = real_width_m / pixel_width
# Takip ve sayaçlar
track_history = {}
object_positions = {}
entered_ids = set()
total_entered = 0
object_id_counter = 0
frame_index = 0
while True:
ret, frame = cap.read()
if not ret:
break
frame_index += 1
# YOLO tespiti (araç sınıfları)
results = model(frame, classes=[2, 3, 5, 7])
detections = results[0].boxes.data.cpu().numpy()
annotated_frame = frame.copy()
# Bölgeyi çiz
cv2.polylines(annotated_frame, [region_pts], True, (0, 255, 0), 2)
overlay = annotated_frame.copy()
cv2.fillPoly(overlay, [region_pts], color=(0, 255, 0))
annotated_frame = cv2.addWeighted(overlay, 0.2, annotated_frame, 0.8, 0)
new_positions = {}
for det in detections:
x1, y1, x2, y2, conf, cls = det
cx, cy = int((x1 + x2) / 2), int((y1 + y2) / 2)
center = (cx, cy)
inside = cv2.pointPolygonTest(region_pts, center, False)
matched_id = None
# ID eşleştirme
for oid, (px, py) in object_positions.items():
if math.dist((px, py), (cx, cy)) < 60:
matched_id = oid
break
if matched_id is None:
object_id_counter += 1
matched_id = object_id_counter
new_positions[matched_id] = (cx, cy)
# Alan giriş kontrolü
if inside > 0 and matched_id not in entered_ids:
total_entered += 1
entered_ids.add(matched_id)
# Sadece alan içindeyse hız hesapla
if inside > 0:
if matched_id not in track_history:
track_history[matched_id] = []
track_history[matched_id].append((cx, cy, frame_index))
# Hız hesaplama (PERSPEKTİF DÜZELTMELİ)
speed_text = ""
if len(track_history[matched_id]) >= 2:
(x1p, y1p, f1), (x2p, y2p, f2) = track_history[matched_id][-2], track_history[matched_id][-1]
time_diff = (f2 - f1) / fps
if time_diff > 0:
# --- Kuş bakışı koordinatları ---
pts_src = np.array([[[x1p, y1p]], [[x2p, y2p]]], dtype=np.float32)
pts_bird = cv2.perspectiveTransform(pts_src, M)
(bx1, by1), (bx2, by2) = pts_bird[0][0], pts_bird[1][0]
# --- Dönüştürülmüş piksel mesafesi ---
pixel_dist = math.dist((bx1, by1), (bx2, by2))
# --- Gerçek hıza dönüştür ---
speed_m_s = (pixel_dist * px_to_m) / time_diff
speed_kmh = speed_m_s * 3.6
speed_text = f"{speed_kmh:.1f} km/h"
else:
speed_text = "..."
else:
speed_text = "..."
# Görsel
color = (0, 255, 255)
cv2.rectangle(annotated_frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2)
cv2.putText(annotated_frame, f"ID {matched_id}", (int(x1), int(y1) - 45),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
cv2.putText(annotated_frame, speed_text, (int(x1), int(y1) - 10),
cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 255), 3)
object_positions = new_positions
# Sayaç
cv2.putText(annotated_frame, f"Total Vehicles Entered: {total_entered}",
(60, 80), cv2.FONT_HERSHEY_SIMPLEX, 1.4, (0, 255, 0), 4)
# Perspektif görünüm (bird-eye)
bird_eye = cv2.warpPerspective(frame, M, (bird_width, bird_height))
cv2.putText(bird_eye, "Perspective View", (20, 40),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# Görüntüleri ayrı pencerelerde göster
resized_main = cv2.resize(annotated_frame, (display_width, display_height))
resized_bird = cv2.resize(bird_eye, (display_width, display_height))
cv2.imshow("YOLO Speed View", resized_main)
cv2.imshow("Perspective (Bird-Eye) View", resized_bird)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Bu kodda yola bir bölge çizerek bölgeye giren cisimleri hazır olan bir araç tespit modeli ile tespit ediyoruz. Bölgeye giren her aracı sayıyor ve hızını ölçüyoruz.
Bu yazımda sabit kameralı bir sistemde görüntü işleme ile nesnelerin hızını ölçmenin temelini basit bir şekilde anlatmaya çalıştım. Gerçek hayatta karşılacağımız sistemler bundan daha karmaşık olacaktır.
Bir sonraki yazıda görüşmek üzere.
메타데이터
- post_id
- 95ca8192d7ca
- slug
- görüntü-i̇şleme-ile-cisim-hız-tespiti-95ca8192d7ca
- url
- https://medium.com/@halilalpak511/g%C3%B6r%C3%BCnt%C3%BC-i%CC%87%C5%9Fleme-ile-cisim-h%C4%B1z-tespiti-95ca8192d7ca
- canonical_url
- https://medium.com/@halilalpak511/g%C3%B6r%C3%BCnt%C3%BC-i%CC%87%C5%9Fleme-ile-cisim-h%C4%B1z-tespiti-95ca8192d7ca
- author_url
- https://medium.com/@halilalpak511
- status
- ok
- fetched_at
- 2026-06-28 04:42:08