Bilgisayar Görüşüyle Gerçek Zamanlı Sanal Aksesuar Filtresi Geliştirme

bilgisayar-gorusuyle-gercek-93

Bir kameraya bakıp ekranda gözlüğü, şapkayı veya komik bir bıyığı yüzünüze kusursuzca oturtmak sihir gibi görünür. Aslında bu etki; yüz tespiti, yüz işaret noktaları (landmark), geometrik dönüşümler ve alfa harmanlama işlemlerinin hızlı bir orkestrasyonudur. Bu projede Python, OpenCV ve MediaPipe kullanarak kameradaki yüzü izleyen, üzerine gerçek zamanlı sanal aksesuar yerleştiren bir artırılmış gerçeklik filtresinin mantığını kuracağız.

``

Filtrenin temel çalışma zinciri

Sistem her video karesinde aynı döngüyü yürütür: Kameradan görüntü alınır, yüz ve yüz üzerindeki referans noktaları bulunur, aksesuarın konumu ile boyutu hesaplanır ve son olarak saydam PNG görüntüsü kareye birleştirilir. Video saniyede yaklaşık 30 kare gösterdiğinde, bu hesapların her biri için yalnızca yaklaşık $33\,ms$ zamanımız vardır:

\[t_{frame} = \frac{1}{FPS} = \frac{1}{30} \approx 0.033\,s\]

Bu nedenle yalnızca yüzün dikdörtgenini bulmak yerine, göz köşeleri, burun ucu ve alın gibi stabil noktaları izlemek daha iyi sonuç üretir. MediaPipe Face Mesh, yüz üzerinde yüzlerce landmark sağlayarak gözlük gibi detaylı aksesuarların konumlandırılmasını kolaylaştırır.

Aşama Görevi Gözlük filtresindeki karşılığı
Yüz tespiti Yüzün olup olmadığını bulur İşleme başlayacak bölgeyi belirler
Landmark tespiti Yüzdeki referans noktalarını verir İki gözün merkezi bulunur
Geometri Ölçek, açı ve konumu hesaplar Gözlük yüzle birlikte döner
Kompozitleme Saydam görseli görüntüye karıştırır PNG gözlük doğal görünür

Geometri: aksesuar neden eğilmeli?

Yüzünüzü sağa yatırdığınızda sabit yatay bir gözlük görüntüsü hemen sahte görünür. Bu yüzden iki göz arasındaki vektörden dönüş açısını hesaplarız. Sol ve sağ göz merkezleri sırasıyla $(x_L, y_L)$ ve $(x_R, y_R)$ ise açı şöyledir:

\[\theta = \operatorname{atan2}(y_R-y_L, x_R-x_L)\]

Gözler arası uzaklık da aksesuarın ölçeği için güçlü bir referanstır:

\[d = \sqrt{(x_R-x_L)^2 + (y_R-y_L)^2}\]

Örneğin gözlük PNG’sinin genişliğini $w = 2.2d$ seçmek, farklı uzaklıklardaki yüzlerde daha tutarlı sonuç verir. 2.2 değeri evrensel bir kural değil; kullandığınız görselin çerçeve genişliğine göre deneyerek ayarlanacak bir katsayıdır.

Temel uygulama iskeleti

Önce pip install opencv-python mediapipe numpy ile bağımlılıkları kurun. Aşağıdaki örnek, landmark koordinatlarından gözler arası mesafeyi hesaplar. Gerçek projede bu değerle PNG’yi yeniden boyutlandırıp döndürmeniz gerekir.

import cv2
import mediapipe as mp
import math

cap = cv2.VideoCapture(0)
face_mesh = mp.solutions.face_mesh.FaceMesh(
    max_num_faces=1, refine_landmarks=True
)

while cap.isOpened():
    ok, frame = cap.read()
    if not ok:
        break

    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    result = face_mesh.process(rgb)

    if result.multi_face_landmarks:
        h, w = frame.shape[:2]
        points = result.multi_face_landmarks[0].landmark
        left = points[33]   # Sol göz dış köşesi
        right = points[263] # Sağ göz dış köşesi

        x1, y1 = int(left.x * w), int(left.y * h)
        x2, y2 = int(right.x * w), int(right.y * h)
        angle = math.degrees(math.atan2(y2 - y1, x2 - x1))
        distance = math.hypot(x2 - x1, y2 - y1)

        cv2.putText(frame, f"aci={angle:.1f}, olcek={distance:.0f}",
                    (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

    cv2.imshow("AR Filtre", frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

Alfa kanalı: siyah kutu sorununu çözmek

Aksesuar görselinizin şeffaf arka planlı RGBA PNG olması gerekir. RGB renk bilgisini, A ise saydamlığı taşır. Piksel bazında karışım şu formülle yapılır:

\[C_{sonuc} = \alpha C_{aksesuar} + (1-\alpha)C_{kamera}\]
Yöntem Avantajı Sınırlaması
Dikdörtgen yapıştırma Çok hızlıdır Arka plan görünür, yapay durur
Maske ile kopyalama Basit ve kullanışlıdır Yarı saydam kenarlar zayıf kalabilir
Alfa harmanlama Yumuşak ve doğal sonuç verir Kanal ve boyut yönetimi gerekir

Son aşamada aksesuarı cv2.resize ile ölçekleyin, cv2.getRotationMatrix2D ile döndürün ve gözlerin orta noktasına yerleştirin. Çerçevenin görüntü dışına taşmasını kırparak kontrol edin. Daha profesyonel bir sürüm için landmark koordinatlarına üstel hareketli ortalama uygulayın; böylece küçük tespit oynamaları titreşen gözlükler yerine sakin, ikna edici bir AR deneyimine dönüşür.

Yorumlar