Ara 092018
 
283 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

Ağu 102018
 
565 kez okundu

Kaçıncı Yeni

Kaçıncı Yeni

1950’li yıllarda edebiyat sahnesine giren “2. Yeni” şiir akımı, bir tepkiyi dile getiriyordu. Bu tepki, Varlık Dergisi etrafında Orhan Veli ve arkadaşlarının başlattığı Garip akımına karşıydı. Eş zamanlı olarak, 2. Dünya Savaşının tetiklediği bunalım ortamlarından filizlenen dadaizm ve varoluşçuluk gibi akımlardan esinlendi.

Bu akımın önde gelen isimleri Cemal Süreya, İlhan Berk, Edip Cansever, Ece Ayhan, Turgut Uyar, Ülkü Tamer ve Sezai Karakoç gibi isimlerdi.

İkinci yenicilerin sloganı “şiir için şiir”dir. Onlar için söz sanatları, kelime oyunları ve hayal dünyası ön plandadır. Bu yüzden mesajlarını doğrudan doğruya vermek yerine imgeleri ve metaforları kullanmayı tercih ettiler.

Bazı 2. yeni şiirleri peşpeşe dizilmiş, ilgisiz sözcüklerden oluşan anlamsız bir biçim gibi görünür. Cümleler belirsiz veya devriktir. Hatta hiç cümle yoktur.

İşte Ece Ayhan’dan birkaç dize:

geçer sokaktan bakışsız bir
Kedi Kara.
Çuvalında yeni ölmüş bir çocuk.
Kanatları sığmamış.
Bağırır Eskici Dede.
Bir korsan gemisi! girmiş körfeze

Biraz kargalarlı, aykırı düşüncelerdir.

Peki bunları niye anlatıyorum?

Çünkü, Tensorflow ile “Char-RNN” yöntemini kullanarak oluşturduğum örnekler bir bakıma bu “2. Yeni” şiirlerine benziyor.
Ancak bu sonucu yaratan baş etmen, sistemi eğitmek amacıyla kullandığım veri kümesinin yeterli büyüklüğe sahip olmayışıdır.
Bir diğer etken ise verilerin içinde yer alan dizim hatalarıdır. Bu durumu ne yazık ki sonradan farkettim. Bütün dizeleri tek tek gözden geçirip düzeltmeye çalışmak, olağanüstü bir çaba ve zaman gerektiriyor.

Yine de, durumu biraz olsun hafifletmek amacıyla “geçersiz sözcük barındıran dizeleri” silen bir süzgeç kullandım. Bu sayede elde ettiğim tüm dizeler, tamamiyle geçerli Türkçe sözcüklerden oluşmaktadır.

İşte benim haylaz öğrencinin dile getirdiği bazı dizeler:

Ne herşey evleri
kağıttan görüyorum
Mutlaka kalacaktı bana inat
İstememiş, sokaklarımız

Kan deniz öyle biri
Anlama gittiğimiz yok
Ben ayı açık sızlar,
umuttan ömrümüz

Kaygılar her şeyleri yerinde

Yağmurları sis böyle düştüm
perde, ilk zamanmış bütün
Ve bu zaman bir güllerden
Aşktı
Acısıyla kaybettiğim karanlıkta

Sonuçların ileride daha fazla anlamsal bütünlük kazanacağını umuyorum. Bunu sağlamak için, öncelikle eğittiğim veri kümesini daha büyük boyutlu ve sorunsuz dizelerden oluşan bir yapıya kavuşturmam gerek. Bu da uzunca bir zamana ihtiyaç duyacak.
Şimdilik, geçici bir yöntem olarak, elde ettiğim ayıklanmış dizeleri mevcut veri kümesine ekleyip, yeniden eğitiyorum. Bu tekrarların ne kadar yarar sağlayacağını zaman gösterecek. Sonuçları yine burada, sizlerle paylaşacağım.

Veri kümesini eğitmek için kullandığım Python kodlarını daha önce paylaşmıştım: http://python.gurmezin.com/tensorflow-ile-acemi-siirler/. Orijinal kodlara, https://github.com/sherjilozair/char-rnn-tensorflow adresinden ulaşabilirsiniz.

Bu çalışmada Python 3.6.5 kullandım. Tensorflow sürümü 1.5.0. 6GB belleği olan GPU ile eğitim işlemi yaklaşık 15 dakika sürüyor.

Veri kümesini internet üzerinden rasgele derlediğim için, şimdilik paylaşmam mümkün değil. İleride, paylaşılabilecek bir veri kümesi oluşturma şansı elde edersem, elbette o veri kümesini sizlerle de paylaşacağım.

Soru, öneri ve eleştirileriniz için yorum alanını kullanabilirsiniz.

Tekrar görüşmek üzere,

Ahmet Aksoy

Ara 162017
 
Raspberry Pi ve Makine Öğrenmesi
1.076 kez okundu

Raspberry Pi ve Makine Öğrenmesi

Yeni bir startup olan Jetpac, görsel tanıma yazılımı Deepbelief’i farklı sistem ve cihazlar üzerinde kolayca kurulup kullanılabilir hale getirdi. Bu girişim, Raspberry Pi ve Makine Öğrenmesi açısından da önemli bir kazanım olacak gibi görünüyor.

DeepBelief sistemini Linux, iOS, OSX, Android, Raspberry Pi ve Javascript üzerinde kullanmak mümkün.

Bu yazımda DeepBelief’in Raspberry Pi üzerinde kurulumunu ve çalıştırılmasını ele alacağım.

Aynı konu http://www.instructables.com/id/Machine-learning-with-Raspberry-Pi/ adresinde işlenmiş. Ancak orada verilen direktifler benim kullandığım Raspberry Pi B+ v1.2 üzerinde biraz sorun yarattı. Ama bu sorunun çözümü de var.

Şimdi en başından başlayarak aşamalar halinde işlemlerimize geçelim:

1. Önce Raspi’ye bağlanalım: (Ben Ubuntu 16.04 üzerinde ssh komutuyla bağlanıyorum. Siz de kendi sisteminizin gerektirdiği şekilde veya cihazınıza klavye, fare ve ekran bağlayarak çalışabilirsiniz.)

Uzaktan bağlanabilmek için Raspinin IP numarasını bilmeniz gerekir. Bu amaçla

komutunu kullanabilirsiniz. sudo kullanırsanız, root yetkisiyle daha ayrıntılı bir rapor alırsınız.

2. GPU kullanımı için bellek tanımlama:

Dosyanın sonuna aşağıdaki satırı ekleyelim:

3. Bellekte yaptığımız değişikliğin sistem tarafından algılanması için cihazımızı yeniden başlatalım:

4. Raspinin kendini yeniden başlatması birkaç dakika sürebilir. Yeteri kadar bekledikten sonra yeniden bağlanalım.

5. Dosyalarımızı github üzerinden indireceğimiz için git uygulamasını kurmamız gerekiyor.

6. Artık DeepBeliefSDK dosyalarını indirip kurulumunu yapabiliriz.

7. Kurulumu yaptık. Sonucu denetlemek için örnek uygulamayı çalıştıralım:

Eğer herşey yolunda gittiyse 998 satırlık bir rapor elde edeceksiniz.

Ya da benim gibi “Can’t open device file: /var/lib/jpcnn/char_dev” mesajını alacaksınız. Bu hata mesajından kurtulmak için aşağıdaki komutları verin:

Artık uygulamamızı yeniden çalıştırabiliriz:

Elde edeceğimiz rapor resimdekine benzeyecektir.

Raspberry Pi ve Makine Öğrenmesi

deepbelief uygulaması, herhangi bir parametre verilmeden çalıştırıldığı zaman “lena.png” dosyasını varsayılan olarak yükler ve öntanımlı imagenet nesneleriyle karşılaştırarak benzerlik oranlarını bulur.

Raporda sıra no, benzerlik olasılığı ve nesne etiketi sıralanır.
En büyük olasılığa sahip olan görüntülerle eşleşme gerçekleşmiştir diyebiliriz.
Eğer sonuçları olasılık değerine göre sıralarsak, benzerlikleri yorumlamamız daha kolay olur.

İstediğiniz bir başka görseli taratmak isterseniz, adını parametre olarak vermek gerekir. Örneğin “cicek.jpg” dosyasını taratmak istediğimizde vereceğimiz komut şöyledir:

DeepBelief sistemini Ubuntu üzerinde kurmak çok daha kolay oluyor. Siz de kendi sisteminizde deneyin.

Ahmet Aksoy

Referanslar: