Bağlam Tabanlı Görüntü İşleme Sistemleri için Azaltılmış Karmaşıklığa Sahip Gecikmeli Karar Algoritması

🎯 Giriş

Görüntü işleme sistemleri, yapay zekâ ve bilgisayarla görme alanlarının temel taşlarından biridir. Ancak bu sistemler genellikle yüksek hesaplama maliyeti, bellek kullanımı ve gerçek zamanlı işlem performansındaki sınırlamalar nedeniyle karmaşık hale gelir. Özellikle bağlam tabanlı (context-aware) görüntü işleme sistemleri, sahnenin genel anlamını veya çevresel bilgiyi dikkate aldıkları için ek bir analiz katmanı gerektirir.

Bu noktada azaltılmış karmaşıklığa sahip gecikmeli karar algoritmaları (Reduced-Complexity Delayed Decision Algorithms) devreye girer. Bu algoritmalar, karar mekanizmasını zaman içinde geciktirerek daha fazla bağlamsal bilgi toplar, fakat aynı zamanda hesaplama yükünü optimize eder.


🔍 Bağlam Tabanlı Görüntü İşleme Nedir?

Bağlam tabanlı görüntü işleme, bir sahnedeki nesneleri sadece piksel düzeyinde değil, anlamsal ilişkiler açısından da değerlendiren bir yöntemdir.
Örneğin bir otonom araç sistemi, sadece “bir nesne tespit edildi” demekle kalmaz; o nesnenin yolun neresinde, hangi hızda ve diğer nesnelerle hangi ilişkide olduğunu da anlamaya çalışır.

Bu yaklaşım sayesinde:

  • Görüntü yorumlama doğruluğu artar,
  • Gürültüye karşı dayanıklılık sağlanır,
  • Sahneye uygun kararlar alınabilir.

Ancak bunun bedeli genellikle yüksek hesaplama maliyetidir.


⚙️ Gecikmeli Karar Algoritması Nedir?

Gecikmeli karar (delayed decision) algoritmaları, görüntü işleme zincirinde karar verme adımını hemen gerçekleştirmez.
Bunun yerine, birkaç karelik veya işlem adımlık bir gecikmeyle daha fazla bilgi toplar. Böylece:

  • Gürültüden kaynaklı yanlış pozitif/negatif sonuçlar azalır,
  • Zaman içinde bağlamın daha doğru tahmini yapılabilir.

Bu strateji, özellikle video analizi, hareket takibi ve nesne sınıflandırma gibi dinamik ortamlarda oldukça etkilidir.


🧩 Azaltılmış Karmaşıklık Yaklaşımı

Klasik bağlam tabanlı sistemlerde, her kare için tam analiz yapılması gerekir. Bu da CPU/GPU yükünü artırır.
Azaltılmış karmaşıklığa sahip gecikmeli karar algoritması, bu yükü aşağıdaki yollarla optimize eder:

  1. Örnekleme Tabanlı İşleme (Subsampling):
    Her kare yerine belirli aralıklarla seçilen kareler analiz edilir. Aradaki kareler için tahminleme yapılır.
  2. Bağlam Penceresi Optimizasyonu:
    Karar geciktirme penceresi dinamik olarak ayarlanır. Gereksiz uzun gecikmeler önlenir.
  3. Hiyerarşik Karar Mekanizması:
    Önce düşük karmaşıklıklı bir tahmin yapılır, gerekirse üst seviye (daha detaylı) analiz devreye girer.
  4. Donanım Bilinçli Tasarım:
    GPU, FPGA veya gömülü işlemciler için optimize edilmiş modüler yapılar kullanılır.

Bu yöntemlerle, sistemin karar doğruluğu korunurken işlem süresi ve enerji tüketimi önemli ölçüde azaltılabilir.


🚗 Uygulama Alanları

Azaltılmış karmaşıklığa sahip bağlam tabanlı görüntü işleme sistemleri, birçok alanda kullanılmaktadır:

  • Otonom araçlar: Nesne tanıma, yaya tespiti ve yol durum analizi
  • Akıllı şehir sistemleri: Trafik akışı izleme ve olay tespiti
  • Endüstriyel otomasyon: Kalite kontrol ve üretim hattı denetimi
  • Güvenlik kameraları: Şüpheli davranış tespiti ve hareket analizi
  • Tıbbi görüntüleme: Görüntü gürültüsünü azaltarak daha net teşhis yapılması

🧮 Performans ve Sonuçlar

Yapılan deneysel çalışmalar göstermektedir ki:

  • Gecikmeli karar stratejisi, %15–30 oranında daha yüksek doğruluk sağlayabilir.
  • Karmaşıklık azaltma yöntemleri sayesinde %40’a kadar işlem süresi kazancı elde edilebilir.
  • Gerçek zamanlı uygulamalarda kare başına gecikme genellikle 20–50 ms civarında kalır; bu da insan gözüyle algılanamayacak düzeydedir.

🧠 Sonuç

Bağlam tabanlı görüntü işleme sistemleri, geleceğin akıllı algılayıcı teknolojilerinin temelini oluşturuyor.
Bu sistemlerde azaltılmış karmaşıklığa sahip gecikmeli karar algoritmaları, hem doğruluk hem de verimlilik açısından dengeli bir çözüm sunuyor.
Özellikle gerçek zamanlı uygulamalarda, akıllı karar geciktirme ve bağlam farkındalığı bir araya geldiğinde, sistem performansında dramatik bir iyileşme sağlanabiliyor.


✍️ Son Söz

Görsel verinin giderek arttığı bir dünyada, her pikselin anlamını doğru yorumlamak kadar, ne zaman karar verileceğini bilmek de kritik öneme sahip.
Azaltılmış karmaşıklıklı gecikmeli karar algoritmaları, bu bilgelik dengesini sağlayan yenilikçi bir yaklaşımdır.

  • Kareleri örnekleyerek (subsampling) iş yükünü azaltır,
  • Hızlı ön karar için frame-diff tabanlı hafif bir detector kullanır,
  • Ön karar “şüpheli/kararsız” olursa daha ağır ama hâlâ gömülebilir bir HOG tabanlı insan dedektörünü devreye sokar (hiyerarşik karar),
  • Son karar için son W karardaki sonuçları toplayıp çoğunluk prensibi ile gecikmeli karar verir.

Gereksinimler

Python 3.8+
pip install opencv-python numpy

(Not: OpenCV’nin HOG insan dedektörü yerel olarak çalışır. İsterseniz daha ağır bir ML modeli ekleyebilirsiniz.)


Kod

"""
delayed_decision_demo.py

Özet:
- Webcam veya video dosyasından kare okur.
- Her kare için (örnekleme ile) hızlı bir ön-detector (frame-diff) çalıştırır.
- Eğer ön-detector "şüpheli" ise daha detaylı HOG insan dedektörü devreye girer.
- Son karar penceresi (sliding window) ile gecikmeli karar alınır (majority voting).
- Amaç: bağlam (geçmiş kararlar) kullanarak daha güvenilir karar vermek,
  aynı zamanda gereksiz yere pahalı işlemleri azaltmak.
"""

import cv2
import numpy as np
from collections import deque
import time
import argparse

# -----------------------
# Parametreler
# -----------------------
SAMPLE_SKIP = 2          # Her X karede bir tam analiz yap (1 = her kare)
WINDOW_SIZE = 5          # Gecikmeli karar için kaç kararı saklayalım
FAST_AREA_THRESH = 5000  # frame-diff ile bulunan kontur alanı eşik değeri
HOG_CONF_THRESH = 0.5    # HOG sonuçlarını filtreleme için zorluk (kullanıma göre ayarla)
FPS_SMOOTH = 0.9

# -----------------------
# Yardımcı bileşenler
# -----------------------
class FrameSampler:
    """Her N karede bir 'full' analiz yapılmasını sağlar."""
    def __init__(self, skip):
        self.skip = max(1, skip)
        self.counter = 0
    def should_process(self):
        self.counter = (self.counter + 1) % self.skip
        return self.counter == 0

class FastDetector:
    """Hafif ön-detector: frame differencing + simple contours."""
    def __init__(self):
        self.prev_gray = None
    def detect(self, frame):
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        gray = cv2.GaussianBlur(gray, (5,5), 0)
        if self.prev_gray is None:
            self.prev_gray = gray
            return [], 0  # ilk karede tespit yok
        diff = cv2.absdiff(self.prev_gray, gray)
        self.prev_gray = gray
        _, th = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)
        th = cv2.dilate(th, None, iterations=2)
        contours, _ = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        boxes = []
        total_area = 0
        for cnt in contours:
            area = cv2.contourArea(cnt)
            if area < 50: continue
            total_area += area
            x,y,w,h = cv2.boundingRect(cnt)
            boxes.append((x,y,w,h))
        return boxes, total_area

class HeavyDetector:
    """Daha ağır ama güvenilir: HOG pedestrian detector (OpenCV)."""
    def __init__(self):
        self.hog = cv2.HOGDescriptor()
        self.hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
    def detect(self, frame):
        # HOG için genelde gri + ölçeklendirme daha iyi sonuç verir
        rects, weights = self.hog.detectMultiScale(frame, winStride=(8,8), padding=(8,8), scale=1.05)
        detections = []
        for r, w in zip(rects, weights):
            if w < HOG_CONF_THRESH: 
                continue
            x,y,wid,hei = r
            detections.append((x,y,wid,hei, float(w)))
        return detections

class DelayedDecisionMaker:
    """
    Sliding window üzerinden majority voting ile nihai karar.
    Her frame için '0'=no object, '1'=object detected (güvenli).
    """
    def __init__(self, window_size):
        self.window = deque(maxlen=window_size)
    def add_vote(self, vote):
        # vote 0 veya 1
        self.window.append(int(bool(vote)))
    def get_decision(self):
        if len(self.window) == 0:
            return 0
        ones = sum(self.window)
        # eşitlik durumunda '0' (daha muhafazakâr) dönülebilir; burada majority kullanıyoruz
        return 1 if ones > len(self.window) / 2 else 0

# -----------------------
# Ana döngü
# -----------------------
def main(video_source=0):
    cap = cv2.VideoCapture(video_source)
    if not cap.isOpened():
        print("Video kaynağı açılamadı:", video_source)
        return
    sampler = FrameSampler(SAMPLE_SKIP)
    fast_det = FastDetector()
    heavy_det = HeavyDetector()
    ddm = DelayedDecisionMaker(WINDOW_SIZE)

    last_time = time.time()
    fps = 0.0

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        # boyut küçültme (işlem hızlandırma / demo amaçlı)
        frame_small = cv2.resize(frame, (640, int(frame.shape[0]*640/frame.shape[1])))

        # Her karede hızlı ön-detector (ancak tam analiz sadece sampler ile yapılır)
        boxes_fast, total_area = fast_det.detect(frame_small)

        # Hızlı kriter: toplam alan bir eşik üzerinde ise "şüpheli"
        fast_flag = total_area > FAST_AREA_THRESH

        heavy_boxes = []
        # Eğer hızlı detector şüpheli ise, daha ağır detector ile doğrula
        if fast_flag and sampler.should_process():
            heavy_boxes = heavy_det.detect(frame_small)
            heavy_flag = len(heavy_boxes) > 0
        else:
            heavy_flag = False

        # Hiyerarşik karar:
        # - Eğer hızlı detector netse (çok büyük alan) => object
        # - Eğer hızlı azsa ve ağır detector pozitif => object
        # - Aksi halde no object
        decision_vote = 1 if (fast_flag and total_area > 2*FAST_AREA_THRESH) else (1 if heavy_flag else 0)

        # Gecikmeli karar mekanizmasına ekle
        ddm.add_vote(decision_vote)
        final_decision = ddm.get_decision()

        # Görselleştirme
        vis = frame_small.copy()
        # Hızlı tespitleri çiz
        for (x,y,w,h) in boxes_fast:
            cv2.rectangle(vis, (x,y), (x+w,y+h), (200,200,0), 1)
        # Ağır tespitleri çiz (daha kalın)
        for (x,y,w,h,conf) in heavy_boxes:
            cv2.rectangle(vis, (x,y), (x+w,y+h), (0,200,0), 2)
            cv2.putText(vis, f"{conf:.2f}", (x,y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,200,0), 1)

        # Ekran üstü bilgi
        cv2.putText(vis, f"FastArea:{int(total_area)}", (10,20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 1)
        cv2.putText(vis, f"FastFlag:{int(fast_flag)} HeavyFlag:{int(heavy_flag)}", (10,45), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 1)
        cv2.putText(vis, f"DelayedDecision:{final_decision}", (10,70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,255,255) if final_decision else (128,128,128), 2)
        cv2.putText(vis, f"SAMPLE_SKIP:{SAMPLE_SKIP} WINDOW:{WINDOW_SIZE}", (10,100), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200,200,200), 1)

        # FPS hesaplama
        now = time.time()
        dt = now - last_time
        last_time = now
        if dt > 0:
            fps = FPS_SMOOTH * fps + (1-FPS_SMOOTH) * (1.0/dt)
        cv2.putText(vis, f"FPS:{fps:.1f}", (vis.shape[1]-120, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 1)

        cv2.imshow("Delayed Decision Demo", vis)
        key = cv2.waitKey(1) & 0xFF
        if key == ord('q'):
            break
        elif key == ord('w'):
            # örnek: pencereyi temizle (sadece demo)
            ddm.window.clear()
        elif key == ord('+'):
            global SAMPLE_SKIP
            SAMPLE_SKIP = min(10, SAMPLE_SKIP+1); sampler.skip = SAMPLE_SKIP
        elif key == ord('-'):
            SAMPLE_SKIP = max(1, SAMPLE_SKIP-1); sampler.skip = SAMPLE_SKIP

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Delayed Decision demo")
    parser.add_argument('--source', type=str, default="0", help="Webcam index (0) veya video dosyası yolu")
    args = parser.parse_args()
    src = int(args.source) if args.source.isdigit() else args.source
    main(src)

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir