Fotoğrafların sayısı zamanla artar. Daha önce olduğu gibi Google Photos’a yükleyip, burada yüz tanıma özelliğinden faydalandım; ancak kendim, kendi donanımımda bu uygulamayı kurabileceğimi düşündüm. Ailemin fotoğraflarını bir bulut sağlayıcısına göndermeden bunu yapmam mümkün müydü?
Evet, bu mümkün ve bu proje benim için oldukça tatmin edici bir altyapı çalışması oldu.
Bu yazı, mimarinin nasıl kurulduğunu, ilginç teknik kararları ve karşılaştığım bazı zorlukları anlatacak.
Ne Yapıyor?
Ne Yapıyor?
Yüksek seviyede: fotoğraflarınızı yüklüyorsunuz, sistem fotoğraflardaki yüzleri tespit ediyor, benzer yüzleri “insanlar” olarak grupluyor ve bu gruplamaları gözden geçirebileceğiniz bir kontrol panelini kullanıma sunuyor — tüm bu işlemler Docker kullanılarak yerel olarak yürütülüyor, harici API aramaları veya abonelik yok.
Proje üç ayrı repodan oluşuyor:
- face-pipeline — gerçek bilgisayarla görme işini yapan bir FastAPI servisi.
- face-pipeline-ui — kontrol panelini, yüklemeleri ve gerçek zamanlı ilerlemeyi sağlayan bir Laravel uygulaması.
- photo-organizer — Docker Compose ile her şeyi birbirine bağlayan dağıtım katmanı.
Yüz Tanıma Süreci
Yüz Tanıma Süreci
Projenin merkezi InsightFace, iki model kullanarak çalışıyor:
- SCRFD — bir fotoğraftaki yüzlerin sınırlayıcı kutularını bulmak için kullanılıyor.
- ArcFace — tespit edilen her yüzü, ayırt edici özelliklerini yakalayan bir vektöre dönüştürmek için kullanılıyor.
Embeddings’i elde ettikten sonra, ilginç sorun şu: insanları gruplamak için önceden kaç kişinin olduğunu bilmeden nasıl gruplandırmalıyız?
HDBSCAN kullandım; bu, önceden cluster sayısını belirtmenizi gerektirmeyen yoğunluk tabanlı bir kümeleme algoritması. Bu, belirli bir fotoğraf kütüphanesinde kaç farklı insan olduğunu bilmediğiniz için çok uygun bir çözüm. Yüz embeddings’leri pgvector (vektör benzerliği araması için bir Postgres uzantısı) ile saklanıyor, bu da yeni yüzleri mevcut kümelerle hızlı bir şekilde karşılaştırmayı sağlıyor.
Bu son nokta çok önemli. Aksi takdirde, yeni bir fotoğraf geldiğinde tüm veri kümesini yeniden kümelersiniz — bu hem pahalıdır hem de kütüphane büyüdükçe işler daha da zorlaşır. Bunun yerine, pipeline artımlı centroid eşlemesi yapıyor: her mevcut kümenin bir centroid’i var (temelde, onun “ortalama yüzü”) ve yeni tespitler öncelikle bu centroid’lerle karşılaştırılıyor. Yalnızca bir şey mevcut bir kümeye güvenle uymadığında, bu durum yeni bir kişi veya inceleme için belirsiz bir durum olarak ifade ediliyor. Bu, kütüphane büyüdükçe sürekli işlemenin hızlı kalmasını sağlıyor.
Küme kalitesini yüksek tutmak için, kümelere ulaşan her şeyden önce iki filtre çalıştırılıyor:
- Blur scoring, yarıdan fazla bulanık olmayan, kullanışlı bir yüz tespitine yönelik.
- Relative face-size filtering, çerçevede güvenilir bir embedding oluşturamayacak kadar küçük yüzleri dışarıda bırakmak için.
Kötü giriş, kötü çıkış (Garbage in, garbage out) yüz kümeleri için geçerlidir — birkaç kötü embedding tüm kümeyi yanlış yöne sürükleyebilir.
Uygulama Katmanı
Uygulama Katmanı
FastAPI servisi, bilinçli olarak dar tutulmuş — sadece bilgisayarla görme işini yapıyor. Kullanıcıya dair her şey bir Laravel uygulamasında yaşıyor: proje yönetimi, fotoğraf yüklemeleri, tespit edilen insanları gözden geçirme, yanlış sınıflandırmaları düzeltme ve pipeline ilerlemesini gösteren gerçek zamanlı bir kontrol paneli.
Bu gerçek zamanlı parça, Laravel Reverb kullanıyor; Laravel’in kendini barındıran WebSocket sunucusu. Bir fotoğraf grubu yüklediğinizde, bunlar pipeline üzerinden asenkron olarak işleniyor ve her aşama tamamlandıkça UI güncelleniyor — tespit, embedding, kümelenme — bunu sürekli yeniden yüklemek zorunda kalmadan sağlıyor.
İki Dağıtım Modu
İki Dağıtım Modu
Başından beri istediğim bir şey: bu proje “ileri düzey kullanıcılar için” olmamalı. Bu nedenle photo-organizer iki farklı şekilde çalıştırılabiliyor:
Tek konteyner modu — her şey (web sunucusu, kuyruk işleyicileri, zamanlayıcı, websocket sunucusu) tek bir konteyner içinde çalışıyor. En basit kurulum: klonlayın, docker compose up yazın, ve tamam! Denemek veya mütevazı bir donanımda çalıştırmak için iyi.
Çoklu konteyner modu — aynı Laravel uygulaması, web sunucusu, Horizon (kuyruk işleyicileri), zamanlayıcı ve Reverb için bağımsız konteynerlere bölünmüş durumda, bunlar bağımsız olarak ölçeklenebiliyor. Eğer büyük bir fotoğraf kütüphanesi işliyorsanız ve sadece kuyruğa daha fazla işçi eklemek istiyorsanız, bu mod tam size göre.
Tek bir konteyner kurulumunu birden fazla konteynere bölmek kendi başına küçük bir macera oldu — Docker ağları, localhost ile ilgili bazı düşüncelere sahip; bu, geçiş sırasında devam etmiyor, ve uygulama bölündüğünde WebSocket yayını sükunetle başarısız oldu çünkü aynı ortam değişkeni sessizce iki uyumsuz işe yarıyordu (tarayıcıya nereden bağlanacağı ve arka planda nereden yayın yapacağı). Bunu gerçekleştirecek olanlar, yaptıkları her ortam değişkenini incelemek amacıyla izlemek zorundalar.
Farklı Yapacaklarım
Farklı Yapacaklarım
Birkaç dürüst yansıma; bu yazıları yazmanın değerinin bir kısmı, zorlu yönlerle ilgili açık olmaktır:
- Küme ayarları sabır gerektirir. HDBSCAN’ın
min_cluster_sizevemin_samplesparametreleri, yüzlerin ne kadar hızlı gruplandığını anlamlı derecede etkiler ve doğru değerler, belirli fotoğraf kütüphaneniz için değişir — kişibaşı kaç fotoğraf, ışık/poz açısı değişimleri gibi. Bunları katı kodlamaktansa ayarlanabilir ortam değişkenleri olarak sundum. - Hizmetler arası paylaşılan depolama özel dikkat gerektirir. FastAPI pipeline ve Laravel uygulaması, aynı fotoğraf/yüz kesim dosyalarına ihtiyaç duyuyor, bu da farklı kullanıcılar olarak çalışan konteynerler arasındaki dosya izinlerinin doğru şekilde ayarlanmasını gerektiriyor — bu küçük şey, bilgisayarla görme kodundan daha fazla hata ayıklama süresine mal oldu.
- Artımlı eşleme karmaşıklığa değer. Daha basit bir tam yeniden kümeleme için bunu atlamayı düşünmüştüm ve iyi ki atlamadım — kütüphaneniz büyüdükçe sistemin hissettirdiği fark önemli.
Deneyin
Deneyin
Her şey açık kaynak (Apache-2.0):
Self-hosting, bilgisayarla görme veya iyi bir Docker Compose yığını ile ilgileniyorsanız, geri dönüşlerinizi duymaktan memnun olurum — sorunlar, PR’lar veya mimari ile ilgili düşünceler de hoş karşılanır.
Kaynak: Orijinal Makale


