AI Technology Review Press: Bu makale ünlü bilgisayarla görme öğretim web sitesi "pyimagesearch" den geliyor ve yazar Adrian Rosebrock. Bu makalede, Adrian, "görüntülerde / videolarda gerçek yüzlerin ve sahte yüzlerin nasıl tanımlanacağı" konusunda derinlemesine bir analiz yapacak ve OpenCV tabanlı modeller kullanarak canlı algılama için belirli yöntemler tanıtacak. Leifeng.com AI Technology Review aşağıdaki gibi derlenmiştir.
Bu eğitim, canlılık tespiti için OpenCV'yi nasıl kullanacağınızı öğretecektir. Öğrenerek, yüz tanıma sisteminde sahte yüzleri algılayabilen ve yüz karşıtı aldatma gerçekleştirebilen bir canlılık detektörü oluşturabileceksiniz.
Geçtiğimiz yıl, bu makalenin yazarı, aşağıdakiler de dahil olmak üzere birçok yüz tanıma eğitimi yazdı:
OpenCV'ye dayalı yüz tanıma (okuma adresi: https://www.pyimagesearch.com/2018/09/24/opencv-face-recognition/)
Yüz tanıma için dlib, Python ve derin öğrenmeyi kullanın (adresi okuyun: https://www.pyimagesearch.com/2018/06/18/face-recognition-with-opencv-python-and-deep-learning/)
Raspberry Pi'ye dayalı yüz tanıma (okuma adresi: https://www.pyimagesearch.com/2018/06/25/raspberry-pi-face-recognition/)
Ancak, aldığım bazı e-postalarda ve bu blog yazılarındaki yüz tanıma hakkındaki yorumlarda sık sık sorulan bir soru şuydu:
Gerçek bir yüz ile sahte bir yüzü nasıl ayırt edebilirim?
Şüphelenmeyen bir kullanıcı kasıtlı olarak yüz tanıma sisteminizi kandırmaya çalışırsa ne olacağını hayal edin?
Yüz tanıma yapan bir kameraya bir fotoğraf veya video (bu makalenin üst kısmındaki resim gibi) göstermeye çalışabilirler. Bu fotoğraf ve videodaki kişiler, kullanıcıların kendileri değildir.
Bu durumda, yüz tanıma sistemi, önlerinde gösterilen resimleri doğru yüz olarak tanımak tamamen mümkündür ve bu da sonuçta yetkisiz kullanıcıların yüz tanıma sisteminden kaçınmasına neden olacaktır!
Bu "sahte" ve "gerçek / yasal" yüzleri nasıl ayırt edebiliriz? Anti-face spoofing algoritması yüz tanıma uygulamanıza nasıl uygulanabilir?
Cevap, canlı algılama için OpenCV kullanmaktır, bu makalede anlatılacak.
Peki OpenCV tabanlı canlı algılama işlevini kendi yüz tanıma sisteminize nasıl entegre edebilirsiniz? Cevap bu makalede bir sonraki bölümde verilecektir.
Bu eğiticinin ilk bölümünde, "Canlılık tespiti nedir?" Ve "Yüz tanıma sistemini iyileştirmek için neden canlılık tespitine ihtiyacımız var?" Dahil olmak üzere canlılık tespitini tartışacağız.
Burada, ilk olarak canlı algılama için kullanılacak veri setini gözden geçiriyoruz:
Canlı algılama için bir veri kümesi nasıl oluşturulur
Gerçek ve sahte yüzlerimizin resim örnekleri
Canlı vücut dedektörü projesi için proje yapısını da gözden geçireceğiz.
Canlı bir dedektör oluşturmak için gerçek ve sahte yüzleri ayırt edebilen derin bir sinir ağını eğiteceğiz.
Bu nedenle şunlara ihtiyacımız var:
1. Bir görüntü veri kümesi oluşturun
2. Canlı algılama yapabilen evrişimli bir sinir ağı uygulayın (biz buna "LivenessNet" diyoruz)
3. Canlı algılama ağını eğitme
4. Eğitimli yaşam algılama modelimizi kullanabilen ve bunu gerçek zamanlı videoya uygulayabilen bir Python + OpenCV komut dosyası oluşturun
Şimdi ana konuya geçelim!
Şekil 1: OpenCV'ye dayalı canlı algılama. Soldaki resim canlı vücudumun (gerçek kişi) bir videosu ve sağdaki resimde iPhone'umu tuttuğumu görebiliyorum (ekranda yüz tanıma sistemini aldatmak için kullanılan sahte bir yüz / yüz resmi var).
Yüz tanıma sistemleri giderek daha popüler hale geliyor. İPhone / akıllı telefondaki yüz tanıma sisteminden, Çin'de büyük ölçekli gözetim-yüz tanıma için kullanılan yüz tanıma sistemine kadar her yerde yaygınlaştı.
Ancak yüz tanıma sistemi, "aldatıcı" ve "gerçek dışı" yüzler tarafından kolayca kandırılır.
Yüz tanıma için kullanılan bir kameraya bir kişinin fotoğrafını (ister basılı olsun ister bir akıllı telefon ekranında görüntülenen vb.) Göstererek, yüz tanıma sistemini kandırmak kolaydır.
Yüz tanıma sistemini daha güvenli hale getirmek için, bu tür sahte / gerçek olmayan yüzleri tespit etmemiz gerekiyor ve "canlı algılama" bu algoritmaya atıfta bulunmak için kullanılan terimdir.
Aşağıdakiler dahil birçok canlı algılama yöntemi vardır:
Yüz alanında yerel ikili desenlerin (LBP, https://www.pyimagesearch.com/2015/12/07/local-binary-patterns-with-python-opencv/) hesaplanması ve destek vektörlerinin kullanımı dahil olmak üzere doku analizi Makine (SVM), insan yüzlerini gerçek veya sahte olarak sınıflandırır.
Bir yüz resminin Fourier alanını görüntülemek gibi frekans analizi (Fourier onu dönüştürür).
İki ardışık kare arasındaki piksel değerlerindeki değişiklikleri görüntüleme gibi değişken odak analizi.
Göz hareketi, dudak hareketi ve göz kırpma algılama dahil sezgisel algoritmalara dayanır (https://www.pyimagesearch.com/2017/04/24/eye-blink-detection-opencv-python-dlib/). Bu tür bir algoritma, kullanıcının başka bir kişinin resmini göstermediğinden emin olmak için göz hareketini ve göz kırpmayı izlemeye çalışır (çünkü resim yanıp sönmez veya dudakları hareket ettirmez).
Optik akış algoritması, yani üç boyutlu bir nesne ve iki boyutlu bir düzlem tarafından oluşturulan optik akışın farkını ve özelliklerini görüntülemek içindir.
Üç boyutlu yüz şekli, Apple iPhone tarafından kullanılan yüz tanıma sistemine benzer olup, yüz tanıma sisteminin basılı / fotoğraftaki / görüntüdeki gerçek yüz ile başka bir kişinin yüzünü ayırt etmesini sağlar.
Yukarıdaki yöntemlerin birleştirilmesi, yüz tanıma sistemi mühendislerinin kendi özel uygulamalarına uygun bir canlı algılama modeli seçmelerine olanak tanır.
Chakraborty ve Das tarafından 2014 yılında yayınlanan "Yüz Canlılığı Algılamaya Genel Bakış" adlı makalede (makale okuma adresi: https://arxiv.org/pdf/1405.2227.pdf), canlılık algılama algoritmasının kapsamlı bir incelemesi yapılmıştır.
Bu makalenin öğreticisinde, canlı algılamayı bir ikili sınıflandırma sorunu olarak ele alıyoruz.
Bir girdi görüntüsü verildiğinde, gerçek ve yanlış yüzleri tanıyabilen evrişimli bir sinir ağını eğiteceğiz.
Canlı algılama modelimizi eğitmeye başlamadan önce, kullanılan veri kümesine bir göz atalım.
Şekil 2: Toplanan gerçek yüzler ve sahte / aldatıcı yüzler örneği. Soldaki video yüzümün yasal bir videosudur. Sağda, dizüstü bilgisayarım tarafından solda kaydedilen video var.
Örneğimizi basitleştirmek için, bu makalede oluşturduğumuz canlılık detektörü, ekrandaki gerçek yüzler ile aldatıcı yüzler arasında ayrım yapmaya odaklanacak.
Algoritma, yazıcılar tarafından yazdırılan yüzler veya yüksek çözünürlüklü dahil olmak üzere diğer aldatıcı yüz türlerine kolayca genişletilebilir.
Canlı algılama veri seti oluşturmak için şunları yapacağım:
1. iPhone'umu kullanın ve onu portre / selfie moduna ayarlayın.
2. Ofiste dolaştığım 25 saniyelik bir video kaydedin.
3. Bu 25 saniyelik videoyu iPhone'um masaüstüme bakacak şekilde tekrar oynatın Bu yeniden oynatılan videoyu masaüstü perspektifinden kaydettim;
4. Bu, iki örnek video oluşturacaktır. Biri "gerçek" bir yüz, diğeri ise "sahte / aldatıcı" bir yüz olarak kullanıldı.
5. Sonunda, iki tür yüzün ilgili ROI'lerini çıkarmak için bu iki video setine aynı anda yüz algılama teknolojisi uyguladım.
Bu makalenin "indir" bölümünde size gerçek yüz videoları ve sahte yüz videoları sağladım.
Bir veri seti oluşturmaya başlamak için bu videoları doğrudan kullanabilirsiniz, ancak canlılık dedektörünüzün sağlamlığını ve doğruluğunu iyileştirmeye yardımcı olmak için daha fazla veri toplamanızı öneririm.
Testler yoluyla, bu modelin kendi yüzümü tespit etme yönünde önyargılı olacağını doğruladım - çünkü tüm modeller kendi videomla eğitildi, bu model hala anlamlı. Ayrıca, Kafkasyalı olduğum için, bu veri setinin diğer ten renklerinin yüzlerini tespit etmek için kullanıldığında aynı mükemmel performansa sahip olmasını beklemiyorum.
İdeal olarak, birden çok ırkın yüzlerini içeren verileri kullanarak bir model eğitebilirsiniz. Okuyucular canlı algılama modelini iyileştirme konusunda daha fazla öneri isterse, lütfen aşağıdaki "Sınırlamalar ve Daha Fazla Çalışma" bölümüne bakın.
Bir sonraki eğitimde, kaydettiğim veri setini nasıl kullanacağınızı öğrenecek ve gerçek bir canlı vücut dedektörü elde etmek için OpenCV ve derin öğrenme teknolojisini kullanacaksınız.
Okumaya devam etme sürecinde, okuyucular kodu, veri setini ve canlı algılama modelini elde etmek ve arşivi açmak için "İndir" bölümünde sağlanan bağlantıyı kullanabilir.
Projenin dizinine gittiğinizde, aşağıdaki yapıyı göreceksiniz:
$ ağaç --dirsfirst --filelimit 10
veri kümesi
sahte
gerçek
yüz algılayıcısı
deploy.prototxt
res10_300x300_ssd_iter_140000.caffemodel
pyimagesearch
__init__.py
livenessnet.py
videolar
fake.mp4
real.mov
collect_examples.py
train_liveness.py
liveness_demo.py
lepickle
canlılık. Model
plot.png
6 dizin, 12 dosya
Projemizde dört ana dizin bulunmaktadır:
"Veri Kümesi /": Veri kümesi dizinimiz iki tür görüntü içerir:
(1) Kamera yüz videomu oynayan cep telefonu ekranının çektiği sahte görüntüye bakıyor.
(2) Cep telefonumla selfie çektiğim videodaki gerçek görüntü.
"Face_detector /": Yüzün ROI'sini bulmak için kullandığımız önceden eğitilmiş Caffe yüz dedektörünü içerir.
"Pyimagesearch /": Bu modül, LivenessNet sınıfımızı içerir.
"Videolar /": LivenessNet sınıflandırıcısını eğitmek için iki giriş videosu sağladım.
Şimdi, üç Python komut dosyasını ayrıntılı olarak inceleyeceğiz. Bu makalenin sonunda, bu betikleri kendi verileriniz üzerinde çalıştırabilir ve video girişi yapabilirsiniz. Bu eğitimde göründükleri sırayla, üç komut dosyası şunlardır:
1. "collect_examples.py": Bu komut dosyası, giriş video dosyasından yüzün ROI'sini alır ve derin öğrenme yüz canlı algılama veri kümesi oluşturmamıza yardımcı olur.
2. "train_liveness.py": Dosya adından da anlaşılacağı gibi, bu komut dosyası LivenessNet sınıflandırıcımızı eğitecektir. Modeli eğitmek için Keras ve TensorFlow kullanacağız. Eğitim süreci aşağıdaki dosyaları üretecektir:
(1) le.pickle: Sınıf etiketi kodlayıcımız.
(2) liveness.model: Yüz canlılığı algılayıcısını eğitmek için kullandığımız bir dizi Keras modeli.
(3) plot.png: Eğitim geçmişi diyagramı, modelin doğruluk ve kayıp eğrisini gösterir ve modelimizi buna göre değerlendirebiliriz (yani, aşırı uydurma / uydurma).
3. "liveness_demo.py": Demo komut dosyamız, gerçek zamanlı yüz canlı algılaması için video kareleri çekmek üzere web kameranızı başlatır.
Şekil 3: Canlılık algılama veri seti oluşturmak için, videodaki yüzün ROI alanının ilk olarak tespit edilmesi gerekir.
Şimdi başlatılmış veri setimizi ve proje mimarimizi inceleyebiliriz, giriş videosundan gerçek ve sahte yüz görüntülerini nasıl çıkaracağımızı görelim.
Bu komut dosyasının nihai amacı, iki dizini verilerle doldurmaktır:
1. "veri kümesi / sahte /": "fake.mp4" dosyasında yüz ROI alanını içerir.
2. "dataset / real /": "real.mov" dosyasında yüz ROI alanını içerir.
Bu çerçevelere dayanarak, bir sonraki görüntüde derin öğrenmeye dayalı canlı bir dedektör eğiteceğiz.
"Collect_examples.py" dosyasını açın ve aşağıdaki kodu ekleyin:
# gerekli paketleri içe aktarın
numpy'yi np olarak içe aktar
ithal argparse
cv2 içe aktar
işletim sistemini içe aktar
# bağımsız değişkeni yapılandırın ve bağımsız değişkenleri çözümleyin
ap = argparse.ArgumentParser
ap.add_argument ("- i", "--input", tür = str, gerekli = Doğru,
help = "video giriş yolu")
ap.add_argument ("- o", "--output", type = str, required = True,
help = "kırpılmış yüzlerin çıktı dizini yolu")
ap.add_argument ("- d", "--detector", tür = str, gerekli = Doğru,
help = "OpenCV'nin derin öğrenme yüz algılayıcısına giden yol")
ap.add_argument ("- c", "--confidence", tür = float, varsayılan = 0,5,
help = "zayıf algılamaları filtrelemek için minimum olasılık")
ap.add_argument ("- s", "--skip", tür = int, varsayılan = 16,
help = "Yüz algılama uygulamadan önce atlanacak kare sayısı")
args = vars (ap.parse_args)
2-5 satırları, ihtiyacımız olan yükleme paketini tanıtır. Yerleşik Python modülüne ek olarak, komut dosyası yalnızca OpenCV ve NumPy'ye ihtiyaç duyar.
Satır 8-19, komut satırı bağımsız değişkenlerimizi ayrıştırır (https://www.pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/):
"--Input": Girdi video dosyamızın yolu.
"--Output": Kırpılan her yüz görüntüsünü depolayan çıktı dizininin yolu.
"--Detektör": Yüz dedektörünün yolu. OpenCV'nin derin öğrenme yüz dedektörünü kullanacağız (https://www.pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/). Okuyucuların rahatlığı için, Caffe modeli bu makalenin "indirme" bölümünde mevcuttur.
"--Güven": Zayıf yüz algılama sonuçlarını filtrelemenin minimum olasılığı. Varsayılan olarak değer% 50'dir.
"--Skip": Her bir görüntüyü algılayıp kaydetmemize gerek yok çünkü bitişik çerçeveler benzer. Bunun yerine, iki yüz algılama görevi arasında N kareyi atlayacağız. Varsayılan N değerini (16) değiştirmek için bu parametreyi kullanabilirsiniz.
Yüz algılayıcıyı yüklemeye ve video akışımızı başlatmaya devam edelim:
# serileştirilmiş yüz dedektörümüzü diskten yükleyin
baskı ("yüz algılayıcı yükleniyor ...")
protoPath = os.path.sep.join ()
modelPath = os.path.sep.join ()
net = cv2.dnn.readNetFromCaffe (protoPath, modelPath)
# video dosyası akışına bir işaretçi açın ve toplamı başlatın
Şimdiye kadar okunan ve kaydedilen kare sayısı
vs = cv2.VideoCapture (değiştirgeler)
oku = 0
kaydedildi = 0
23-26 satırları OpenCV'nin derin öğrenme yüz dedektörünü yükler (ilgili okuma: https://www.pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/) .
Ardından 30. satırdaki video akışımızı açtık.
Hala döngüyü yürütürken, okunan çerçeve sayısı ve kaydedilen çerçeve sayısı için iki değişkeni (satır 31 ve 32) başlattık.
Ardından, bu kareleri işlemek için bir döngü oluşturacağız:
# video dosyası akışından kare üzerinden döngü
True iken:
# kareyi dosyadan al
(yakalandı, çerçeve) = vs. okunmuş
# Çerçeve yakalanmadıysa, sona ulaştık
akışın #
yakalanmadıysa:
kırmak
# o ana kadar okunan toplam çerçeve sayısını artırır
+ = 1 oku
# bu çerçeveyi işlememiz gerekip gerekmediğini kontrol edin
% args! = 0 okursanız:
devam et
35. satırdaki "while" döngüsünü başlatıyoruz.
Sonra, bir çerçeve aldık ve doğruladık (37-42. Satırlar).
Şu anda, bir çerçeve okuduğumuz için, "okuma" sayacının sayısını artıracağız (48. satır). Bu belirli çerçeveyi atlamamız gerekirse, bir sonraki döngüye hiçbir şey yapmadan devam edeceğiz (48 ve 49. satırlar).
Yüzleri tespit etmeye devam edelim:
# çerçeve boyutlarını alın ve çerçeveden bir damla oluşturun
(h, w) = çerçeve.shape
blob = cv2.dnn.blobFromImage (cv2.resize (çerçeve, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
# blob'u ağ üzerinden geçirin ve algılamaları alın ve
# tahmin
net.setInput (blob)
algılamalar = net.forward
# en az bir yüz bulunduğundan emin olun
eğer len (tespitler) > 0:
# her görüntünün yalnızca BİR tane olduğunu varsayıyoruz
# yüz, öyleyse en büyük olasılığa sahip sınırlayıcı kutuyu bulun
i = np.argmax (algılamalar)
güven = tespitler
Yüz algılama gerçekleştirmek için görüntüden bir damla oluşturmamız gerekir (53 ve 54. satırlar). Caffe yüz dedektörüne uyum sağlamak için, bu "blob" un genişliği ve yüksekliği 300 * 300'dür. Sınırlayıcı kutuyu daha sonra ölçeklendirmemiz gerekiyor, bu yüzden 52. satırda çerçevenin boyutlarını alacağız.
58 ve 59. satırlar bu "blob" u derin öğrenme yüz detektöründen geçirir.
Komut dosyamız, videonun her karesinde (62-65. Satırlar) yalnızca bir yüz olduğunu varsayar, bu da yanlış pozitifleri önlemeye yardımcı olur. Birden fazla yüzü olan bir video üzerinde çalışıyorsanız, mantığı buna göre ayarlamanızı öneririm.
Bu nedenle, 65. satır en yüksek yüz algılama endeksini alır. 66. satır, testin güvenirliğini çıkarmak için dizini kullanır.
Ardından, zayıf yüz algılama sonuçlarını filtreleyelim ve yüzün yatırım getirisini diske yazalım:
# en büyük olasılıkla algılamanın da
# minimum olasılık testimiz anlamına gelir (böylece filtrelemeye yardımcı olur
# zayıf algılama)
güven varsa > argümanlar:
# için sınırlayıcı kutunun (x, y) koordinatlarını hesaplayın
# yüz ve yüz ROI'sini çıkarın
kutu = algılamalar * np.array ()
(startX, startY, endX, endY) = box.astype ("int")
yüz = çerçeve
# çerçeveyi diske yaz
p = os.path.sep.join ()
cv2.imwrite (p, yüz)
kaydedildi + = 1
print ("{} diske kaydedildi" .format (p))
# biraz temizlik yapın
vs sürüm
cv2.destroyAllWindows
Satır 71, yüz algılama ROI'mizin yanlış pozitifleri azaltmak için gereken minimum eşiği karşılamasını sağlar.
Bu temelde, yüzün ROI sınırlayıcı kutusu "kutu" koordinatlarını ve karşılık gelen yüz ROI değerini (74-76 satırları) çıkardık.
Yüz ROI'si için bir "yol + dosya adı" oluşturduk ve 79-81. Satırlarda diske yazdık. Burada "kurtulan" kişilerin sayısını artırabiliriz.
İşlemden sonra OpenCV'nin çalışma belleğini 86 ve 87. satırlarda temizleyeceğiz.
Şekil 4: OpenCV yüz canlı algılama veri setimiz. Canlı algılama modelinin tanıtım örneğini eğitmek için Keras ve OpenCV'yi kullanacağız.
Kaynak kodunu ve giriş video örneklerini almak için bu eğiticinin "İndir" bölümündeki bağlantıyı kullandığınızdan emin olun.
Bu temelde, lütfen bir terminal açın ve "sahtecilik / aldatıcı" kategorimiz için gerekli yüz görüntüsünü çıkarmak için aşağıdaki komutu çalıştırın:
$ python collect_examples.py --input videos / real.mov --output veri kümesi / gerçek \
--detector face_detector - 1 atla
yüz dedektörü yükleniyor ...
kaydedilmiş veri kümeleri / sahte / 0.png diske
kaydedilmiş veri kümeleri / sahte / 1.png diske
kaydedilmiş veri kümeleri / sahte / 2.png diske
kaydedilmiş veri kümeleri / sahte / 3.png diske
kaydedilmiş veri kümeleri / sahte / 4.png diske
kaydedilmiş veri kümeleri / sahte / 5.png diske
...
kaydedilmiş veri kümeleri / sahte / 145.png diske
kaydedilmiş veri kümeleri / sahte / 146.png diske
kaydedilmiş veri kümeleri / sahte / 147.png diske
kaydedilmiş veri kümeleri / sahte / 148.png diske
kaydedilmiş veri kümeleri / sahte / 149.png diske
Benzer şekilde, "gerçek" kategorinin yüz görüntüsünü elde etmek için aynı işlemi gerçekleştirebiliriz:
$ python collect_examples.py --input videos / fake.mov --output veri seti / sahte \
--detector face_detector --skip 4
yüz dedektörü yükleniyor ...
kaydedilmiş veri kümeleri / real / 0.png diske
kaydedilmiş veri kümeleri / real / 1.png diske
kaydedilmiş veri kümeleri / real / 2.png diske
kaydedilmiş veri kümeleri / real / 3.png diske
kaydedilmiş veri kümeleri / real / 4.png diske
...
kaydedilmiş veri kümeleri / real / 156.png diske
kaydedilmiş veri kümeleri / real / 157.png diske
kaydedilmiş veri kümeleri / real / 158.png diske
kaydedilmiş veri kümeleri / real / 159.png diske
kaydedilmiş veri kümeleri / real / 160.png diske
"Gerçek" yüz videosu, "sahte" yüz video dosyasından daha uzun olduğundan, her bir çıktı türü için yüz ROI sayısını dengelemek için daha uzun bir çerçeve atlama değeri kullanacağız.
Yukarıdaki komut dosyasını çalıştırdıktan sonra, aşağıda gösterildiği gibi görüntü verilerini elde etmiş olmalısınız:
Sahte insan yüzleri: 150 resim
Gerçek yüzler: 161 görüntü
Toplam: 311 resim
Şekil 5: Görüntülerde ve videolarda canlı yüzleri algılamak için tasarlanmış evrişimli bir sinir ağı (CNN) olan LivenessNet'in derin öğrenme mimarisi.
Daha sonra, derin öğrenme teknolojisine dayalı canlılık dedektörü "LivenessNet" i uygulayacağız.
Özünde, "LivenessNet" basit bir evrişimli sinir ağıdır.
Aşağıdaki iki nedenden dolayı, kasıtlı olarak ağı olabildiğince sığ ve olabildiğince az parametre tutacağız:
1. Küçük veri setimize aşırı uyum olasılığını azaltmak için.
2. Canlı dedektörümüzün hızlı ve gerçek zamanlı çalışabilmesini sağlamak için (Raspberry Pi gibi sınırlı bilgi işlem kaynaklarına sahip cihazlarda bile).
Şimdi "LivenessNet" i uygulamaya başlayacağız, lütfen "livenessnet.py" dosyasını açın ve aşağıdaki kodu ekleyin:
# gerekli paketleri içe aktarın
keras.models'den Sıralı içe aktarma
keras.layers.normalization'dan import BatchNormalization
keras.layers.convolutional import Conv2D'den
keras.layers.convolutional import MaxPooling2D'den
keras.layers.core'dan içe aktarma Etkinleştirme
keras.layers.core'dan içe aktarma Düzleştir
keras.layers.core'dan import Dropout
keras.layers.core'dan import Dense
keras'tan arka ucu K olarak içe aktar
sınıf LivenessNet:
@hayalhanemersin
def build (genişlik, yükseklik, derinlik, sınıflar):
# modeli giriş şekli ile birlikte başlat
# "kanal kalıcıdır" ve kanalın boyutu
model = Sıralı
inputShape = (yükseklik, genişlik, derinlik)
chanDim = -1
# "önce kanalları" kullanıyorsak, giriş şeklini güncelleyin
# ve kanal boyutu
K.image_data_format == "channel_first" ise:
inputShape = (derinlik, yükseklik, genişlik)
chanDim = 1
Keras paketinden gerekli tüm yöntemleri içe aktaracağız (2-10. Satırlar). Her bir ağ katmanı ve işlevi hakkında daha fazla bilgi edinmek istiyorsanız, lütfen "Python ile Bilgisayar Görü için Derin Öğrenme" (URL: https://www.pyimagesearch.com/deep-learning-computer-vision-python-book/ ).
12. satırda "LivenessNet" sınıfını tanımlamaya başlıyoruz. Statik bir kurucu "yapı" (satır 14) içerir. "Derleme" yöntemi dört girdi parametresini kabul eder:
"Genişlik": resmin / videonun genişliği
"Yükseklik": görüntünün yüksekliği
"Derinlik": görüntünün kanal sayısı (RGB görüntüleri kullanacağımız için bu örnekte derinlik 3'tür).
"Sınıflar": Algılama kategorilerinin sayısı. İki tür çıktı yüzümüz var: "gerçek" yüzler ve "sahte" yüzler.
17. satırda "model" i başlatıyoruz.
18. satır, modelin "inputShape" i tanımlar ve 23-25. Satırlar kanalların sırasını belirtir.
Aşağıda, evrişimli sinir ağına bazı ağ katmanı bileşenleri ekleyeceğiz:
# ilk DÖNÜŞ = > RELU = > CONV = > RELU = > HAVUZ katman seti
model.add (Conv2D (16, (3, 3), padding = "aynı",
input_shape = inputShape))
model.add (Etkinleştirme ("relu"))
model.add (BatchNormalization (eksen = chanDim))
model.add (Conv2D (16, (3, 3), dolgu = "aynı"))
model.add (Etkinleştirme ("relu"))
model.add (BatchNormalization (eksen = chanDim))
model.add (MaxPooling2D (pool_size = (2, 2)))
model.add (Bırakma (0,25))
# saniye CONV = > RELU = > CONV = > RELU = > HAVUZ katman seti
model.add (Conv2D (32, (3, 3), dolgu = "aynı"))
model.add (Etkinleştirme ("relu"))
model.add (BatchNormalization (eksen = chanDim))
model.add (Conv2D (32, (3, 3), dolgu = "aynı"))
model.add (Etkinleştirme ("relu"))
model.add (BatchNormalization (eksen = chanDim))
model.add (MaxPooling2D (pool_size = (2, 2)))
model.add (Bırakma (0,25))
Evrişimli sinir ağımız, VGGNet'in bazı özelliklerini gösterir. Sadece birkaç öğrenilmiş evrişim çekirdeği ile çok sığdır. İdeal olarak, gerçek yüzleri sahte yüzlerden ayırmak için derin bir ağ kullanmamız gerekmez.
28-36. Satırlar ilk "CONV = > RELU = > CONV = > RELU = > POOL "(evrişimli katman = > RELU aktivasyon işlevi katmanı = > Evrişimli katman = > RELU aktivasyon işlevi katmanı = > Havuzlama katmanı) Toplu normalleştirme katmanı ve bırakma katmanı da ekleyen ağ katmanı toplama.
39-46. Satırlar başka bir "CONV = > RELU = > CONV = > RELU = > POOL "(evrişimli katman = > RELU aktivasyon işlevi katmanı = > Evrişimli katman = > RELU aktivasyon işlevi katmanı = > Havuzlama katmanı) ağ katmanı koleksiyonu.
Sonunda "FC = > RELU "(tam bağlantı = > RELU aktivasyon işlevi katmanı) katmanı:
# ilk (ve tek) FC seti = > RELU katmanları
model.add (Düzleştir)
model.add (Yoğun (64))
model.add (Etkinleştirme ("relu"))
model.add (BatchNormalization)
model.add (Dropout (0.5))
# softmax sınıflandırıcı
model.add (Yoğun (sınıflar))
model.add (Etkinleştirme ("softmax"))
# inşa edilen ağ mimarisini döndür
dönüş modeli
49-57 satırları, tamamen bağlı bir katmandan, bir ReLU aktivasyon işlevi katmanından ve bir softmax sınıflandırıcı başlığından oluşur.
Modeli, 60. satırdaki eğitim komut dosyasına geri döndürün.
Şekil 6: LivenessNet eğitim süreci. Veri setimiz olarak hem "gerçek" yüzleri hem de "aldatıcı / sahte" yüz görüntülerini kullanarak, canlı bir algılama modeli eğitmek için OpenCV, Keras çerçevesi ve derin öğrenme teknolojisini kullanabiliriz.
Gerçek / aldatıcı yüz görüntüsü veri setimiz ve LivenessNet uygulamamız göz önüne alındığında, artık ağı eğitmeye hazırız:
Lütfen "train_liveness.py" dosyasını açın ve aşağıdaki kodu ekleyin:
# matplotlib arka ucunu ayarlayın, böylece rakamlar arka planda kaydedilebilir
ithal matplotlib
matplotlib.use ("Agg")
# gerekli paketleri içe aktarın
pyimagesearch.livenessnet'ten LivenessNet'i içe aktarın
sklearn.preprocessing adresinden LabelEncoder'ı içe aktar
sklearn.model_selection'dan import train_test_split
sklearn.metrics'den sınıflandırma içe aktarma
keras.preprocessing.image adresinden ImageDataGenerator içe aktarın
keras.optimizers'dan Adam'ı içe aktarın
keras.utils'ten np_utils'i içe aktar
imutils'den içe aktarma yollarından
matplotlib.pyplot dosyasını plt olarak içe aktar
numpy'yi np olarak içe aktar
ithal argparse
ithal turşu
cv2 içe aktar
işletim sistemini içe aktar
# bağımsız değişken çözümleyiciyi oluşturun ve bağımsız değişkenleri çözümleyin
ap = argparse.ArgumentParser
ap.add_argument ("- d", "--dataset", gerekli = Doğru,
help = "giriş veri kümesine giden yol")
ap.add_argument ("- m", "--model", tür = str, gerekli = Doğru,
help = "eğitilmiş modele giden yol")
ap.add_argument ("- l", "--le", tür = str, gerekli = Doğru,
help = "etiket kodlayıcı yolu")
ap.add_argument ("- p", "--plot", type = str, default = "plot.png",
help = "çıktı kaybı / doğruluk grafiğine giden yol")
args = vars (ap.parse_args)
Canlı yüz algılama komut dosyamız çok sayıda girdi sağlar (2-19. Satırlar). sırasıyla şunlardır:
"Matplotlib": Eğitim durumunun şematik bir diyagramını oluşturmak için kullanılır. 3. satırda, diyagramı diske kolayca yazabilmemiz için arka ucu "Agg" olarak belirtiyoruz.
"LivenessNet": Önceki bölümde tanımladığımız canlılığı algılayan evrişimli sinir ağı.
"Train_test_split": Eğitim ve test için bir veri bölümü oluşturan, scikit-learn'den tanıtılan bir işlev.
"Sınıflandırma_raporu": Scikit-learn'den getirilen ve modelimizin performansını açıklayan kısa bir istatistiksel rapor oluşturan bir işlev.
"ImageDataGenerator": Veri iyileştirme için kullanılır ve bize rastgele mutasyonla geliştirilmiş görüntü grupları sağlar.
"Adam": Bu model için çok uygun bir iyileştirici (isteğe bağlı seçenekler arasında Stokastik Gradyan İniş (SGD), RMSprop, vb. Bulunur).
"Yollar": "imutils" paketimden tanıtılan bu modül, diskteki tüm görüntü dosyalarının yollarını toplamamıza yardımcı olabilir.
"Pyplot": Güzel bir eğitim süreci diyagramı oluşturmak için kullanılır.
"Numpy": OpenCV için de gerekli olan Python için bir dijital işleme geliştirme kitaplığı.
"Argparse": komut satırı bağımsız değişkenlerini işlemek için kullanılır (ilgili okuma: https://www.pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/)
"Pickle": Etiket kodlayıcımızı serileştirmek ve diske yazmak için kullanılır.
"Cv2": OpenCV'yi bağlamak için kullanılır.
"Os": Bu modülün birçok işlevi vardır, ancak burada onu yalnızca işletim sistemi yol ayırıcıları oluşturmak için kullanıyoruz.
Giriş biraz fazla görünüyor, ancak bu girdilerin amacını anladıktan sonra, komut dosyasının geri kalanını kontrol etmek daha sezgisel olmalıdır.
Komut dosyası dört komut satırı parametresini kabul eder:
"--Veri Kümesi": Veri kümesinin yolunu girin. Bu veri kümesi, bu makalenin önceki bölümlerinde bulunan "collect_examples.py" komut dosyası kullanılarak oluşturuldu.
"--Model": Komut dosyamız bir çıktı modeli dosyası oluşturacak ve yolunu bu parametre aracılığıyla belirleyecektir.
"--Le": Serileştirilmiş etiket kodlayıcı dosyasını çıkarmak için gereken yol.
"--Plot": Eğitim komut dosyası, eğitim sürecinin şematik bir diyagramını oluşturacaktır. "Plot.png" varsayılan değerini geçersiz kılmak istiyorsanız, değeri komut satırında belirtmelisiniz.
Aşağıdaki kod bloğu bir dizi başlatma çalışması gerçekleştirecek ve verilerimizi oluşturacaktır:
# ilk öğrenme oranını, parti boyutunu ve
Eğitim yapılacak # dönem
INIT_LR = 1e-4
BS = 8
EPOCHS = 50
# veri kümesi dizinimizdeki görüntülerin listesini alın, ardından başlatın
# veri listesi (ör. resimler) ve sınıf resimleri
baskı ("resimler yükleniyor ...")
imagePaths = list (paths.list_images (değiştirgeler))
data =
etiketler =
imagePaths'te imagePath için:
# dosya adından sınıf etiketini çıkarın, resmi yükleyin ve
# en boy oranını göz ardı ederek sabit bir 32x32 piksel olacak şekilde yeniden boyutlandırın
label = imagePath.split (os.path.sep)
image = cv2.imread (imagePath)
image = cv2.resize (resim, (32, 32))
# sırasıyla veri ve etiket listelerini güncelleyin
data.append (resim)
tags.append (etiket)
# verileri bir NumPy dizisine dönüştürün, ardından ölçeklendirerek önceden işleyin
# aralığa göre tüm piksel yoğunlukları
data = np.array (data, dtype = "float") / 255.0
35-37. Satırlarda ayarlanan eğitim parametreleri, öğrenme oranını, parti boyutunu ve yineleme sayısını içerir.
Bu noktada, "iamgePaths" içindeki yolu elde ettik ve ayrıca "veri" ve sınıf "etiketleri" (42-44. Satırlar) depolamak için iki listeyi başlattık.
46-55. Satırlardaki döngü bir "veri" ve "etiket" listesi yaratır. "Veri" listesi yüklediğimiz ve 32 * 32 piksel olarak yeniden boyutlandırdığımız görüntülerden oluşur. Her görüntünün "etiketler" listesinde saklanan karşılık gelen bir etiketi vardır.
Her pikselin parlaklığı aralığa göre ölçeklendi ve listeyi 59. satırdaki NumPy dizisine dönüştürdük.
Sonra, etiketleri kodlayıp verileri böleceğiz:
# etiketleri (şu anda dizelerdir) tamsayı olarak kodlayın ve ardından
# onları tek seferde kodlayın
le = LabelEncoder
etiketler = le.fit_transform (etiketler)
etiketler = np_utils.to_categorical (etiketler, 2)
#% 75'i kullanarak verileri eğitim ve test bölümlerine ayırın
# eğitim verileri ve kalan% 25 test için
(trainX, testX, trainY, testY) = train_test_split (veriler, etiketler,
test_size = 0.25, random_state = 42)
63-65 satırları etiketi tek sıcak vektör olarak kodlar.
Verileri bölmek için scikit-learn kullanıyoruz - verilerin% 75'i eğitim için kullanılıyor ve kalan% 25'i test için ayrılıyor (satır 69 ve 70).
Daha sonra, veri artırma nesnemizi başlatacağız ve canlı yüz algılama modelimizi derleyip eğiteceğiz:
# Veri büyütme için eğitim görüntü oluşturucusunu oluşturun
aug = ImageDataGenerator (rotation_range = 20, zoom_range = 0,15,
width_shift_range = 0.2, height_shift_range = 0.2, kesme_aralığı = 0.15,
horizontal_flip = Doğru, fill_mode = "en yakın")
# optimize ediciyi ve modeli başlat
baskı ("model derleniyor ...")
opt = Adam (lr = INIT_LR, bozunma = INIT_LR / EPOCHS)
model = LivenessNet.build (genişlik = 32, yükseklik = 32, derinlik = 3,
sınıflar = len (le.classes_))
model.compile (loss = "binary_crossentropy", optimize edici = opt,
metrics =)
# ağı eğitin
print ("{} dönem için eğitim ağı ...". format (EPOCHS))
H = model.fit_generator (aug.flow (trainX, trainY, batch_size = BS),
validation_data = (testX, testY), steps_per_epoch = len (trainX) // BS,
epochs = EPOCHS)
73-75. satırlar, rasgele döndürme, ölçekleme, çevirme, kesme ve çevirme yoluyla yeni bir görüntü oluşturacak, verileri zenginleştirilmiş bir nesne oluşturur. Veri büyütme hakkında daha fazla bilgi edinmek için lütfen şu blog gönderisine bakın: https://www.pyimagesearch.com/2018/12/24/how-to-use-keras-fit-and-fit_generator-a- uygulamalı eğitim /
79-83. Satırlarda "LivenessNet" modelini oluşturduk ve derledik.
Daha sonra, modeli 87-89. Satırlarda eğitmeye başlıyoruz. Sığ ağlar ve küçük veri kümeleri kullandığımız için, bu süreç nispeten hızlı olacaktır.
Model eğitimi tamamlandığında, eğitim sonuçlarını değerlendirebilir ve eğitim sürecinin şematik bir diyagramını oluşturabiliriz:
# ağı değerlendirin
print ("ağ değerlendiriliyor ...")
tahminler = model.predict (testX, batch_size = BS)
print (sınıflandırma_raporu (testY.argmax (eksen = 1),
tahminler.argmax (axis = 1), target_names = le.classes_))
# ağı diske kaydedin
print ("ağ '{}' ...". format (değiştirgeler) olarak serileştiriliyor)
model.save (değiştirgeler)
# etiket kodlayıcıyı diske kaydedin
f = açık (bağımsız değişkenler, "wb")
f.write (pickle.dumps (le))
f.kapat
# eğitim kaybını ve doğruluğunu çizin
plt.style.use ("ggplot")
plt.figure
plt.plot (np.arange (0, EPOCHS), H.history, label = "tren_ kaybı")
plt.plot (np.arange (0, EPOCHS), H.history, label = "değer_ kaybı")
plt.plot (np.arange (0, EPOCHS), H.history, label = "train_acc")
plt.plot (np.arange (0, EPOCHS), H.history, label = "val_acc")
plt.title ("Veri Kümesinde Eğitim Kaybı ve Doğruluğu")
plt.xlabel ("Dönem #")
plt.ylabel ("Kayıp / Doğruluk")
plt.legend (loc = "alt sol")
plt.savefig (değiştirgeler)
93. satır, test setinde elde edilen tahmin sonuçlarını gösterir. Buna bağlı olarak, sınıflandırma sonucu raporu "sınıflandırma_raporu" oluşturulur ve terminalde görüntülenir (satır 94 ve 95).
"LivenessNet" modeli ve etiket kodlayıcı serileştirilir ve 99-104 satırlarında diske yazılır.
Kalan satır 107-117, gözden geçirme için eğitim sürecinin şematik bir diyagramını oluşturur.
Canlılık dedektörümüzü eğitmek
Şimdi, canlı dedektörü eğitmeye hazırız.
Lütfen bu eğiticinin "İndir" bölümündeki bağlantılardan kaynak kodunu ve veri kümesini indirdiğinizden emin olun. Ardından, lütfen aşağıdaki komutunuzu uygulayın:
$ python train.py --dataset veri kümesi --model liveness.model --le le.pickle
resimler yükleniyor ...
model derleniyor ...
50 devir eğitim ağı ...
1/50 Yaş
29/29 - 2s 58ms/step - loss: 1.0113 - acc: 0.5862 - val_loss: 0.4749 - val_acc: 0.7436
Epoch 2/50
29/29 - 1s 21ms/step - loss: 0.9418 - acc: 0.6127 - val_loss: 0.4436 - val_acc: 0.7949
Epoch 3/50
29/29 - 1s 21ms/step - loss: 0.8926 - acc: 0.6472 - val_loss: 0.3837 - val_acc: 0.8077
...
Epoch 48/50
29/29 - 1s 21ms/step - loss: 0.2796 - acc: 0.9094 - val_loss: 0.0299 - val_acc: 1.0000
Epoch 49/50
29/29 - 1s 21ms/step - loss: 0.3733 - acc: 0.8792 - val_loss: 0.0346 - val_acc: 0.9872
Epoch 50/50
29/29 - 1s 21ms/step - loss: 0.2660 - acc: 0.9008 - val_loss: 0.0322 - val_acc: 0.9872
evaluating network...
precision recall f1-score support
fake 0.971.000.9935
real 1.000.980.9943
micro avg 0.990.990.9978
macro avg 0.990.990.9978
weighted avg 0.990.990.9978
serializing network to 'liveness.model'...
6 OpenCVKeras
99%
7 OpenCV
1. /
2.
3.
liveness_demo.py
# import the necessary packages
from imutils.video import VideoStream
from keras.preprocessing.image import img_to_array
from keras.models import load_model
numpy'yi np olarak içe aktar
import argparse
import imutils
ithal turşu
ithalat zamanı
import cv2
işletim sistemini içe aktar
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser
ap.add_argument("-m", "--model", type=str, required=True,
help="path to trained model")
ap.add_argument("-l", "--le", type=str, required=True,
help="path to label encoder")
ap.add_argument("-d", "--detector", type=str, required=True,
help="path to OpenCV's deep learning face detector")
ap.add_argument("-c", "--confidence", type=float, default=0.5,
help="minimum probability to filter weak detections")
args = vars(ap.parse_args)
2-11
VideoStream
img_to_array
load_model Keras
imutils
cv2 OpenCV
14-23
--model Keras
--le
--detector ROI OpenCV
--confidence
LivenessNet +
# load our serialized face detector from disk
print(" loading face detector...")
protoPath = os.path.sep.join()
modelPath = os.path.sep.join()
net = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
# load the liveness detector model and label encoder from disk
print(" loading liveness detector...")
model = load_model(args)
le = pickle.loads(open(args, "rb").read)
# initialize the video stream and allow the camera sensor to warmup
print(" starting video stream...")
vs = VideoStream(src=0).start
time.sleep(2.0)
27-30 OpenCV
LivenessNet 34-35
39 40 VideoStream 2
/
# loop over the frames from the video stream
True iken:
# grab the frame from the threaded video stream and resize it
# to have a maximum width of 600 pixels
frame = vs.read
frame = imutils.resize(frame, width=600)
# grab the frame dimensions and convert it to a blob
(h, w) = frame.shape
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
# pass the blob through the network and obtain the detections and
# predictions
net.setInput(blob)
detections = net.forward
43 while46 47
50
OpenCV blobFromImagehttps://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/blob 51 52 56 57
OpenCV
# loop over the detections
for i in range(0, detections.shape):
# extract the confidence (i.e., probability) associated with the
# prediction
confidence = detections
# filter out weak detections
if confidence > args:
# compute the (x, y)-coordinates of the bounding box for
# the face and extract the face ROI
box = detections * np.array()
(startX, startY, endX, endY) = box.astype("int")
# ensure the detected bounding box does fall outside the
# dimensions of the frame
startX = max(0, startX)
startY = max(0, startY)
endX = min(w, endX)
endY = min(h, endY)
# extract the face ROI and then preproces it in the exact
# same manner as our training data
face = frame
face = cv2.resize(face, (32, 32))
face = face.astype("float") / 255.0
face = img_to_array(face)
face = np.expand_dims(face, axis=0)
# pass the face ROI through the trained liveness detector
# model to determine if the face is "real" or "fake"
preds = model.predict(face)
j = np.argmax(preds)
label = le.classes_
# draw the label and bounding box on the frame
label = "{}: {:.4f}".format(label, preds)
cv2.putText(frame, label, (startX, startY - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.rectangle(frame, (startX, startY), (endX, endY),
(0, 0, 255), 2)
60
63-66
box 69-77
ROI 81-85
/ 89-91
91 if label == "real": run_face_reconition 91
labelrectangle 94-98
# show the output frame and wait for a key press
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) and 0xFF
# if the `q` key was pressed, break from the loop
if key == ord("q"):
kırmak
# do a bit of cleanup
cv2.destroyAllWindows
vs.stop
101-102 qquit 105-110
$ python liveness_demo.py --model liveness.model --le le.pickle \
--detector face_detector
Using TensorFlow backend.
loading face detector...
loading liveness detector...
starting video stream...
311 161 150
/
/
/
)
OpenCV
OpenCV Python
vs
1.
2. /
3.
LivenessNet Keras
1.
2.
99%
Python + OpenCV
OpenCV
https://www.getdrip.com/forms/321809846/submissions
via https://www.pyimagesearch.com/2019/03/11/liveness-detection-with-opencv