Merhaba, bugünkü yazımızda python ile yüz okumayı ve tanımayı anlatmaya çalışacağım. Bunun için bir takım kütüphanelere ihtiyacımız olacak. Önce bu kütüphaneleri tanıyalım.
numpy:
NumPy, numerical python, oldukça büyük bir bilimsel işlem kütüphanesidir. Mantıktan cebire, dizilerden istatiki işlemlere kadar birçok işlemi yapmanızı sağlar.
opencv:
OpenCV bildiğiniz üzere görselleri işlememize yarayan oldukça güçlü bir kütüphane
pickle:
Oluşturacağımız çıktıyı dosyaya yazdırmamızı sağlayan bir araç.
Kütüphanelerimizi import edelim
Şimdi bir sınıf oluşturup kodlamaya geçmeden önce yapacaklarımdan bahsedeyim; Öncelikle kameradan bir video kaydı alacağım, sonra bu video kaydındaki yüzleri tanımlayacağım. Sonra kendi yüzümü ve bir takım ünlülerin yüzünü train edip bir dataset oluşturacağım, hemen ardından video kaydındaki yüzün oradaki herhangi bir yüzle eşleşip eşleşmediğini kontrol edeceğim. Eşleşme varsa bu yüzün sahibinin adını ekrana yazdıracağız.
Buraya kadar her şey tamam ise sınıfımızı oluşturup kodlamaya başlayalım.
Bu sınıfı çağırdığımızda video kaydının başladığını göreceğiz. Şimdi videodaki yüzleri tespit edelim, bunun için opencv nin bize sunduğu classifier'ları kullanacağız. Kameraya direkt bakacağımdan "haarcascade_frontalface_alt2.xml" benim için uygun bir tercih olacaktır. Üstteki sınıfımıza dönelim ve bazı değişiklikler ekleyelim.
Bu parçacığı init kısmına ekledikten sonra alttaki fonksiyonuma geçiyorum. Şimdi daha kolay okuyabilmek için video kaydını siyah-beyaza dönüştüreceğim, ardından tespit ettiğim yüzün koordinatlarını bulup etrafına bir kare çizeceğim. Tüm bunları yaparken bana openCV kütüphanesi yardımcı olacak.
Bu değişikliklerden sonra yüzümüzün etrafında bir kare oluşacaktır, mantıken ne yaptığımız zaten üst koddaki yorum satırlarında yazılı.
Şimdi, bu yüzü diğer yüzlerden ayırmaya çalışacağım. Bu yüzden birkaç ünlünün fotoğrafını kullanacağım.
mikhail tal:
rock:
bonnie tyler:
Atatürk -kalbimizde...-:
Tüm bu üstteki isimlere dair 5 er tane fotoğraf indirdikten sonra "images" adı altında bir klasör açıyorum ve bu klasörün içine hepsinin isminde 5 klasör daha açıyorum. Her klasöre ilgili ünlüye ait 5 fotoğraf atıyorum ve klasör yapımız şu şekilde oluyor.
Şeklinde bir dosya yapımız olacaktır. Şimdi bu dosya yapısından fotoğrafları ve isimleri işleyelim. Yeni bir script yazacağım bu işlem için, tekrardan en başta kütüphanelerimizi içe aktaralım.
Şimdilik bu yeterli, lazım oldukça ekleme yapacağım. Bir sınıf oluşturalım ve kodumuzu yazmaya başlayalım.
Kodu çalıştırdığımıda aldığımız çıktı bu;
Şimdi bu yüzleri işlememiz gerekiyor. Neyse ki ekstra bir machine learning kütüphanesi kullanmama gerek yok, şimdiki kütüphaneler işe yarayacaktır. init fonksiyonuma son kez dönüyorum ve editliyorum
Gerekli değişkenlerimizi tanımladık, zamanı geldikçe tek tek ne işe yaradığından bahsedeceğim. Öncelikle dosya adlarını isim olarak kullanacağımızdan bahsetmiştik, bir nevi bu klasör adları bizim "label" ımız olacak. current_id isimli değişkenimiz ise onun kaçıncı label olduğunu söyleyecek.
Bu kod işimize yarayacaktır. Label'ları belirlediysek elimizdeki yüzleri birer array'e dönüştürüp bunu uygun bir dataset olarak kaydetmeliyiz. array işlemlerini "numpy" adlı kütüphane ile yapacağımızı zaten söylemiştim. Basitçe elimizdeki resmi "L" yada "RGB" moda çevirip diğer resimlerle olan benzerliğini kıyaslayacağım. Bunu da yüzdeye vuracağım, eğer beni ikna edecekte bir yüzdeye sahipse bunu label olarak yazdıracağım. Hemen ardından bunu kaydedeceğim ki ilk scriptim'de bu dataseti kullanabileyim.
Gördüğünüz üzere resmi rgb olarak array'e dönüştürdüm. Pickle kütüphanesini kullanarak bu dataset'i kaydettim.Bu sınıfı bir defa çalıştırdıktan sonra ilk
Şimdi asıl kodumuza dönelim.
Kaydettiğim trainer'ı asıl scriptte okuyacağım. Ardından üstte bahsettiğim gibi beni ikna edecek bir yüzdeyse ise bu label'ı ekranda yazdıracağım. Daha teknik olmayan bir dille anlatırsam, kameranın gördüğü kişiyi tanıyorsanız yanında ismi yazacak. İlk script'teki init fonksiyonumu tekrar editlemem gerekiyor.
Gördüğünüz gibi hem datasetimi hem de label'ları çektim diğer scriptten. Elimde zaten yüzü işaretleyen kod vardı, geldik sonuna...
Bu kod parçacığını ana fonksiyonuma yazıyorum, ve işlem tamam. Tüm kod şu şekilde oldu
face_trainer.py:
Bugünkü yazımın sonuna geldim, umarım projelerinizde işinize yarar. Sağlıcakla kalın
numpy:
NumPy, numerical python, oldukça büyük bir bilimsel işlem kütüphanesidir. Mantıktan cebire, dizilerden istatiki işlemlere kadar birçok işlemi yapmanızı sağlar.
opencv:
OpenCV bildiğiniz üzere görselleri işlememize yarayan oldukça güçlü bir kütüphane
pickle:
Oluşturacağımız çıktıyı dosyaya yazdırmamızı sağlayan bir araç.
Kütüphanelerimizi import edelim
Kod:
import numpy as np
import cv2
import pickle
Şimdi bir sınıf oluşturup kodlamaya geçmeden önce yapacaklarımdan bahsedeyim; Öncelikle kameradan bir video kaydı alacağım, sonra bu video kaydındaki yüzleri tanımlayacağım. Sonra kendi yüzümü ve bir takım ünlülerin yüzünü train edip bir dataset oluşturacağım, hemen ardından video kaydındaki yüzün oradaki herhangi bir yüzle eşleşip eşleşmediğini kontrol edeceğim. Eşleşme varsa bu yüzün sahibinin adını ekrana yazdıracağız.
Buraya kadar her şey tamam ise sınıfımızı oluşturup kodlamaya başlayalım.
Kod:
class faceID(object):
def __init__(self):
self.cap = cv2.VideoCapture(0)
def video_capture(self):
while 1:
ret, frame = self.cap.read()
cv2.imshow('video', frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
self.cap.release()
cv2.destroyAllWindows()
Bu sınıfı çağırdığımızda video kaydının başladığını göreceğiz. Şimdi videodaki yüzleri tespit edelim, bunun için opencv nin bize sunduğu classifier'ları kullanacağız. Kameraya direkt bakacağımdan "haarcascade_frontalface_alt2.xml" benim için uygun bir tercih olacaktır. Üstteki sınıfımıza dönelim ve bazı değişiklikler ekleyelim.
Kod:
self.face_cascade = cv2.CascadeClassifier('cascades\\data\\haarcascade_frontalface_alt2.xml')
Kod:
self.gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#siyah beyaza çevirir.
self.faces= self.face_cascade.detectMultiScale(self.gray, scaleFactor=1.5, minNeighbors=5)#yüzleri tespit eder
for (x,y,w,h) in self.faces:#yüzlerin koordinatlarını alıyorum
self.roi_gray = self.gray[y:y+h, x:w+w]
color=(95,234,249)
stroke=2
end_cord_x = x + w
end_cord_y = y + h
cv2.rectangle(frame, (x, y), (end_cord_x, end_cord_y), color, stroke)#bu koordinatlara bir kare çiziyorum
Bu değişikliklerden sonra yüzümüzün etrafında bir kare oluşacaktır, mantıken ne yaptığımız zaten üst koddaki yorum satırlarında yazılı.
Şimdi, bu yüzü diğer yüzlerden ayırmaya çalışacağım. Bu yüzden birkaç ünlünün fotoğrafını kullanacağım.
mikhail tal:
rock:
bonnie tyler:
Atatürk -kalbimizde...-:
Tüm bu üstteki isimlere dair 5 er tane fotoğraf indirdikten sonra "images" adı altında bir klasör açıyorum ve bu klasörün içine hepsinin isminde 5 klasör daha açıyorum. Her klasöre ilgili ünlüye ait 5 fotoğraf atıyorum ve klasör yapımız şu şekilde oluyor.
Kod:
-images
|
|
|
|___>rock
|
|
|__>fotoğraflar
|
|
|
|___>mikhail tal
|
|
|___>fotoğraflar
|
|
|
|___>Atatürk
.
.
.
Kod:
import os
Kod:
import os
class train_image(object):
def __init__(self):
self.base_directory = os.path.dirname(os.path.abspath(__file__))#dizine ilerle
self.image_directory = os.path.join(self.base_directory, "images")
def train(self):
for root, dirs, files in os.walk(self.image_directory, "images"):#dosyadaki diğer dosyaları bulalım. Arka planda bu;
#C:\Users\Hackno\Desktop\eye_final>py -3 konu_.py
#C:\Users\Hackno\Desktop\eye_final\images ['atatürk', 'mikhail tal',...] []
#C:\Users\Hackno\Desktop\eye_final\images\atatürk [] ['a..]
#şeklinde bir çıktı döndürür
for self.file in files:
if self.file.endswith("png") or self.file.endswith("jpg"):#png ilee jpg ile biten, yani resim dosyalarını bulalım
self.path = os.path.join(root, self.file)#
self.label = os.path.basename(os.path.dirname(self.path)).replace(" ", "-").lower()
print(self.path, self.label)#Fotoğraf adını ve o fotoğrafın bulunduğu klasörü (yani şahsın ismini) yazdırdım.
train = train_image()#sınıfı çağırıyoruz...
train.train()
Kodu çalıştırdığımıda aldığımız çıktı bu;
Kod:
C:\Users\Hackno\Desktop\eye_final\images\michael tal\Mikhail-Tal-300x168.jpg mikha
il-tal
C:\Users\Hackno\Desktop\eye_final\images\michael tal\tal1.png mikhail-tal
C:\Users\Hackno\Desktop\eye_final\images\rock\WHDQ-512469260.png rock
C:\Users\Hackno\Desktop\eye_final\images\rock\WHDQ-512469283.jpg rock
C:\Users\Hackno\Desktop\eye_final\images\rock\WHDQ-512469299.jpg rock
C:\Users\Hackno\Desktop\eye_final\images\rock\WHDQ-512469316.jpg rock
C:\Users\Hackno\Desktop\eye_final\images\rock\WHDQ-512469340.png rock
C:\Users\Hackno\Desktop\eye_final\images\Hackno\my-image.png utku
C:\Users\Hackno\Desktop\eye_final\images\Hackno\0xhacknology.png utku
C:\Users\Hackno\Desktop\eye_final\images\Hackno\0xhacknology.png utku
C:\Users\Hackno\Desktop\eye_final\images\Hackno\0xhacknology.png utku
C:\Users\Hackno\Desktop\eye_final\images\Hackno\0xhacknology.png utku
Şimdi bu yüzleri işlememiz gerekiyor. Neyse ki ekstra bir machine learning kütüphanesi kullanmama gerek yok, şimdiki kütüphaneler işe yarayacaktır. init fonksiyonuma son kez dönüyorum ve editliyorum
Kod:
class train_image(object):
def __init__(self, c_path): #c_path = classifier path
self.base_directory = os.path.dirname(os.path.abspath(__file__))
self.image_directory = os.path.join(self.image_directory, "images")
self.face_cascade = cv2.CascadeClassifier(c_path)
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
self.current_id = 0
self.label_ids = {}
self.y_labels = []
self.x_train = []
Gerekli değişkenlerimizi tanımladık, zamanı geldikçe tek tek ne işe yaradığından bahsedeceğim. Öncelikle dosya adlarını isim olarak kullanacağımızdan bahsetmiştik, bir nevi bu klasör adları bizim "label" ımız olacak. current_id isimli değişkenimiz ise onun kaçıncı label olduğunu söyleyecek.
Kod:
if not self.label in label_ids:
self.label_ids[self.label] = self.current_id
self.current_id += 1
self.id_ = self.label_ids[self.label]
Kod:
self.pimage = Image.open(self.path).convert("L")
self.image_array = np.array(self.pimage, "uint8")
self.faces= self.face_cascade.detectMultiScale(self.image_array, scaleFactor=1.5, minNeighbors=5)
for (x, y, w, h) in self.faces:
self.roi = image_array[y:y+h, x:x+w]
self.x_train.append(self.roi)
self.y_labels.append(self.id_)
def pickle(self):
self.train_it()
with open("labels.pickle", "wb") as f:
pickle.dump(self.label_ids, f)
self.recognizer.train(self.x_train, np.array(self.y_labels))
self.recognizer.save("trainner.yml")
Gördüğünüz üzere resmi rgb olarak array'e dönüştürdüm. Pickle kütüphanesini kullanarak bu dataset'i kaydettim.Bu sınıfı bir defa çalıştırdıktan sonra ilk
Şimdi asıl kodumuza dönelim.
Kaydettiğim trainer'ı asıl scriptte okuyacağım. Ardından üstte bahsettiğim gibi beni ikna edecek bir yüzdeyse ise bu label'ı ekranda yazdıracağım. Daha teknik olmayan bir dille anlatırsam, kameranın gördüğü kişiyi tanıyorsanız yanında ismi yazacak. İlk script'teki init fonksiyonumu tekrar editlemem gerekiyor.
Kod:
class faceID(object):
def __init__(self):
self.cap = cv2.VideoCapture(0)
self.face_cascade = cv2.CascadeClassifier('cascades\\data\\haarcascade_frontalface_alt2.xml')
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
self.recognizer.read("trainner.yml")
def get_label_names(self):
self.labels = {"person_name": 1}
with open("labels.pickle", "rb") as f:
self.labels = pickle.load(f)
self.labels = {v: k for k,v in self.labels.items()}
Gördüğünüz gibi hem datasetimi hem de label'ları çektim diğer scriptten. Elimde zaten yüzü işaretleyen kod vardı, geldik sonuna...
Kod:
for (x,y,w,h) in self.faces:
self.roi_gray = self.gray[y:y+h, x:w+w]#siyah beyaz versiyon
roi_color = frame[y:y+h, x:x+w]#renkli versiyon
id_, conf = self.recognizer.predict(self.roi_gray)#yüzdeye vuracak
if conf >= 4 and conf <= 85:#yüzde 4 ten büyük 85 ten küçük ise
font = cv2.FONT_HERSHEY_COMPLEX#yazının fontunu seçtim
name = self.labels[id_]#id_ = isim
color = ()
stroke = 2
cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)#Yüzün yanına ismi yazıyorum
else:
pass
Kod:
face_identifier.py:
import numpy as np
import cv2
import pickle
class faceID(object):
def __init__(self):
self.cap = cv2.VideoCapture(0)
self.face_cascade = cv2.CascadeClassifier('cascades\\data\\haarcascade_frontalface_alt2.xml')
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
self.recognizer.read("trainner.yml")
def get_label_names(self):
self.labels = {"person_name": 1}
with open("labels.pickle", "rb") as f:
self.labels = pickle.load(f)
self.labels = {v: k for k,v in self.labels.items()}
def video_capture(self):
self.get_label_names()
while 1:
ret, frame = self.cap.read()
self.gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
self.faces= self.face_cascade.detectMultiScale(self.gray, scaleFactor=1.5, minNeighbors=5)
for (x,y,w,h) in self.faces:
self.roi_gray = self.gray[y:y+h, x:w+w]
roi_color = frame[y:y+h, x:x+w]
id_, conf = self.recognizer.predict(self.roi_gray)
if conf >= 4 and conf <= 85:
font = cv2.FONT_HERSHEY_COMPLEX
name = self.labels[id_]
color = ()
stroke = 2
cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)
else:
pass
self.img_item = 'my-image.png'
cv2.imwrite(self.img_item, self.roi_gray)
color=(95,234,249)
stroke=2
end_cord_x = x + w
end_cord_y = y + h
cv2.rectangle(frame, (x, y), (end_cord_x, end_cord_y), color, stroke)
cv2.imshow('video_rec', frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
ID = faceID()
ID.video_capture()
face_trainer.py:
Kod:
import cv2
import os
import numpy as np
from PIL import Image
import pickle
import sys
class trainer(object):
def __init__(self, c_path): #c_path = classifier path
self.BASE_DIR = os.path.dirname(os.path.abspath(__file__))
self.image_dir = os.path.join(self.BASE_DIR, "images")
self.face_cascade = cv2.CascadeClassifier(c_path)
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
self.current_id = 0
self.label_ids = {}
self.y_labels = []
self.x_train = []
def train_it(self):
for root, dirs, files in os.walk(self.image_dir, "images"):
for self.file in files:
if self.file.endswith("png") or file.endswith("jpg"):
self.path = os.path.join(root, file)
self.label = os.path.basename(os.path.dirname(self.path)).replace(" ", "-").lower()
if not self.label in label_ids:
self.label_ids[self.label] = self.current_id
self.current_id += 1
self.id_ = self.label_ids[self.label]
self.pimage = Image.open(self.path).convert("L")
self.image_array = np.array(self.pimage, "uint8")
self.faces= self.face_cascade.detectMultiScale(self.image_array, scaleFactor=1.5, minNeighbors=5)
for (x, y, w, h) in self.faces:
self.roi = image_array[y:y+h, x:x+w]
self.x_train.append(self.roi)
self.y_labels.append(self.id_)
def pickle(self):
self.train_it()
with open("labels.pickle", "wb") as f:
pickle.dump(self.label_ids, f)
self.recognizer.train(self.x_train, np.array(self.y_labels))
self.recognizer.save("trainner.yml")
Bugünkü yazımın sonuna geldim, umarım projelerinizde işinize yarar. Sağlıcakla kalın
Son düzenleme: