背景
公司的門禁,通過(guò)識(shí)別檢測(cè)嚷兔,如果是公司的員工森渐,就開(kāi)門,否則不開(kāi)門冒晰。用的是百度的人臉識(shí)別技術(shù)實(shí)現(xiàn)此迅。突然公司要自研(畢竟百度是收費(fèi)的)锋华,也許要彰顯公司的技術(shù)實(shí)力恤筛。任務(wù)分配給我祟偷,我一個(gè)搞Java的彩郊,Java并不擅長(zhǎng)圖片的處理前弯,調(diào)研下,python比較適合做這方面場(chǎng)景的應(yīng)用秫逝,但是我對(duì)python恕出,只能說(shuō)了解,并不熟練违帆,腫么辦呢浙巫?盡然給我了,當(dāng)做學(xué)習(xí)了刷后,硬著頭皮就上的畴。
技術(shù)調(diào)研
谷歌是最好的老師,搜索下尝胆,找找這方面的資料丧裁。但是心里面也得想想大概的流程,第一步含衔,我怎么才能檢測(cè)出圖片上煎娇,有沒(méi)有人呢二庵,這是比較關(guān)鍵的一步,經(jīng)過(guò)搜索比對(duì)缓呛,發(fā)現(xiàn)insightface催享,能識(shí)別出圖片上,有沒(méi)有人哟绊。那圖片上檢測(cè)出人因妙,剩下的就是圖片上的人,跟目標(biāo)圖片比對(duì)下匿情,看兩個(gè)人的相似度是多少兰迫,設(shè)置一個(gè)閥值,達(dá)到這個(gè)值就是一個(gè)人炬称,然后告訴門禁汁果,開(kāi)門,萬(wàn)事大吉玲躯,搞定据德。理一理流程,流程如下:
insightface介紹
InsightFace 是一個(gè)開(kāi)源的 2D 和 3D 深度人臉?lè)治龉ぞ呦漉纬担饕?PyTorch 和 MXNet棘利。
詳情查看網(wǎng)站。
InsightFace 有效地實(shí)現(xiàn)了豐富多樣的人臉識(shí)別朽缴、人臉檢測(cè)和人臉對(duì)齊的最新算法善玫,并對(duì)訓(xùn)練和部署進(jìn)行了優(yōu)化。
環(huán)境搭建
前提先要安裝python密强,python版本3.6以上茅郎,安裝下面的庫(kù)
# 安裝人臉識(shí)別包
# 人臉識(shí)別庫(kù)
pip install -U insightface
# 圖片處理的庫(kù)
pip install opencv-python
識(shí)別人臉
import cv2
from insightface.app import FaceAnalysis
# 加載人臉識(shí)別模型
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
# 讀取圖片
img = cv2.imread("./test.jpeg")
# 獲取人臉數(shù)據(jù)
faces = app.get(img)
# 把圖片中的人臉圈出來(lái)
rimg = app.draw_on(img, faces)
# 對(duì)圖片中的人臉處理后保存
cv2.imwrite('./t1_output.jpg', rimg)
測(cè)試圖片
識(shí)別后的效果
那現(xiàn)在我們準(zhǔn)確的識(shí)別出測(cè)試圖片里面有三個(gè)人,同時(shí)標(biāo)識(shí)出人臉的位置或渤。其實(shí)系冗,提出人臉數(shù)據(jù)是一些圖片像素點(diǎn),人臉識(shí)別出來(lái)了薪鹦,那接下來(lái)掌敬,就只需要,識(shí)別出池磁,圖片里的人臉是誰(shuí)奔害,完成了檢測(cè)比對(duì)
人臉比對(duì)
錄入人臉數(shù)據(jù)
需要提前錄入人臉,進(jìn)行識(shí)別地熄,提取人臉數(shù)據(jù)舀武,進(jìn)行存儲(chǔ),存儲(chǔ)可以本地文件存儲(chǔ)离斩,也可以使用向量數(shù)據(jù)庫(kù)存儲(chǔ)银舱,比如:milvus瘪匿,此代碼演示使用pickle進(jìn)行本地存儲(chǔ),需要提前安排庫(kù)寻馏,
pip install pickle4
圖片數(shù)據(jù)
我們準(zhǔn)備了楊紫棋弥、景甜的照片,也可以自己找其他圖片進(jìn)行測(cè)試
注冊(cè)的核心代碼
import pickle
from numpy.linalg import norm
import cv2
import numpy as np
from insightface.app import FaceAnalysis
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
faces_embedding = list()
# # 使用本地人家存儲(chǔ)
f = open('./face_ai_db', 'wb')
# 讀取照片
img1 = cv2.imread("./楊紫.jpeg")
# 提取人臉數(shù)據(jù)
yzFace = app.get(img1)
# 楊紫人臉數(shù)據(jù)加入到列表中
faces_embedding.append({"userName":"楊紫","embedding":yzFace[0].normed_embedding})
# 讀取景甜的照片
img2 = cv2.imread("./景甜.jpeg")
# 提取楊紫的人臉數(shù)據(jù)
jtFace = app.get(img2)
# 景甜人臉數(shù)據(jù)加入到列表中
faces_embedding.append({"userName":"景甜","embedding":jtFace[0].normed_embedding})
pickle.dump(faces_embedding,f)
f.close()
執(zhí)行此程序诚欠,楊紫顽染、景甜提取的人臉數(shù)據(jù)已經(jīng)存在,本地文件 face_ai_db文件中
對(duì)目標(biāo)圖片進(jìn)行識(shí)別
對(duì)目標(biāo)圖片轰绵,進(jìn)行識(shí)別粉寞,找出里面有沒(méi)有庫(kù)里的人
import pickle
from numpy.linalg import norm
import cv2
import numpy as np
from insightface.app import FaceAnalysis
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
# 使用本地人家存儲(chǔ)
f = open('./face_ai_db', 'rb')
# 加載前面存儲(chǔ)的人臉數(shù)據(jù)
faces_embedding = pickle.load(f)
# 讀取圖片
img = cv2.imread("./test.jpeg")
# 圖片里面有多個(gè)人,faces就有多個(gè)值左腔,是個(gè)數(shù)組
faces = app.get(img)
# 用提取的每一張人臉去跟庫(kù)里面的人臉數(shù)據(jù)比對(duì)唧垦,檢測(cè)出是否有庫(kù)里的注冊(cè)的人
for face in faces:
feat1 = face.normed_embedding
for t in faces_embedding:
feat2 = t["embedding"]
# 余弦相似度比較
sim = np.dot(feat1, feat2) / (norm(feat1) * norm(feat2))
sim = sim * 100
# 設(shè)置一個(gè)閾值,就是分?jǐn)?shù)液样,大于40振亮,就得到我們庫(kù)里的人,打印下分?jǐn)?shù) 以及是哪個(gè)明星
if sim >40:
print("姓名:{},分?jǐn)?shù);{}".format(t['userName'],sim))
測(cè)試結(jié)果:準(zhǔn)確的識(shí)別出圖片人
姓名:景甜,分?jǐn)?shù);64.38514590263367
姓名:楊紫,分?jǐn)?shù);44.4240003824234
這就簡(jiǎn)單實(shí)現(xiàn)了鞭莽,人臉的檢測(cè)識(shí)別坊秸,文章對(duì)你有幫助,麻煩點(diǎn)贊關(guān)注澎怒,謝謝褒搔,后續(xù)會(huì)繼續(xù)分享。