Turkhackteam.org/net - Ethical Hacking & Cyber Security Platform

Turkhackteam.org/net - Ethical Hacking & Cyber Security Platform (https://www.turkhackteam.org/)
-   Python (https://www.turkhackteam.org/python/)
-   -   Python Face Identifier Yapımı (https://www.turkhackteam.org/python/1746771-python-face-identifier-yapimi.html)

Hacknology 18-07-2018 21:10 21:10

Python Face Identifier Yapımı
 
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.
https://www.learnopencv.com/wp-conte...on-windows.jpg
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')
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.
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:
https://qph.ec.quoracdn.net/main-qim...a17c1ed27.webp
rock:
https://www.hindustantimes.com/rf/im...6882c41036.jpg
bonnie tyler:
https://images-na.ssl-images-amazon....CL._SX425_.jpg
Atatürk -kalbimizde...-:
https://www.makaleler.com/fotomakale...olumu-2038.png
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
.
.
.

Ş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.
Kod:

import os
Şimdilik bu yeterli, lazım oldukça ekleme yapacağım. Bir sınıf oluşturalım ve kodumuzu yazmaya başlayalım.
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]

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.
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

Bu kod parçacığını ana fonksiyonuma yazıyorum, ve işlem tamam. Tüm kod şu şekilde oldu
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

MaliTR 18-07-2018 21:35 21:35

Ellerine sağlık teşekkür ederim.

qRunt11 18-07-2018 22:13 22:13

Eline sağlık hacknocum

Gbmdpof 18-07-2018 22:30 22:30

Eline sağlık

k3~ 18-07-2018 22:31 22:31

Eline sağlık ;)

sqruhqn 18-07-2018 22:38 22:38

Buram buram emek kokuyor :)
Eline sağlık hocam

siberdrone15 18-07-2018 22:43 22:43

Eline sağlık harika
Bir sorum olacak cv2 yüklerken sadece import yazıp çağırmamız yeterli mi yoksa pip olarak bir kurulum vs var mı

GZM16 18-07-2018 23:00 23:00

Eline sağlık

Hacknology 18-07-2018 23:12 23:12

Alıntı:

MaliTR´isimli üyeden Alıntı (Mesaj 8314976)
Ellerine sağlık teşekkür ederim.

Alıntı:

sqruhqn´isimli üyeden Alıntı (Mesaj 8315128)
Buram buram emek kokuyor :)
Eline sağlık hocam

Alıntı:

siberdrone15´isimli üyeden Alıntı (Mesaj 8315133)
Eline sağlık harika
Bir sorum olacak cv2 yüklerken sadece import yazıp çağırmamız yeterli mi yoksa pip olarak bir kurulum vs var mı

Öncelikle size ve üstte tüm yorum atanlara teşekkürlerimi sunarım. Önce kurmanız gerekiyor, 3rd lib'dir kendileri.

Hacknology 19-07-2018 16:03 16:03

Güncel...


Şu Anki Saat: 08:57

Powered by vBulletin® Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.