Haz 022019
 
2.131 kez okundu

Facebook wit.ai ile Sesten Yazıya

Son dönemdeki kitap çalışmalarım nedeniyle bu siteyi epeyce ihmal ettim. Umarım arayı kısa sürede kapatırız.
Yeni çalışmalarım, “Sesten Yazıya” ve “Yazıdan Sese” dönüşüm üzerine.
Bu yazımda Facebook’un denetimindeki wit.ai sitesi üzerinden sağlanan Sesten Yazıya çalışmasına bir örnek vereceğim. Bu hizmet tamamiyle ücretsiz.
Wit.ai gibi Google, Google Cloud, Microsoft Azure ve IBM tarafından sağlanan Sesten Yazıya çözümleme hizmetleri de bulunuyor.
Google ve Google Cloud belli kısıtlamalar içerse de uzun soluklu ve ücretsiz hizmetler sunuyor.
IBM ise “one month of inactivity” gibi bir kısıtlama koymuş. Benim yaptığım gibi deneme amaçlı bir hesap açar ve bu zamanı geçirirseniz, bir daha IBM ile -ücretsiz- çalışamıyorsunuz.
Benzer bir durum da Microsoft Azure için var. Sadece bir aylık ücretsiz üyelik sağlıyor. Daha sonra yapacağınız denemeler için ücret ödemek zorundasınız.
Eğer ticari olarak yararlanmayı düşünmüyorsanız IBM ve Microsoft dışındaki ücretsiz çözümler size daha cazip gelebilir.
Facebook – wit.ai bunlardan biri.
Öncelikle bu siteye üye olmanız ve bir hesap oluşturarak yeni bir API anahtarı almanız gerekiyor.
Gerekli işlemler şöyle:

1. https://wit.ai sitesine gir

https://wit.ai sitesine bağlan


2. Facebook veya Github üyeliğin üzerinden sisteme bağlan (ilgili butona tıkla)
3. Sayfanın sağ üst tarafındaki artı (+) işaretine tıklayarak yeni bir hesap oluştur
3.1. Hesaba bir isim ver (resimdeki deneme hesabı)
3.2. İkinci kutuya bir açıklama yaz
3.3. Language (dil) olarak Turkish seç
3.4 En alttaki “+ Create App” butonuna tıkla

Sayfanın sağ üst tarafındaki artı (+) işaretine tıklayarak yeni bir hesap oluştur

4. Sağ üst köşedeki “Settings” butonuna tıkla

Sağ üst köşedeki “Settings” butonuna tıkla

5. Bu sayfadaki “Server Access Token” değerini kopyala (API anahtarı olarak bu bilgi kullanılacak)
5.1 Gerekiyorsa Default Timezone ve Language değerlerini değiştir.

API anahtarı olarak Server Access Token değerini kopyala

6. Python projenin çalışma klasöründe witkeys_tr.py (veya benzeri) bir dosya oluştur
7. Bu dosyanın içine WIT_ACCESS_TOKEN= yaz ve eşit işaretinin sağ tarafına tırnak içinde 5. satırda elde ettiğin değeri yaz
8. Dosyayı kaydet

Şimdi de kullanacağımız betiği görelim:

Betiğimizde speech_recognition modülünü kullanıyoruz.
Bu modülü kurmak için vereceğimiz konsol komutu şudur:

Betiğimiz Python 3.6 için hazırlanmıştır ve Ubuntu 18.04, Windows 10 ve Mac OS Sierra üzerinde sorunsuz çalışmaktadır.

Ahmet Aksoy

Ara 182018
 
4.845 kez okundu

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

Önceki yazımda veri setimizi nasıl oluşturacağımızı anlatmıştım.

Bu kez veri setimizi Keras kullanarak eğiteceğiz. Sonra da yeni resimleri bu eğitilmiş veri setini kullanarak sınıflandıracağız.

3. ADIM – EĞİTİM

Projemize örnek olarak aldığımız çalışmada Adrian, Keras modellemesi için SmallerVGGNet sınıfını kullanıyor. Ben onun yerine daha basit bir model kullandım (vgg_like). Eğer isterseniz yazının sonundaki Referanslar bölümünde yer alan linkleri kullanarak SmallerVGGNet kodlarına ulaşabilirsiniz.

Lafı uzatmadan eğitim betiğimize geçelim. Betiğimizin adı: train.py

İşin içine eğitim girince bir sürü kütüphane ve modüle ihtiyaç duyuyoruz. Kullanacağımız kütüphaneler hakkında kabaca da olsa, bilgi sahibi olduğunuzu umuyorum. Yoksa bu yazıyı 1000-1500 kelimelik bir hacme sığdırmak olanaksız hale gelirdi.

İlk 27 satırımızda matplotlib, keras, sklearn, imutils, numpy, random, pickle, cv2 ve os kütüphanelerimizi içe aktarıyoruz. smallervggnet kütüphanesini de belki kullanırsınız diye listeden çıkarmadım.

Modeli daha basit tutmak amacıyla vgg_like() fonksiyonunu tanımladım. (VGGNet, 2014 yılındaki Imagenet Büyük Ölçekli Görsel Tanıma Yarışmasında çok iyi performans gösteren bir yapay sinir ağıdır. VGG (Visual Geometry Group) Oxford Üniversitesi Mühendislik Bilimleri Bölümünün bir alt birimidir.)

Eğitim için Doğrusal(Sequential) bir model kullanıyoruz – satır 30
Görsellerimiz 96×96 boyutlu ve 3 renk kanalına sahip.
Modelimize ilk önce bir Conv2D katmanı uyguluyoruz – satır 31
İkinci katmanımız yine Conv2D – satır 32
Üçüncü katmanda MaxPooling2D var – satır 33
34. satırdaki Dropout ile %25’lik giriş bilgisini devre dışı bırakıyoruz (overfitting engelleme).

Benzer işlemleri bir kez daha tekrarlıyoruz. Ama boyutlamalar biraz farklı. satır 36-39

Son aşamada modelimize önce Flatten(), sonra Dense() uyguluyoruz. satır 41-42
Dropout oranımız %50 satır 43
Son işlemimiz her zamanki gibi ‘softmax’ satır 44
45.satırda modelimizi geri döndürüyoruz.

47. satırda işlem başlangıç zamanını t0 olarak not ediyoruz. Bu değişkeni belirli aşamalarda geçen süreyi belirtmek için kullanacağız.

Satır 48-51’de sabitlerimizi tanımlıyoruz.

data ve labels boş birer listedir. satır 53-54

58. satırda görsel dosya yollarımızı bir listede topluyoruz (imagePaths).

imagePaths listesinin satırlarını karıştırırken, sonraki denemelerde de aynı rasgele değerleri elde edebilmek için seed değerini 42 olarak belirliyoruz. satır 60 (Bu değer herhangi bir başka sayı da olabilir. Önemli olan hep aynı başlatma değerini kullanmak.)

63. satırda görsel dosyalarını işlemeye başlıyoruz.
Dosyayı okuyoruz – satır 64
İmajı 96×96 olarak yeniden boyutlandırıyoruz – satır 65
İmajı bir dizi (array) haline dönüştürüyoruz – satır 66
Ve imaj dizisini data listesine ekliyoruz – satır 67

Dosya yolundan etiket bilgisini (sanatçı_kodu) ayrıştırıyoruz – satır 70
Etiket bilgisini labels listesine ekliyoruz – satır 71

data listesini elemanları 0 veya 1 olacak şekilde bir numpy dizisine çeviriyoruz – satır 75
Aynı şekilde labels listesini de bir numpy dizisi haline getiriyoruz – satır 76

Satır 81-82’de etiketleri sayısallaştırıyoruz.

Satır 85-86: data ve labels dizi elemanlarının %20’sini test, geri kalanını eğitim için ayırıyoruz.

Veri sayımız kısıtlı olduğu için data çoğullama (augmentation) işlemi yaptırıyoruz – satır 89-91 (Çoğullama sırasında döndürme, kaydırma, yükseklik değiştirme, kesme, büyütme ve yatay aynalama (flip) işlemleri yapılacak.)

Modelimizi vgg_like() fonksiyonu ile oluşturuyoruz – satır 99

model.summary(), model katmanlarımızın değişimini ayrıntılı bir şekilde açıklıyor. Bu özeti hem ekrana, hem de dosyaya kaydediyoruz. – satır 102-105

Optimizasyon işlemi için Adam da yaygın bir şekilde kullanılıyor. Benim yaptığım denemelerde SGD daha iyi sonuçlar almamı sağladı. Her ikisini de deneyebilirsiniz. Satır 108

110. satırda modelimizi derliyoruz.

Eğitim işlemleri (satır 116-120) için bir kaç dakika bekliyoruz.

Eğitim tamamlandığında, önce modelimizi (satır 124), sonra da etiketlerimizi (satır 128-130) kaydediyoruz.

Son aşama olarak, eğitim işlemlerimiz sırasında hesaplanan kayıp ve doğruluk değerlerini grafiğe döküyor ve plot.png adıyla kaydediyoruz. – satır 135-146

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

Artık sınıflandırma işlemlerimize geçebiliriz. Ama daha önce model özetimize kısaca bir göz atsak iyi olacak:

Conv2D katman çıkış boyutlarında 2 piksellik küçülme yaratıyor.
MaxPooling2D ise (2,2) oranları ile her iki yönde boyutları yarıya indiriyor.
Flatten işlemi katmanı tek boyutlu bir diziye dönüştürür.
Dropout input değerlerinden bir bölümünü işlem dışı bırakır. Böylece overfitting olasılığı azalır.

4. ADIM – SINIFLANDIRMA

Sınıflandırma işlemlerinde eğitim aşamasında kullanmadığımız görsellerden yararlanacağız. Her sanatçı için birer görsel seçtik ve bunları kontrol klasörünün altına kopyaladık.

İlk 7 satırda gerekli kütüphaneleri içeri aktarıyoruz.

imajlar listesi sınıflandıracağımız fotoğrafları tutuyor. satır 10

Sınıflandırma işlemlerini check_image() fonksiyonu ile yapacağız (satır 12). Her görsel ayrı ayrı işleme sokulacak.

Satır 13-16’da imajımızı 96×96 piksel boyutlarına küçültüyor ve modelimize uygun bir numpy dizisine dönüştürüyoruz.

Satır 19 ve 20’de eğitim sonunda kaydettiğimiz model ve etiket bilgilerini belleğe alıyoruz.

Modele göre bulunan tahmin ve olası doğruluk derecesini saptıyor; etiket değerini alıyoruz. satır 23-25

Sınıflandırma sonucunu genişliğini 400 pikselle sınırlandırdığımız imajımızın üzerine işliyoruz. satır 28-33

İşlenmiş imajı ekranda gösterip diske kaydettikten sonra bir tuşa basılmasını bekliyoruz. satır 35-38

Tuşa basıldığında belleği temizliyoruz: satır 39

check_image() fonksiyonumuzu her resim için ayrı ayrı çağıran döngümüz satır 42-45 arasında.

Elde ettiğim görüntüler aşağıda:

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

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

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

SmallerVGGNet kullanarak yaptığım denemelerde daha yüksek sayısal doğruluk oranlarına ulaştım ama, yapılan tahminlerin pek çoğu aslında hatalıydı. Bu, veri kümemizin çok dar olmasından kaynaklanmış olabilir.

Aynı eğitim setini yüz saptama fonksiyonlarıyla birlikte kullanarak grup fotoğraflarından çoklu yüz tanıma işlemleri gerçekleştirmek mümkün olabilir.

Açıklamalara böyle bir blog yazısında daha kapsamlı bir şekilde girmek mümkün olmuyor. Sorularınız varsa, yorum alanından iletebilirsiniz.

Bu tür çalışmalar çok geniş bir kapsama alanına sahip. Yapılan işlemler ve elde edilen sonuçlar deneysel nitelikte. Bu yüzden, bu tür konulara ilgi duyuyorsanız, siz de kendi modellerinizi geliştirin. Mümkünse veri kümeleri oluşturun. Deneyin. Yorumlayın.

Elbette hala öğrenecek çok şey var. Ama yapabileceğimiz şeyler de pek çok…

Önemli olan, hangi düzeyde olursak olalım, deneysel bakış açımızı yitirmemek ve hevesimizi kaybetmemek… Hata yapmak bizi korkutmasın. Hatalar, kullanmasını bilenler için en etkin yol göstericilerdir.

Yeni yazılarda buluşmak üzere…

Beni izlemeye devam edin.

Ahmet Aksoy

Referanslar:
https://github.com/kjaisingh/pokemon-classifier/blob/master/pyimagesearch/smallervggnet.py
https://www.pyimagesearch.com/2018/04/16/keras-and-convolutional-neural-networks-cnns/
https://hackernoon.com/learning-keras-by-implementing-vgg16-from-scratch-d036733f2d5
http://www.robots.ox.ac.uk/~vgg/research/very_deep/

Ara 172018
 
5.521 kez okundu

OpenCV ile Yüz Tanıma Bölüm 3-1

Bu yazımda 3 Yeşilçam emektarının fotoğraflarını içeren küçük bir veri setini oluşturmak için gerekli işlemleri ele alacağım. Eğitim ve sınıflandırma işlemleri ise bir sonraki yazımın konusu olacak.

OpenCV ile Yüz Tanıma Bölüm 3-1

Orijinal kodları yine PyimageSearch web sitesinden edinmek mümkün. Adrian, anime karakterleri kullanmış. Ben ise Yeşilçam karakterlerini tercih ettim. Ayrıca kodları biraz daha basitleştirdim ve gerekli yerlerini Türkçeleştirdim.

Veri seti için Google üzerinden ulaşabildiğim fotoğrafların sayısı hiç ummadığım kadar düşük çıktı. Oysa çok fazla fotoğrafa ulaşabileceğimi umuyordum. Bu proje için 3 sanatçımızın toplam 147 farklı fotoğrafına ulaşabildim. Sayının azlığına rağmen sınıflandırma değerleri fena değil.

Projemizde 4 ayrı betiğimiz var:
1- Dosyadaki linklerin okunup, ilgili imaj dosyalarının internetten indirilip kaydedilmesi
2- Kaydedilen dosyaların denetlenerek, içeriği aynı olan dosyaların teke düşürülmesi
3- Veri setinin eğitilmesi
4- Eğitilmiş veri seti bilgilerini kullanarak örnek dosyaların sınıflandırılması

VERİ SETİMİZİ OLUŞTURMAK

Sanatçılarımız: Türkan Şoray, Sadri Alışık ve Cüneyt Arkın. Amacım sadece çalışma yöntemini örneklemek olduğu için sayıyı daha fazla arttırmadım. Belki ileride, bu veri setini genişletip çok daha zengin ve işlevsel bir projeye dönüştürmek mümkün olabilir.

1. ADIM – VERİ SETİNİN OLUŞTURULMASI

İnternet üzerinden ulaştığım görsel linklerini, “linkler.txt” isimli bir metin dosyasına kaydettim. Bu dosyayı linkler.txt adresinden indirebilir veya tamamen kendiniz oluşturabilirsiniz.
Dosya yapısı şöyle:
sanatçı_kodu,link1
sanatçı_kodu,link2

Sanatçı kodları aynı zamanda data klasörünün içindeki klasörlerin de adlarıdır. O nedenle kodlarda Türkçe karakter kullanmadım. Kodlar ve klasör isimleri şu şekildedir:
c_arkin
s_alisik
t_soray

Betik kodlarını kısa tutmak için data klasörünü ve onun altındaki klasörleri kendim oluşturdum.

Çalışma klasörümüzün adı “yesilcam”. Alt dizin yapısı da şu şekilde:
yesilcam
|–data
| |–c_arkin
| |–s_alisik
| |–t_soray
|–kontrol
|–__pycache__

Önce ilk betiğimizi (resim_indir.py) inceleyelim:

skimage kütüphanesi, imaj dosyalarımızı doğrudan internet üzerinden okuyabilmek için gerekli. Ancak bu kütüphane RGB renk sistemini kullanıyor. Bu yüzden 22 nolu satır ile renk sistemini OpenCV’nin kullandığı BGR sistemine çeviriyoruz.

Linkleri tutan dosyamızın adı “linkler.txt”.

Sorunsuz okunan dosya sayısını tutmak için ok, sorunluları saymak içinse hata değişkenlerini kullanıyoruz.

kac sözlük değişkeni, her sanatçı için dosya isimlerini ayrı ayrı sayılaştırmamızı sağlıyor.

Satırları tek tek okuyoruz. # ile başlayan veya boyu 3 karakterden kısa olan satırları atlıyoruz.

İşlenecek satırları “,” ile parçalıyoruz. İlk parçada sanatçı kodu bulunuyor. Normalde ikinci parçanın link adresini tutması lazım. Ancak, sayıları az olsa da, bazı link adreslerinde “,” işaretinin kullanıldığına rastlayabiliriz. Bu nedenle -eğer varsa- 3. parçayı 2. parçaya ekleyerek doğru adresi elde ediyoruz.

17. satırda başlattığımız try bloğu, hatalı okumalardan kaçınmamızı sağlıyor.

kim değişkeni sanatçı kodunu, url ise imaj adresini saklıyor.

kac anahtarları içinde kim stringi yoksa, ilk kez tanımlanacak demektir. Başlangıç değeri olarak 1 atıyoruz.

21. satırda dosyamızı internet üzerinden okuyor; 2. satırda renk sistemini BGR haline çeviriyor ve 23. satırda okuduğumuz imajı görselleştiriyoruz.

24. satırdaki tuş kontrolü, gerektiğinde, Esc tuşuna basarak döngüyü kırabilmemizi sağlıyor. Bu satır aynı zamanda görselleştirme işlemleri için de gerekli.

27-36 satırlarını kullanarak dosyayı data klasörü altındaki sanatçı klasörüne (kim) kaydediyoruz. Dosya isimlendirmesinde bir çakışma olması ihtimalini dikkate alıyor, ama bu sayının 100’den fazla olmasına izin vermiyoruz. (Dikkat! Eğer kendi veri setinizi oluşturacaksanız, kullanacağınız link sayısını dikkate almak için bu sınırı değiştirmeniz gerekebilir.)

41. satırda son işlem olarak bilgisayar belleğini temizliyoruz.

İmajlar farklı boyutlarda olduğu için işlenmeleri farklı süreler gerektirebiliyor.

(Not: Çalışmalarımı Pycharm üzerinde yapıyor ve çalıştırıyorum. Ancak bu betiği terminal üzerinden çalıştırmak zorunda kaldım. Aynı durum sizin başınıza da gelebilir. Betiği çalıştırmak için Pycharm’ın terminal modunu kullanabilirsiniz.)

2. ADIM – İMAJ TEKRARLARININ ÖNLENMESİ

Bu betiğimizde doğrudan md5 hesaplamak yerine imagehash kütüphanesindeki dhash() metodunu uyguluyoruz. Bu metod hash hesabını imajları belli bir boyuta indirip gri renge çevirdikten sonra yapıyor. Yeniden boyutlandırma biraz zaman alıyor olsa da sonuçlar daha güvenilir.

İkinci betiğimizde os, PIL ve imagehash kütüphanelerini kullanıyoruz.

hash() fonksiyonumuzda okuma işlemini PIL.Image modülü ile gerçekleştiriyor ve elde edilen imaja imagehash.dhash() işlemini uyguluyoruz. (Doğrudan md5 hesabı yaptığımızda birbirine çok benzer bazı imajlar gözden kaçabiliyor.)

Tekrarlanan imaj dosyaları tekrar_sil() fonksiyonunun içinde temizleniyor.

19. satırda path değişkenimizle aktarılan klasör yolu bir döngü yapısı içinde kök, klasör ve dosya bileşenlerine ayrıştırılıyor ve her bir dosya için hash() değeri hesaplanıp, hash_dict sözlük değişkeninde saklanıyor. Eğer eşdeğer hash değeri (key) bulunursa, aynı anahtarın karşılığına mükerrer dosyanın adı ekleniyor. Böylece len(hash_dict[k]) değeri birden büyük olan kayıtlar, mükerrer dosyaları tutuyor.

25-30 satırları mükerrer dosyaların silinmesini sağlıyor.

34. satırda data klasörünü işleme sokuyoruz. Böylece onun altındaki tüm klasör ve dosyaları taramış oluyoruz.

Sizi daha fazla yormamak ve veri setini hazırlamanız zaman tanımak için bu yazıyı burada kesiyorum. Bir sonraki yazımda, oluşturduğumuz veri setini önce eğiteceğiz, sonra da eğitim setinde yer almayan kontrol görsellerinin kime ait olduğunu sorgulayacağız.

Beni izlemeye devam edin.

Ahmet Aksoy

Referanslar:

https://www.pyimagesearch.com/

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

Ara 062018
 
12.640 kez okundu

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

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

Yüz tanıma biraz geniş kapsamlı bir konu. Öncelikle incelediğimiz görselde bulunan olası “yüz”leri, daha sonra da gerekiyorsa bu yüzlerin “kim”e ait olduğunu saptamak sözkonusu. Ya da yüzlerin üzerindeki yüz, göz, kaş, burun, kulak gibi elemanların (facial features) belirlenmesi… O yüzden bu konuyu tek bir yazıyla değil, ardışık birkaç yazıyla ele alacağım.

İlk bölümde bir fotoğraf karesinde kaç adet “yüz” bulunduğunu saptayacağız.

Çeşitli beden parçalarını filtre etmek amacıyla kullanılan en yaygın araçlardan biri “haar cascade” sınıflandırıcılarıdır. Yazının sonunda bu “.xml” uzantılı dosyalara ulaşabileceğiniz çeşitli linkler bulacaksınız. Hatta isterseniz, kendi sınıflandırıcılarınızı bile eğitebilirsiniz. (Ben şimdilik bu maceraya kalkışmıyorum. Elde yeterince hazır kaynak var.)

Ele alacağımız “face_count.py” betiğindeki temel filtremiz “haarcascade_frontalface_default.xml”. Bu filtre genellikle çok verimli çalışıyor. Ancak imaj boyutları yeterince büyük değilse bazı hatalı (false positive) sonuçlar döndürebiliyor. Bu sorunu kısmen de olsa aşabilmek için “it_contains_eyes()” isimli bir fonksiyon tanımladım. Bu fonksiyon saptanan yüz alanının içinde göz, burun veya dudak olup olmadığını araştırıyor. Bulamazsa, yüz bulgusunun hatalı olduğunu geriye “False” döndürerek bildiriyor.

Ben 3 ayrı fotoğrafı döngü içinde test ettirdim. Siz de kendi istediğiniz fotoğrafları kullanabilirsiniz.

Orijinal koda ilave ettiğim bir değişiklik de UTF-8 fontlarını destekleyen Pillow kütüphanesini kullanarak hazırladığım print_utf8_text() fonksiyonudur. Böylece Türkçe karakterleri bastırmak da mümkün. OpenCV’nin putText() fonksiyonu sadece ASCII fontları destekliyor. Bu nedenle Türkçe karakterler basılamıyor.

Kodların içinde İngilizce açıklamalar kullandım. Çünkü bu seri tamamlandığında github üzerinden ve İngilizce olarak paylaşmayı düşünüyorum. İngilizce bilmeyen arkadaşlar zaten buradaki yazılardan aynı açıklamaları fazlasıyla edinebilecekler.

Gelelim kodlarımızın açıklamalarına:

Betiğimizde numpy ve cv2 yanında PIL kütüphanesini de kullanacağız. Böylece UTF-8 destekli FreeType fontları üzerinden Türkçe karakterli mesajları da basabileceğiz.

“haarcascade” dosyalarını “Cascades” isimli klasörün altında topladım. Bu betikte 4 farklı sınıflandırıcı kullanacağız. Sırasıyla yüz (cepheden), göz, gülümseme (dudak) ve burun.

“nocheck” değişkeni True olursa, fazladan göz, dudak ve burun kontrolü yapılmaması için it_contains_eyes() fonksiyonu işlem yapmadan True döndürerek devre dışı kalacaktır. Bu değer False olursa, ek kontrollerin yapılmasına izin veriliyor demektir.

OpenCV string basımı için putText() metodunu kullanıyor. Bu metodun kullanabildiği HERSHEY fontları sadece ASCII karakterleri destekliyor. Eğer sadece İngilizce veya ASCII karakterler içeren mesajlar kullanacaksanız print_text() fonksiyonu size yetecektir.

OpenCV doğrudan UTF-8 desteklemediği için Pillow kütüphanesini devreye sokarak FreeType fontlarını kullanabiliyoruz.
Örnekte ‘FreeSerif.ttf’ fontunu kullandım. Siz bir başka fontu tercih edebilirsiniz.
ImageFont.truetype() metodu ile font adını ve boyutunu belirliyoruz.
OpenCV ve Pillow farklı imaj sistemleri kullanıyor. Image.fromarray() metodunu kullanarak OpenCV formatlı imajı Pillow sistemine uygun biçime dönüştürüyoruz. Sonra da bu imajı bir Draw() nesnesi haline çevirip, text mesajımızı da bu nesnenin draw.text() metoduyla görüntünün üzerine işliyoruz.
Son aşamada işlenmiş görüntüyü yine bir numpy.array() biçimine dönüştürerek OpenCV’nin kullandığı formata aktarıyoruz. Fonksiyonumuz, üzerine text mesajı işlenmiş görüntüyü geri döndürüyor.

Eğer no_check değişkenimiz True değerine sahipse, it_contains_eys() fonksiyonumuz başka bir işlem yapmadan True değeri döndürür. Böylece ek kontrol yapılmaz.
Aksi halde önce roi_gray tanımlanır. Bu, “yüz” olarak tesbit edilen dikdörtgen yüzeydir.
İlk kontrol olarak bu alanın içindeki olası “göz”ler araştırılır. Parametreler deneyseldir. Çalışmanız için en uygun değerleri deneyerek bulmanız gerekebilir.
41-45 satırları arasında göz sayısını buluyor, bu sayı sıfırdan büyükse True değeri döndürerek geri dönüyoruz. Aynı satırları if len(eyes)>0: return True olarak kısaltmak da mümkün.
Diğer smiles (gülümseme-dudak) ve noses (burun) kontrolleri de aynı mantıkla çalışıyor.
Bu fonksiyonun temel amacı şudur: Bir yüzün içinde en azından 2 göz, bir dudak veya bir burun olmalıdır. Eğer hiçbiri yoksa, yüz hatalı saptanmıştır.

Ben bu betikte 3 ayrı imaj kullandım. İlk başta scaleFactor=1.5, minNeighbors=5, minSize(20,20) kullandım. Daha sonra deneme-yanılma yöntemiyle yukarıdaki değerlere ulaştım. Siz de deneyin.
Döngü içinde isimlerini verdiğim imaj dosyaları sırayla okunup image değişkenine atanıyor. Buradan da görüntünün gri bir kopyası oluşturuluyor. Gri görüntüler üzerinde sayısal işlem yapmak çok daha hızlı sonuçlar veriyor.
faceCascade.detectMultiScale(grayImage) metodu bize imaj içinde bulduğu yüz koordinatlarını veriyor (sol üst köşe x, sol üst köşe y, genişlik ve yükseklik). Konsol ekranına type(faces) değerini bastırıyoruz.

Eğer faces içinde hiç bilgi yoksa, görüntü üzerinde hiç yüz bulunamadı demektir. Bunu “Yüz bulunamadı” mesajıyla raporluyoruz.
Eğer faces içinde yüz koordinatları mevcutsa, -bilgi için- bulunan koordinatlar ile eleman boyutunu ve bu bilgiyi kullanarak ek filtre uygulanmamış yüz sayısını konsol ekranına bastırıyoruz.
Bulunan dikdörtgenlere it_contains_eyes() fonksiyonu ile ek denetimleri uyguluyoruz. Denetim atlanıyorsa veya aranan ek bilgiler bulunduysa o dikdörtgenin kenarlarını görüntünün üzerine çiziyor ve bulunan yüz sayısını tutan count değişkeninin değerini bir arttırıyoruz.
Tüm yüzler tarandıktan sonra “Belirlenen yüz sayısı: ” mesajımızın kolay görünebilir olması için altına beyaz bir zemin bastırıyoruz. (satır 88)
90-92 satırlarında bulunan yüz sayısını ifade eden mesajımız görüntünün üzerine işleniyor ve 94 numaralı satırda sonucu görüntülüyoruz.
Eğer UTF-8 yerine sadece ASCII fontlar kullanacaksanız 89 nolu satırı aktif hale getirip 90-92 satırlarını devre dışı bırakmanız yeterlidir.
Döngünün devam etmesi için herhangi bir tuşa basmamız gerek.
Tuşa bastığımızda ortalığı temizliyor ve varsa bir sonraki imaja geçiyoruz. Yeni imaj yoksa döngüyü ve betiği sonlandırıyoruz.

Tüm kodlar bir bütün olarak aşağıda:

Betiğin çalışmasını aşağıdaki videodan izleyebilirsiniz:

Bir sonraki yazımda kişi yüzlerini ismen tanıyan bir sistemi nasıl eğiteceğimizi ele alacağım.

Ahmet Aksoy

https://techtutorialsx.com/2017/05/02/python-opencv-face-detection-and-counting/
https://github.com/voidstellar/haar-cascade-files
https://github.com/opencv/opencv/tree/master/data/haarcascades
http://alereimondo.no-ip.org/OpenCV/34
https://www.instructables.com/id/Create-OpenCV-Image-Classifiers-Using-Python/
https://medium.com/@a5730051/train-dataset-to-xml-file-for-cascade-classifier-opencv-43a692b74bfe

Ara 032018
 
7.077 kez okundu

OpenCV ile Portakalın Peşinde

OpenCV ile Portakalın Peşinde

Bu yazımda bir önceki yazımda ele aldığım kodlardan yararlanacak, sadece bir kaç küçük değişiklik yapacağım.
Bu kez çember içine alarak işaretlediğimiz nesnenin (portakalın) merkez noktasını izlenebilir hale getireceğiz. İzlemeyi, en son ardışık 50 merkez noktasını çizgilerle birbirine birleştirerek yapacağız.

Bu betikte 2 kütüphaneye daha gereksinim var: collections ve numpy.

collections kütüphanesinin deque sınıfı her iki ucundan eleman eklenebilen ve önceden belirtilmişse maksimum eleman saısı sabit kalan nesneler üretir. Numpy kütüphanesini ise izleme çizgilerinin kalınlığını hesaplarken karekök almada kullanacağız. Onun yerine math kütüphanesini de kullanabilirdik ama, bu tür çalışmalarda numpy‘yi el altında tutmamızda büyük yarar var.

Bu kez kaynak kodları bir bütün halinde vereceğim. Sadece önceki örnekle karşılaştırdığımızda değişen satırları açıklamam yeterli olacak.

Kodlar aşağıda. Açıklamaları da onun altına ekledim.

3 ve 4 numaralı satırlarımızda yeni kütüphaneleri içe aktarıyoruz.

7. satırdaki WIDTH değerini 800 yaptım. Çünkü bu kez sadece bir pencereyi görselleştireceğiz.

8. satırda NO_OF_POINTS = 50 satırını ekledim. Bu sabit, merkez noktalarından kaç tanesini izleyeceğimizi belirliyor. Sayıyı azaltırsak izleme çizgilerimiz daha kısa, çoğaltırsak daha uzun olacaktır.

9. satırdaki ONLY_MAX artık kullanılmayacak. Çünkü sadece tek bir nesneyi (en büyük olanı) izleyeceğiz.

36. satıra kadar bir değişiklik yok. Burada frame isimli çerçevenin görüntüsünü cv2.GaussianBlur() metoduyla yumuşatıyoruz. Bu sayede görüntülerdeki renk dağılımları çok keskin hatlar oluşturmuyor. Aslında bizim örneğimizde bu metodu kullanmasak da olur.

46. satırda center değişkenini tanımlıyoruz. Bu değişken her görüntü karesinde yakalanan en büyük çemberin merkez noktasını tutacak.

49. satırdaki cmax değişeni en büyük alana sahip kontur değerlerini tutuyor.

51. satırda cmax’ı içine alan en küçük çembere ait merkez ve yarıçap bilgilerini buluyoruz.

52 ve 53. satırlarda şeklimizin ağırlık merkezini hesaplatıyoruz. Aslında bunun yerine center = (int(x),int(y)) kullansak da pek bir şey değişmeyecektir. Deneyebilirsiniz.

57-63 arası satırlarda yeni merkez noktamızı pts’ye ilk eleman olarak ekliyoruz. Böylece tüm elemanlar birer sıra sağ kayıyor ve en sondaki eleman siliniyor.

62. satırdaki thickness hesabı, çizgi kalınlığının, konumuna bağlı olarak değişmesini sağlıyor. Olayı basitleştirmek istersek onun yerine thickness=3 gibi bir satır kullanabiliriz. Elbette bu durumda çizgilerimizin kalınlığı sabit olur.

Son değişikliğimiz, 67.satırı devre dışı bırakmak. Böylece mask çerçevesini görünmez yapıyoruz.

Videoda kodların çalışır halini görebilirsiniz.

Bu yazıyı daha fazla uzatmayacağım. Çünkü ana fikirde bir önceki örneğimize göre önemli bir değişiklik yok. Ama istersek eğlenmek için bazı değişklikler yapabiliriz.

Örneğin ben cizgi kalınlıklarını biraz abartıp, rengini de kırmızı yaptım. Aşağıdaki videoda bu değişikliği görebilirsiniz. Siz de pts (deque) eleman sayısını azaltabilir veya çoğaltabilir, çizgi renkleriyle oynayabilirsiniz. Ya da renk aralıklarını değiştirerek farklı nesneleri izleyebilir veya web kamera yerine bir video dosyası kullanabilirsiniz (elinizde uygun bir video varsa).

Bir sonraki yazımda yüz tanıma konusunu yeniden ele alacağım.

Beni izlemeye devam edin.

Ahmet Aksoy

Ara 022018
 
6.777 kez okundu

OpenCV ile Portakallar ve Elmalar

OpenCV ile Portakallar ve Elmalar
Bu yazıda işleyeceğim kodların orijinal halini yine PyImageSearch sitesinde bulabilirsiniz. “ball tracking pyimagesearch” sözcüklerini Google’da aratırsanız, konuyla ilgili sayfalara kolayca ulaşırsınız.

Orijinal kodlarda izlediğimiz yuvarlağın (renkli topun) merkez noktasına ait koordinatlardaki değişimler görsel olarak izlenebiliyor. Benim aşağıda vereceğim kodlarda ise merkez noktası yerine, belirlediğimiz renk aralığının grileştirilerek maskelenmiş izdüşümünü ikinci çerçeveden izleyeceğiz.

(Not: Bir sonraki yazımda merkez noktalarının izlenmesi konusunu da ele alacağım. Ama dilerseniz bu kodları geliştirmeyi şimdiden bir ödev olarak üstlenebilirsiniz.)

OpenCV ile nesneleri izlemede kullanılan en basit yöntem, HSV renk sistemine uygun bir renk aralığını kullanmaktır. Çünkü HSV renk sistemi bu tür bir çalışmaya RGB veya BGR renk sistemlerine kıyasla çok daha yatkındır. Eğer renk sistemleriyle ilgili daha çok ayrıntıya ulaşmak isterseniz, internetteki pek çok kaynak size yardımcı olacaktır.

HSV terimi (Hue Saturation Value) sözcüklerinin ilk harflerini birleştirerek oluşturulmuştur. Hue renk tonlarını, saturation doygunluk oranını ve value parlaklık düzeyini ifade eder. OpenCV kütüphanesinde hue değerleri 0-179, diğerleri 0-255 arası değerler alır.

Şimdi kodlarımızı incelemeye başlayalım:

Örnek kodumuz için sadece cv2 ve imutils kütüphanelerini kullanacağız.

Web kamera görüntülerini kullanmak istiyorsak video_file string değeri boş olmalıdır. Eğer buraya bir video dosyasının erişim adresini yazarsak, web kamera yerine o videonun görüntüleri kullanılır.

WIDTH sabiti, pencerelerimizin genişliğini belirler. İstediğimiz gibi değiştirebiliriz.

ONLY_MAX sabiti False olarak tanımlanırsa, bulunan tüm sınır çizgileri (kontur) dikkate alınır. Bu değer True olarak verilirse, sadece alanı en büyük olan nesnenin çevre çizgisi çizilir.

Renk aralıkları için farklı opsiyonlar tanımladım. Kodu çalıştırmadan önce istediğiniz aralığı seçebilirsiniz. Örneğin YELLOW_RANGE aralığını kullanırsanız alt HSV değerler (10,100,100), üst değerler ise (40,255,255) olur.

video_file değişkenimizin uzunluğu sıfıra eşitse, içinde bir dosya adı yok demektir. Bu durumda web kamerayı etkinleştiriyoruz. İlk web kameranın karşılığı “0”dır. İkinci bir kamera tanımlarsanız, değeri “1” olur.

Örneğimizde yanyana 2 farklı pencere açacağız: frame ve mask. “mask” penceresi, “frame” penceresinin tam sağında yer alacak. Eğer bu yerleştirmeyi yapmazsak, pencereler üst üste açılacak; ikisini birden izleyebilmek için fare ile yerleşimi düzenlemek zorunda kalacaktık. (Not: cv2.moveWindow() parametreleri için kendi bilgisayarınızda biraz farklı değerler vermeniz gerekebilir.)

Ön tanımlarımızı yaptıktan ve pencere yerleşimlerini belirledikten sonra asıl işlemlerin içinde yer aldığı sonsuz döngüyü başlatıyoruz.

kamera.read() komutu, web kamera veya video dosyasından hangisini belirlediysek oradan bir çerçeveyi okuyor. Eğer ok değeri False ise ve dosya adı tanımlanmış ise okunacak çerçeve kalmadı demektir. Bu yüzden break komutuyla döngüyü sonlandırırız. Aksi halde işlenmesi gereken bir çerçeve okundu demektir.

Çerçeve boyutlarımızı WIDTH sabitine göre yeniden düzenledikten sonra frame isimli çerçevemizi HSV renk sistemine göre dönüştürüp, hsv isimli değişkene atarız. “frame” isimli çerçevemizin renk sistemi BGR’dir.

hsv isimli çerçeveden colorLower ve colorUpper renk değerlerine göre filtrelenen yeni çerçeveyi bu kez mask değişkenine atarız. Bu çerçeveye önce erode(), sonra da dilate() metodlarını uyguladıktan sonra bir de kopyasını alıp, çerçeve içinde yer alan nesne kenar çizgilerini (konturları) belirlemede kullanmak üzere mask_copy değişkenine atarız. (Not: erode() ve dilate() metodlarını kullanmadan önce mask çerçevemize GaussianBlur() metodu uygulayarak görüntüyü yumuşatmak daha güzel bir görsel etki yaratabilir. Bir sonraki yazımda bu metodu da örnekleyeceğim.)

contours listesi çerçevemizde yer alan tüm konturları içerir.

Eğer kontur listesi boş değilse, hepsini tek tek işleme sokarız.

ONLY_MAX sabitimiz True olarak tanımlandıysa her çerçevede sadece bir tek (en büyük) kontur belirlenir. Aksi halde yarıçapı 40 pikselden büyük olan tüm çemberleri kullanacağız demektir.

Konturlarımızı circle() metoduyla frame isimli çerçevemize işledikten sonra hem orijinal frame isimli çerçevemizi, hem de mask çerçevemizi görüntüleriz.

waitKey() metodumuz 4 milisaniyelik bir süre içinde basılacak tuşları dinler. Eğer ‘q’ veya ‘Esc’ tuşlarından birine basılmışsa, döngünün kırılmasını sağlar.

Döngü kırıldığında kamera nesnesini serbest bırakır ve açılmış tüm pencereleri kapatarak belleği temizleriz.

Örnek kodumuzun tamamı aşağıda:

Videoda kodların nasıl çalıştığı örnekleniyor. Tenis topu yerine elma ve portakal kullandım. Siz de isterseniz sarı renkler içeren başka nesneler kullanabilirsiniz.

mask çerçevesini görselleştirmek yerine sadece asıl çerçevedeki alanın veya alanların çember ile işaretlenmesini kullanabilir; ya da yakaladığımız nesnenin merkez koordinatlarındaki değişimi izlenebilir hale getirebiliriz.

Bu işlem için kendiniz doğrudan uğraşabilir ya da PyImageSearch sitesindeki örnekten veya benzer başka örneklerden yararlanabilirsiniz. (Bir sonraki yazımda bu konuyu ele alacağım.)

Yeni yazılarımdan anında haberdar olmak isterseniz sitemize abone olun.

Ahmet Aksoy

Kas 282018
 
OpenCV Kurulumu
4.001 kez okundu

OpenCV Kurulumu

OpenCV Kurulumu

Bu yazımda Ubuntu 18.04 üzerinde OpenCV kurulumunu ele alacağım. Kurulum bir sanal ortam üzerinde gerçekleşecek. Böylelikle farklı paketler arasında uyumsuzluk yaşama olasılığını en aza indirgeyeceğiz.

İşe, sistemimize virtualenv kurmakla başlayalım:

Aşağıdaki satırları ~/.bashrc dosyasına ekle ve dosyayı kaydedip çık.

Virtualenv paketinin kurulumunu böylece tamamlamış olduk.

Şimdi “ocv” isimli sanal sistemimizi tanımlayalım ve onun üzerine OpenCV’yi kuralım:

Yaptığımız kurulum işlemlerini doğrulayalım:

Sizin yaptığınız kurulumun OpenCV sürüm numarası farklı olabilir. Ama herhangi bir hata mesajı almamış olmalısınız.
Terminalinizdeki görüntü aşağıdakine benzemelidir:
OpenCV Kurulumu

Kurulumu kaynak kodlarını kullanarak yapmak mümkün. Ama bu konuyu uzatmak istemiyorum.

https://linuxize.com/post/how-to-install-opencv-on-ubuntu-18-04/ adresinde gerekli tüm ayrıntıları “Install OpenCV from source” başlığı altında bulabilirsiniz.

Şimdi önceki yazımda verdiğim küçük örneği biraz daha basitleştirerek denetleyelim.

Ben metin editörü olarak gedit kullanmayı tercih ediyorum. Siz de kendi tercihinizi kullanarak kodlayabilirsiniz. Dosyamızın adını “kamerakontrol.py” koyalım.

İlk komutlarımızı vermek için yeni bir komut penceresi açalım:

Aşağıdaki satırları “kamerakontrol.py” dosyasına yazıp kaydedelim.

Şimdi betiğimizi çalıştıralım:

Eğer web kameranız açıksa, şimdi ekrandan kendinize bakıyor olmalısınız.

“q” veya “Esc” tuşlarına basarak betiği durdurun.

Herhangi bir hata mesajı almadıysanız, komut pencereniz aşağıdaki gibi görünecektir:

OpenCV Kurulumu

Artık “ocv” sanal ortamını etkinleştirdiğinizde, OpenCV betiklerinizi istediğiniz gibi çalıştırabilirsiniz. Sanal ortamdan çıkmak istediğiniz zaman deactivate komutu vermeniz yeterlidir.

Gördüğünüz gibi, OpenCV Kurulumu oldukça kolay bir işlemdir.

Soru veya yorumlarınız için aşağıdaki yorum alanını kullanabilirsiniz.

Beni izlemeye devam edin.

Ahmet Aksoy

Kas 272018
 
3.499 kez okundu

OpenCV ile Yüz Saptama

opencv ile yüz saptamaBir önceki -ilk- yazımı tasarlarken bir “yüz saptama” (face detection) örneği vermeyi planlamıştım. Ama sonra fikrimi değiştirip, daha basit bir örnekle yetindim.

Oysa şimdi görüyorum ki, bu yazıları okuyan/okuyacak bir çok arkadaş için o yazı biraz basit kalmış olabilir.

O yüzden “yüz saptama” kodlarını da hemen paylaşayım istedim.

Bu amaçla cv2.CascadeClassifier() metodunun kullanacağı haarcascade_frontalface_default.xml dosyasına ihtiyacımız olacak. Bu dosyayı https://github.com/opencv/opencv/tree/master/data/haarcascades adresinden indirebilirsiniz. Aynı adreste sadece “yüz saptama” değil, pek çok beden parçasını tanımaya yönelik dosya mevcut. Gerek duyduğunuzda onları da bu adresten indirebilirsiniz.

Şimdilik sadece haarcascade_frontalface_default.xml dosyasını indirip, çalışma klasörümüzün içinde oluşturacağımız Cascades isimli klasöre kopyalayalım.

Yeni kodlarımız aşağıda. (Orijinal kodları https://www.hackster.io/mjrobot/real-time-face-recognition-an-end-to-end-project-a10826 adresinde bulabilirsiniz.)

Kodlarımızın büyük bölümünü bir önceki yazımda paylaşmıştım.

Öncelikle yeni indirdiğimiz dosyayı kullanıyor ve oluşan nesneyi faceCascade değişkenine atıyoruz.

Görüntümüz yine öntanımlı webcam üzerinden geliyor ve bu görüntüyü 640×480 olarak yeniden boyutlandırıyoruz.

Sonsuz döngümüzün içinde her görüntü karesini img değişkenine aktarıyor, sonra bu görüntünün gri bir kopyasını oluşturarak gray değişkeninde saklıyoruz.

Grileştirme, “kenar saptama” (edge detection) gibi işlemleri kolaylaştıran bir yaklaşımdır. İşlenecek veri miktarını azaltarak değişim hızının artmasını sağlar.

Görüntümüzün içinde birden fazla “yüz” olabilir. faceCascade.detectMultiScale() metoduyla yakaladığımız tüm yüzleri faces değişkeninde saklıyor ve bu yüzlere ait kareleri bir döngü içinde görüntümüzün üzerine işliyoruz.

Dikkat ederseniz, yüz bilgileri (x,y,w,h) şeklinde dönüyor. Yani sol üst köşenin koordinatları (x,y), genişlik w ve yükseklik h.

İstersek aynı işlemleri gray görüntümüze de uygulayabiliriz. (İlgili satırlardaki # işaretlerini kaldırmanız yeterlidir. Böylece hem renkli, hem de gri görüntülerimiz olur.)

Sonsuz döngümüz yine ‘Esc’ veya ‘q’ butonlarına basıldığında kırılıyor.

Döngü kırıldığında “cap” nesnesini serbest bırakıyor ve belleği temizliyoruz.

Peki sadece webcam ile çalışmamız zorunlu mu?

Elbette hayır!

Görüntüleri bir video dosyasından da alabiliriz. Sadece aşağıdaki gibi bir değişiklik yapmak yeterlidir:

Kullanacağınız video dosyasını ya çalışma klasörüne koyun, ya da tam adresini vermeyi unutmayın.

Bu yazıyı araya sıkıştırdım. O yüzden de “kurulum” bilgilerini bir sonraki yazıya ötelemiş oldum.

Beni izlemeye devam edin.

Ahmet Aksoy

Kas 272018
 
5.965 kez okundu

OpenCV ile Dünyayı Yeniden Keşfetmek

OpenCVOpenCV kütüphanesi’ni 1999 yılında Intel’den Gary Bradsky başlattı ve ilk sürümü 2000 yılında yayınlandı. Daha sonra bu çalışmalara Vadim Pisarevsky de katıldı. Halen OpenCV’nin Bilgisayar Görmesi ve Makina Öğrenmesi çalışmalarına yönelik desteği artarak devam etmektedir. (1)

OpenCV kütüphanesi hem C++, Python ve Java gibi dilleri; hem de Linux, Windows, OS X, Android ve iOS gibi platformları desteklemektedir. Kütüphane çalışmaları açık kaynaklıdır ve https://www.opencv.org/ sitesi üzerinden paylaşılmaktadır. Son sürüm OpenCV 4.0, 20 Kasım 2018 tarihinde duyurulmuştur.

Kütüphane ile ilgili daha ayrıntılı bilgilere ulaşmak isterseniz, kendi sitesine bir göz atmanızda yarar görüyorum.

Söz konusu kütüphanenin pratik kullanımına yönelik güzel örnekler paylaşan bir site daha var: https://www.pyimagesearch.com/ Her ne kadar arka planda kitap ve kurs pazarlaması bulunsa da, açık şekilde paylaşılan kod ve açıklamaları mutlaka izlemenizi öneririm. Olanaklarınız elveriyorsa Adrian Rosebrock’un kitaplarını almayı, ya da online kurslarına katılmayı düşünebilirsiniz. Elbette bunun için yeterli düzeyde İngilizce bilgisine ihtiyacınız olacak.

Bu ve izleyen bazı yazılarımda PyImageSearch veya benzer siteler tarafından paylaşılan kimi kodları temel alan bazı çalışmalar yayınlamayı düşünüyorum. Bu çalışmaları test ettiğim bilgisayarımda Ubuntu 18.04 işletim sistemi yüklü. Python sürümü 3.6. GPU destekli Tensorflow kurulumundaki sorunları aşmak için gerektiğinde Anaconda da kullanıyorum. IDE sistemim: güncel Pycharm Community sürümü. Örneklerde kullandığım OpenCV sürümü 3.4.3.

Adrian Rosebrock, betiklerinde komut modunu kullanmayı seviyor. Bense parametreleri dışarıdan vermek yerine betiğin içine gömmeyi daha fazla tercih ediyorum. Ayrıca, çok mecbur kalmadıkça ekrana print ettirdiğim ifadelerde geçen Türkçe karakterlerin “olması gerektiği gibi” görünmesini de önemsiyorum.

Lafı daha fazla uzatmadan ilk örneğimizi kodlayalım. Bu örnek bir başka siteden: https://www.hackster.io/mjrobot/real-time-face-recognition-an-end-to-end-project-a10826

Betiğimiz webcam görüntülerini tarayıp ekrana yansıtmaktadır.

cap = cv2.VideoCapture(0) satırı, varsayılan webcam cihazını aktif hale getirerek, görüntüleri yakalamasını sağlamaktadır.

cap.set() metodu ile görüntünün en ve yükseklik değerleri belirleniyor.

Sonsuz while döngümüzün içinde görüntü yakalama işlemi cap.read() metodu tarafından gerçekleştirilmekte ve “frame” değişkenine aktarılmaktadır. “ret” değeri okuma işleminin başarılı olup olmadığını saptamaktadır.

cv2.flip() metodu, webcam görüntünüz tepetaklak ise işe yarayacaktır. Eğer webcam görüntünüz normalse, bu satırı -benim yaptığım gibi- devre dışı bırakmanız gerekir.

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) satırı ile “frame” görüntüsünü “GRİ” renge çeviriyoruz.

cv2.COLOR_BGRGRAY parametresindeki “BGR” harfleri (B)lue-(G)reen-(R)ed (mavi-yeşil-kırmızı) kelimelerinden türetilmiştir. OpenCV RGB yerine BGR renk sistemini kullanmaktadır.

cv2.imshow() metodu imajları görünür hale getirmek için kullanılır. “frame” ve “gray” imajlarını ayrı ayrı görselleştiriyoruz.

OpenCV sisteminde olay yakalama mekanizması cv2.waitkey() metodu ile başlatılır. Bu metod kullanılmazsa ne görüntüleme, ne de tuş yakalama olayları gerçekleşebilir.

Döngüyü kırmak için ‘Esc’ veya ‘q’ tuşlarını tanımlıyoruz. Bu tuşlardan herhangi biri tıklandığında döngümüz kırılıyor; cap nesnesi sebest bırakılıyor ve oluşturulan tüm pencereler bellekten temizleniyor.

Eğer istersek görüntü karelerini webcam cihazımız yerine herhangi bir video dosyasından da aynı şekilde okuyabiliriz. Sonraki yazılarımda bu tür örnekleri de ele alacağım.

Örnek betiğimizden gördüğümüz gibi, OpenCV işlerimizi olağanüstü derecede kolaylaştırmaktadır.

Bu kütüphaneyi bir PC veya dizüstü üzerinde olduğu gibi, Raspberry Pi gibi mikro bilgisayarlar üzerinde de çalıştırabilmekteyiz. Bu konuyu da daha sonra ele alacağım.

Eğer bilgisayarınızda OpenCV zaten kuruluysa, örneğimizi de kolayca çalıştırmış olmalısınız.

Ama bu kütüphaneyi ilk kez kuracaksanız, işiniz o kadar kolay olmayabilir. Çünkü bu kütüphane çok geniş bir alana el attığı için pek çok başka kütüphanenin varlığına ihtiyaç duyar. Öncelikle bu kütüphanelerin kurulup hazır hale getirilmesi gerekiyor.

Bu yazıyı daha fazla uzatmamak için OpenCV kurulumunu bir sonraki yazımda ele alacağım.

Beni izlemeye devam edin.

Ahmet Aksoy

(1) – https://docs.opencv.org/3.4/d0/de3/tutorial_py_intro.html

  tarafından 12:12 itibariyle gönderildi.