訂閱
糾錯
加入自媒體

亞馬遜門鈴系統(tǒng)上的人臉識別是如何實現(xiàn)的?


加載模型的代碼很簡單。模型存儲在目錄model/files/中。from tensorflow.keras.models import load_model

model = load_model('model/facenet_keras.h5')

開發(fā)一個模型來概括它以前從未見過的面孔是很困難的。FaceNet模型是在MS-Celeb-1M數(shù)據(jù)集上訓(xùn)練的,該數(shù)據(jù)集包含100萬張不同名人的照片。通過對同一個人的圖像組進(jìn)行L2歸一化,以及余弦相似函數(shù),F(xiàn)aceNet能夠產(chǎn)生令人難以置信的高識別精度。我發(fā)明了一種方便的方法來登記你家人的面孔,運行submit_face.py,并傳遞參數(shù)“name”(要注冊的人的名字)。另外,為了提高準(zhǔn)確性和匹配照明條件,你可以使用布爾參數(shù)“from_door”,如果為真,將直接從你的門鈴的最后錄制的視頻中保存圖像。這些圖像被存儲在目錄data/faces/中。用MTCNN人臉檢測對它們進(jìn)行預(yù)裁剪。檢測方法將在稍后顯示,它是face_recognition.py的一部分。對于拍到的視頻,我抓取了視頻的特定幀,并測試哪些幀可以工作。我們將需要做一些圖像預(yù)處理,以及其他小的函數(shù),我將在utils.py中定義:import cv2
def normalize(img):
   mean, std = img.mean(), img.std()
   return (img - mean) / (std + 1e-7)
def preprocess(cv2_img):
   cv2_img = normalize(cv2_img)
   cv2_img = cv2.resize(cv2_img, (160, 160))
   return cv2_img
def get_specific_frames(video_path, times):
   vidcap = cv2.VideoCapture(video_path)
   frames = []
   for time in times:
       vidcap.set(1, time * 15)
       success, image = vidcap.read()
       if success:
           frames.a(chǎn)ppend(image)
   return frames

一旦你想要識別的每個人的圖像都在目錄data/faces/中,我們就可以將其轉(zhuǎn)換為編碼。我們把這作為單獨的一步,因為我們L2標(biāo)準(zhǔn)化了每個人對應(yīng)的所有圖像。import os
from utils import preprocess
import cv2
import numpy as np
from sklearn.preprocessing import Normalizer
import face_recognition
import pickle
encoding_dict = {}
l2_normalizer = Normalizer('l2')
for face_names in os.listdir('data/faces/'):
   person_dir = os.path.join('data/faces/', face_names)
   encodes = []
   for image_name in os.listdir(person_dir):
       image_path = os.path.join(person_dir, image_name)
       face = cv2.imread(image_path)
       face = preprocess(face)
       encoding = face_recognition.encode(face)
       encodes.a(chǎn)ppend(encoding)
   if encodes:
       encoding = np.sum(encodes, axis=0)
       encoding = l2_normalizer.transform(np.expand_dims(encoding, axis=0))[0]
       encoding_dict[face_names] = encoding
path = 'data/encodings/encoding.pkl'
with open(path, 'wb') as file:
   pickle.dump(encoding_dict, file)

預(yù)處理函數(shù)是我用來標(biāo)準(zhǔn)化圖像并將其重塑為(160,160,3)的函數(shù),而識別函數(shù)是一個執(zhí)行編碼函數(shù)的類。如果你注意到了,我將這些編碼保存為字典。在執(zhí)行實時識別時,這個字典很方便,因為它是存儲人名和編碼的一種簡單方法。實時人臉識別現(xiàn)在我們有了我們想要識別的人的圖像,那么實時識別過程是如何工作的呢?如下圖所示:

門鈴響時,下載一個視頻,選擇多個幀。利用這些幀,用detect_faces方法進(jìn)行多實例的人臉檢測。下面是face_recognition.py 類的一個片段:import cv2
import mtcnn
face_detector = mtcnn.MTCNN()
conf_t = 0.99
def detect_faces(cv2_img):
   img_rgb = cv2.cvtColor(cv2_img, cv2.COLOR_BGR2RGB)
   results = face_detector.detect_faces(img_rgb)
   faces = []
   for res in results:
       x1, y1, width, height = res['box']
       x1, y1 = abs(x1), abs(y1)
       x2, y2 = x1 + width, y1 + height
       confidence = res['confidence']
       if confidence < conf_t:
           continue
       faces.a(chǎn)ppend(cv2_img[y1:y2, x1:x2])
   return faces
def detect_face(cv2_img):
   img_rgb = cv2.cvtColor(cv2_img, cv2.COLOR_BGR2RGB)
   results = face_detector.detect_faces(img_rgb)
   x1, y1, width, height = results[0]['box']
   cv2.waitKey(1)
   x1, y1 = abs(x1), abs(y1)
   x2, y2 = x1 + width, y1 + height
   confidence = results[0]['confidence']
   if confidence < conf_t:
       return None
   return cv2_img[y1:y2, x1:x2]

對圖像進(jìn)行預(yù)處理并送入FaceNet。FaceNet將輸出每個人臉的128維嵌入。然后使用余弦相似度將這些向量與encode .pkl中存儲的向量進(jìn)行比較。人臉與輸入人臉最接近的人被返回。如果一張臉距離它最近的臉有一個特定的閾值,則返回“未知”。這表明這張臉不像任何已知的臉。下面是face_recognition.py類的其余部分:from utils import preprocess
from model.facenet_loader import model
import numpy as np
from scipy.spatial.distance import cosine
import pickle
from sklearn.preprocessing import Normalizer
l2_normalizer = Normalizer('l2')
def encode(img):
   img = np.expand_dims(img, axis=0)
   out = model.predict(img)[0]
   return out
def load_database():
   with open('data/encodings/encoding.pkl', 'rb') as f:
       database = pickle.load(f)
   return database
recog_t = 0.35
def recognize(img):
   people = detect_faces(img)
   if len(people) == 0:
       return None
   best_people = []
   people = [preprocess(person) for person in people]
   encoded = [encode(person) for person in people]
   encoded = [l2_normalizer.transform(encoding.reshape(1, -1))[0]
              for encoding in encoded]
   database = load_database()
   for person in encoded:
       best = 1
       best_name = ''
       for k, v in database.items():
           dist = cosine(person, v)
           if dist < best:
               best = dist
               best_name = k
       if best > recog_t:
           best_name = 'UNKNOWN'
       best_people.a(chǎn)ppend(best_name)
   return best_people

這樣就完成了大部分的識別任務(wù)。語音合成我想知道誰在門口。一開始,我以為在鈴聲設(shè)備上播放聲音是最佳策略,但亞馬遜不允許我這么做,只允許我播放鈴聲伴隨的默認(rèn)聲音。因此,從文本到語音似乎是一種更合適的方式。這可以通過兩個包GTTS和playsound來簡化。GTTS使用谷歌的Tacotron 2模型。雖然完全理解它的工作原理并不重要,但對于感興趣的讀者來說,該圖說明了它的架構(gòu)

Tacotron與Seq2Seq非常相似,但是它使用了雙向LSTM、卷積層、預(yù)網(wǎng)絡(luò)層,以及最重要的2D生成輸入到解碼器(光譜圖)。如果你想了解更多關(guān)于Tacotron 2的內(nèi)容,這里有一個由CodeEmporium制作的關(guān)于這個主題的視頻。https://www.youtube.com/watch?v=le1LH4nPfmE&ab_channel=CodeEmporium雖然Tacotron 2算不上是最好的,尤其是與transformer 模型相比,但它確實做到了。使用GTTS python API的方法如下:from gtts import gTTS
from playsound import playsound
language = 'en'
slow_audio_speed = False
filename = 'tts_file.mp3'
def text_to_speech(text):
   audio_created = gTTS(text=text, lang=language,
                        slow=slow_audio_speed)
   audio_created.save(filename)
   playsound(filename)

很簡單。我使用playsound而不是os.system的原因是,os.system將默認(rèn)打開默認(rèn)的聲音播放器應(yīng)用程序,而playsound不會彈出任何窗口。這就完成了項目的最后一個步驟?偨Y(jié)和Git存儲庫請在這里查看我的git存儲庫,以獲得完整的代碼,并輕松地定制你自己的門鈴。https://github.com/dude123studios/SmarterRingV2在README.md中查看說明,并解釋在你自己的家里使用這個系統(tǒng)的確切步驟。只需要5分鐘就可以安裝好!亞馬遜,把它放進(jìn)你的下一個門鈴里!進(jìn)一步的探索和問題FaceNet是一個相當(dāng)過時的模式。在過去的五年里,在transformer模型方面有了重大發(fā)現(xiàn),例如ViT。GPT-3是一個概括之神。完成創(chuàng)建廣義嵌入的任務(wù)后,GPT-3之類的轉(zhuǎn)換器會更好地工作嗎?卷積神經(jīng)網(wǎng)絡(luò)可能不是面部識別的最佳選擇,因為長期依賴關(guān)系(如耳朵或下顎線)需要龐大的網(wǎng)絡(luò)。另一方面,transformer模型可以考慮到自相似性,并且實時進(jìn)行人臉識別的速度要快得多。

圖片標(biāo)題

<上一頁  1  2  
聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯
x
*文字標(biāo)題:
*糾錯內(nèi)容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網(wǎng)安備 44030502002758號