Ara 092018
 
1.096 kez okundu

OpenCV ile Yüz Tanıma Bölüm 2

OpenCV Yüz Tanıma 2

Bu bölümde 3 ayrı betik kullanıyoruz:
1- veri toplama: 01_face_dataset.py
2- eğitim: 02_face_training.py
3- uygulama: 03_face_recognition.py

Orijinal kodlara https://www.hackster.io/mjrobot/real-time-face-recognition-an-end-to-end-project-a10826 adresinden ulaşabilirsiniz.

Ben veri kümesini yeniden oluşturdum. Türkçe karakterlerin görüntülenebilmesi için gerekli düzenlemeyi yaptım ve bazı mesajları Türkçeleştirdim.

İlk betikte input() komutunu # ile devre dışı bıraktım. Yeni bir yüz tanıtırken face_id sayısını doğrudan tanımladım. Örneğimizde 4 yüz tanımlı. Her yüz için 30 kare dataset klasörüne kaydedildi. Siz de kendi verilerinizi kaydetmeli ve eğitmelisiniz.

İlk betiğimizde cv2 ve os kütüphanelerini kullanıyoruz.

Görüntüleri webcam üzerinden elde edeceğiz. Görüntülerimizin eni 640, yüksekliği 480 piksel olarak tanımlandı (satır 5 ve 6).

7 nolu satırda cepheden yüz sınıflandırıcısını tanımlıyoruz.

face_id yüz görüntülerini eğiteceğimiz kullanıcı numarasını belirtiyoruz. Eğer input() satırını kullanmak isterseniz 9.satırın başındaki # işaretini silip, 10. satırın başına # eklemelisiniz.

count değişkenini görüntü sayısını takip etmek için kullanacağız.

Kayıt işlemlerimiz 15. satırdaki sonsuz while döngüsüyle başlıyor.

16. satırda kamera görüntüsünü alıyoruz. ret değişkeni işlevsizdir. Bu değişken video dosyasından okuma yaparken işimize yarıyor.

Görüntü karesini griye çevirip içindeki yüzleri saptıyoruz. (Satır 18 ve 19.)

Aslında her karede sadece 1 kişiye ait tek bir yüz bulunmalı. Yine de burada bir döngü kullanıyoruz. Aslında döngüdeki enbüyük dikdörtgeni seçsek daha doğru olurdu. Ama kodu gereksiz yere uzatmamak için bu tür ayrıntılara girmiyoruz.

Yakalanan her yüz için count değerini 1 arttırıyor (satır 22) ve yüz görüntüsünü dataset klasörüne kaydediyoruz. Kaydedilen görüntünün boyutları yüzün boyutları ile aynı. Yani webcam tarafından yakalanan görüntünün tümünü kullanmıyoruz. (Satır 24)

25.satırda kamera görüntüsünü (tamamını) ekrana yansıtıyoruz.

k değişkeni ile 100 milisaniye içinde bir tuşa basılıp basılmadığını kontrol ediyoruz.

Eğer ‘Esc’ tuşuna basıldıysa (sayısal karşılığı 27 olan tuş) döngüyü kırıyor, basılmadıysa bu kez count değerinin 30’u aşıp aşmadığını denetliyoruz. Sayı 30’u aştıysa döngüyü yine kırıyoruz. Çünkü her kişi için 30 görüntü kaydediyoruz.

Son iki satırda kamerayı serbest bırakıyor ve belleği temizliyoruz.

“dataset” klasörünün içine bakarsanız, verdiğiniz kullanıcı numarasına karşılık gelen 30 adet resim göreceksiniz.

Kullanıcı sayısını (yüz görüntülerini kaydedeceğiniz kişi sayısını) istediğiniz kadar arttırabilirsiniz. (Elbette en az bir kişi olmalı!)

Verilerimizi tamamladığımızda işimiz bitmiyor. Şimdi bu veri kümesini eğitmemiz lazım. İkinci betiğimizin işlevi bu!

İkinci -eğitim- betiğimizde opencv ve os yanısıra numpy ve pillow kütüphanelerini kullanıyoruz.

Veri klasörümüzün adı ‘dataset’. Bu bilgiyi path değişkeninde tutuyoruz.

Veri kümemizin eğitimini cv2.face.LBPHFaceRecognizer_create() komutuyla oluşturduğumuz recognizer (satır 7) üzerinden yapacağız.

Görüntülerdeki yüz alanlarını ayırmak için yine ‘haarcascade_frontalface_default.xml’ filtresinden yararlanacağız. Filtre değişkenimizin adı: detector. (satır 8)

Görüntü etiketlerimizi almak için getImagesAndLabels() fonksiyonunu kullanıyoruz.

ImagePaths listesi, path klasörü içinde yer alan dosyaların listesidir.

faceSamples listesi yüz görüntülerini, ids listesi ise her bir görüntünün etiketini tutacak.

imagePaths listesindeki her bir elemanı (dosya adını) kullanarak ilgili resmi okuyup griye dönüştürüyor ve PIL_img değişkenine atıyoruz (satır 15). Sonra bu görüntüleri 8 bitlik pozitif tamsayılardan oluşan bir numpy dizisi (array) haline dönüştürüyoruz (satır 16).

17 numaralı satırda, dosya adından kişi numarasını ayırıp, bir tam sayı olarak id değişkenine atıyoruz.

img_numpy görüntü numpy dizisinde bulunan yüz alanlarını bulup faces listesine atıyoruz. Yüzleri içeren listeyi döngüye sokup her bir görüntüyü faceSamples, ona karşılık gelen etiketi ise ids listesine ekliyoruz.

Fonksiyonumuz faceSamples ve ids listelerini döndürüyor.

24 numaralı satırda faces ve ids listeleri oluşturuluyor.

25 nolu satırda ise veri kümemizi eğitiyoruz.

Eğitilmiş veriseti bilgileri 27. satırda trainer klasörü içindeki trainer.yml dosyasına kaydediliyor. Bu dosyayı son betiğimizdeki görüntüleri sınıflandırırken kullanacağız.

Son betiğimiz şöyle:

Kamera görüntülerindeki yüzleri yakalayıp kime ait olduklarını belirten betiğimiz bu. Kullanacağımız kütüphaneler opencv, numpy ve pillow.

print_utf8_text() fonksiyonunu bir önceki yazımda anlatmıştım. Türkçe karakterleri bu fonksiyon aracılığıyla bastırıyoruz.

Yüz tanıma nesnemiz recognizer‘a trainer.yml dosyası aracılığıyla eğitilmiş verisetimizi yüklüyoruz (satır 18 ve 19).

Canlı kamera görüntülerindeki yüzleri de yine haarcascade_frontalface_default.xml filtresi aracılığıyla yakalayacağız. Filtre değişkenimiz faceCascade (satır 20 ve 21).

22 nolu satırda orijinal betikte kullanılan font tanımlanıyor. Biz bu fontu da kullanacağız.

Kişi numaraları id değikeninde tutulacak. (Satır 24)

Etiketleri (isimleri) ise names listesiyle tanımlıyoruz.

Web kamerasının görüntüsünü cam değişkenine aktarıyoruz ve görüntü boyutlarını 1000 ve 800 piksel olarak ayarlıyoruz. (Bu değerleri 640 ve 480 olarak da bırakabilirdik.)

minW ve minH değişkenleri yakalanan yüz dikdörtgenlerinin boyutu için alt sınır değerleridir (satır 33 ve 34). Bu değerleri kendi ortamınıza göre değiştirebilirsiniz.

35 nolu satırda sonsuz döngümüz başlıyor.

36. satırda kamera görüntüsünü okuyor, 38. satırda bu görüntüyü grileştiriyoruz.

40 nolu satırda görüntü karesindeki tüm yüzleri yakalıyor; 46. satırda ise bu yüz dikdörtgenlerini bir döngü içinde işleme sokuyoruz.

recognizer.predict() metodu id ve confidence değerlerini döndürüyor. id kişi numarası; confidence ise yapılan saptamanın tahmini doğruluk oranıdır (satır 48).

id ve confidence değişkenlerini print için uygun hale getiriyoruz (satır 50-55).

58 nolu satırda kişi ismini UTF-8 kullanarak (Türkçe karakterleri doğru şekilde yansıtarak), 60 nolu satırda ise belirtilen kişinin tahmini doğruluk oranını standart font ile görüntüye işliyoruz.

Görüntünün ekrana yansıtılması 62 nolu satırda.

Döngümüz yine Esc veya q tuşlarından birine basıldığında kırılıyor.

Döngü kırıldığında web kamerayı sonlandıyor ve belleği temizliyoruz (satır 68-69).

Bu betiğin çalışmasını gösteren örnek video aşağıda.

Bu yazı, açıklamaları olabildiğince kısa tutsam da biraz uzunca oldu. Umarım yeterince açıklayıcıdır. Sorularınız için yorum alanını kullanabilirsiniz.

Bir sonraki yazımda yine yüz tanıma olacak. Ancak veri kümemizi oluşturmak ve eğitmek için farklı yöntemler kullanacağız.

Beni izlemeye devam edin.

Ahmet Aksoy