重磅!!!!代碼來了~~~~
連續更新的第二篇,這邊是上一篇的續集,在這里我已經假設你已經完成了,上一篇的環境安裝的作業,今天我們就來手撕代碼,注入靈魂,今天正式就進入代碼篇了,我局的我已經把代碼掰開揉碎了來講了,大家肯定看的明白,
所以先不啰嗦,直接先把代碼提貼出來,一共兩個腳本,一個是收集人臉特征的代碼,一個是判斷人臉相似度的代碼,在這之前還是先貼出一張檢測后的圖片,目的是為了吸引觀眾朋友們,

1.收集人臉特征的代碼
import cv2
import dlib
import os
import numpy as np
def drawrec_drawdot(shape,image):
landmarks = shape.parts()
landmarks = np.matrix([[p.x, p.y] for p in landmarks])
#畫圖
for idx, point in enumerate(landmarks):
# 68點的坐標
pos = (point[0, 0], point[0, 1])
# 利用cv2.circle給每個特征點畫一個圈,共68個
cv2.circle(image, pos, 2, color=(0, 255, 0), thickness=3)
# 利用cv2.putText輸出1-68
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(image, str(idx + 1), None, font, 0.8, (0, 0, 255), 1, cv2.LINE_AA)
return image
if __name__ == '__main__':
#定義圖片檔案夾路徑
folder_path = r'D:\DATAS\manhua\manhua_tou'
upper_path = '\\'.join(folder_path.split('\\')[:-1])
numpy_data_save_folder = os.path.join(upper_path,'TENSOR')
output_image_folder = os.path.join(upper_path,'OUTPUT')
if not os.path.exists(numpy_data_save_folder):
os.makedirs(numpy_data_save_folder)
if not os.path.exists(output_image_folder):
os.makedirs(output_image_folder)
#定義定位人臉的定位器
detector = dlib.get_frontal_face_detector()
#定義檢測人臉特征點的檢測器
predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")
feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')
for i in os.listdir(folder_path):
for j in os.listdir(os.path.join(folder_path, i)):
# 圖片路徑
image_path = os.path.join(folder_path, i, j)
image = cv2.imread(image_path)
# 獲取人臉坐標
locations = detector(image)
if len(locations) != 0:
for location in locations:
#獲取64個特征點
shape_64 = predictor(image,location)
#將64個特征點轉變成128維的向量
face_descriptor = feature_value_detctor.compute_face_descriptor(image, shape_64)
value_128 = np.array(face_descriptor)
# print(value_128)
np.save(numpy_data_save_folder + '/' + image_path.split('\\')[-1].split('.')[0],value_128)
# 畫人臉位置和64個特征點
draw_image = drawrec_drawdot(shape_64,image)
# 保存影像
cv2.imwrite(os.path.join(output_image_folder,j),draw_image)
從主函式看起:
1.1定義圖片檔案和創建兩個必要的檔案夾
if __name__ == '__main__':
#定義圖片檔案夾路徑
folder_path = r'D:\DATAS\manhua\manhua_tou'
upper_path = '\\'.join(folder_path.split('\\')[:-1])
numpy_data_save_folder = os.path.join(upper_path,'TENSOR')
output_image_folder = os.path.join(upper_path,'OUTPUT')
if not os.path.exists(numpy_data_save_folder):
os.makedirs(numpy_data_save_folder)
if not os.path.exists(output_image_folder):
os.makedirs(output_image_folder)
首先我定義了一個檔案夾路徑 folder_path,它是圖片所在的檔案夾,這個檔案下,是這樣的

以人的名稱直接來命名,因為我的資料集只有pangpang和shouhsou,所以只有兩個子檔案夾,還是給大家看看里面吧,哈哈,別羨慕,題外話了,哈哈,


里面的圖片最好也以人的名稱命名,方便以后操作
好了,好了,說回代碼
然后我又定義了一個numpy_data_save_folder 和 output_image_folder,然后創建了這個兩個檔案夾,以便后面程式往這兩個檔案中生成檔案,
1.2定義人臉定位器和檢測器
#定義定位人臉的定位器
detector = dlib.get_frontal_face_detector()
#定義檢測人臉特征點的檢測器
predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")
feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')
這個你就看到了,昨天我的那篇文章讓你配置環境的重要性了吧,我在這里再提供一下,下載路徑
鏈接:https://pan.baidu.com/s/1PReHKPiG0ZSCXTiy75TtCQ
提取碼:dbr5
夠意思了吧,
簡單說一下,detector 是用于定位人臉位置的,predictor是用于檢測人臉的64個特征點的,feature_value_detctors是用于將64個特征點轉變成128維向量的工具
1.3遍歷讀圖,進行檢測,存盤人臉128維特征向量和檢測圖
for i in os.listdir(folder_path):
for j in os.listdir(os.path.join(folder_path, i)):
# 圖片路徑
image_path = os.path.join(folder_path, i, j)
image = cv2.imread(image_path)
# 獲取人臉坐標
locations = detector(image)
if len(locations) != 0:
for location in locations:
#獲取64個特征點
shape_64 = predictor(image,location)
#將64個特征點轉變成128維的向量
face_descriptor = feature_value_detctor.compute_face_descriptor(image, shape_64)
value_128 = np.array(face_descriptor)
# print(value_128)
np.save(numpy_data_save_folder + '/' + image_path.split('\\')[-1].split('.')[0],value_128)
# 畫人臉位置和64個特征點
draw_image = drawrec_drawdot(shape_64,image)
# 保存影像
cv2.imwrite(os.path.join(output_image_folder,j),draw_image)
先利用os庫來找到圖片的路徑,然后讀圖,這兩步都沒問題吧,默認沒問題
locations = detector(image)
這一行代碼,就是在定位圖片中人臉的位置了,圖片上有幾個人,會定位到幾個,所以你看我命名的時候用用的locations,有一個‘s’,表示多個,哈哈,嚴謹!
shape_64 = predictor(image,location)
這一行代碼就是提取人臉的64個特征點了,文章最開頭的那張美女圖上的那些綠點就是畫上去的特征點,不是麻子,應該沒問題吧
face_descriptor = feature_value_detctor.compute_face_descriptor(image, shape_64)
這一行代碼就是把64個特征點變成128維的向量,我們來看看這個128維向量長什么樣子吧

這絕對是128個數,不信你數一數,
np.save(numpy_data_save_folder + '/' + image_path.split('\\')[-1].split('.')[0],value_128)
# 畫人臉位置和64個特征點
draw_image = drawrec_drawdot(shape_64,image)
# 保存影像
cv2.imwrite(os.path.join(output_image_folder,j),draw_image)
這個時候1.1里面個建立的兩個檔案夾就派上用場了,他們一個用來存盤128維度的資料,一個用來保存生成后的圖,運行腳本完成后,如下

看看里面


這個npy檔案存盤的numpy格式的資料
好了,收集人臉特征到這里就結束了,大家一起來試一試吧,
2.判斷人臉相似度
老規矩,先上代碼
import cv2
import dlib
import os
import numpy as np
def load_tensor(tensor_folder):
feature_list = [] # 用于存放人物128維特征值串列
class_name = [] # 用于存放類別資訊
for i in os.listdir(tensor_folder):
tensor_path = os.path.join(tensor_folder,i)
tensor = np.load(tensor_path)
feature_list.append(tensor)
class_name.append(tensor_path.split('\\')[-1].split('.')[0])
return feature_list,class_name
if __name__ == '__main__':
#--------------init--------------------------
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")
feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')
#-------------加載資訊------------------------
tensor_folder = r'D:\DATAS\manhua\TENSOR'
feature_list, class_name = load_tensor(tensor_folder)
#-------------開始測驗------------------------
test_image_path = r'D:\DATAS\test\pangpang (28).jpg'
test_image = cv2.imread(test_image_path)
locations = detector(test_image)
dist = []
for k, loc in enumerate(locations):
shape = predictor(test_image, loc)
face_descriptor = feature_value_detctor.compute_face_descriptor(test_image, shape)
d_test = np.array(face_descriptor)
for i in feature_list: #計算距離
distance = np.linalg.norm(i-d_test)
dist.append(distance)
distance_dict = dict(zip(class_name, dist))
distance_sorted = sorted(distance_dict.items(), key=lambda x:x[1])
print ("識別到的人物最有可能是: ",distance_sorted[0][0].split('(')[0])
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(test_image, distance_sorted[0][0].split('(')[0], (int(test_image.shape[0]//2)-50,test_image.shape[1]-50), font, 0.8, (0, 0, 255), 3, cv2.LINE_AA)
cv2.imshow('test_image', test_image)
cv2.waitKey()
2.1 定義人臉定位器和檢測器和加載剛剛提取的人臉特征資料
if __name__ == '__main__':
#--------------init--------------------------
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")
feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')
#-------------加載資訊------------------------
tensor_folder = r'D:\DATAS\manhua\TENSOR'
feature_list, class_name = load_tensor(tensor_folder)
我們來看看 load_tensor 這個函式
def load_tensor(tensor_folder):
feature_list = [] # 用于存放人物128維特征值串列
class_name = [] # 用于存放類別資訊
for i in os.listdir(tensor_folder):
tensor_path = os.path.join(tensor_folder,i)
tensor = np.load(tensor_path)
feature_list.append(tensor)
class_name.append(tensor_path.split('\\')[-1].split('.')[0])
return feature_list,class_name
傳入的引數是 tensor_folder,這個引數就是剛剛第一個程式里創建的那個TENSOR檔案夾的路徑
最后回傳值是,所有的128維特征的串列和特征對應的類別,也是pangpang或者shoushou,
2.2開始檢測求歐氏距離
test_image_path = r'D:\DATAS\test\pangpang (28).jpg'
test_image = cv2.imread(test_image_path)
locations = detector(test_image)
dist = []
for k, loc in enumerate(locations):
shape = predictor(test_image, loc)
face_descriptor = feature_value_detctor.compute_face_descriptor(test_image, shape)
d_test = np.array(face_descriptor)
for i in feature_list: #計算距離
distance = np.linalg.norm(i-d_test)
dist.append(distance)
test_image_path 是你要用來測驗的圖片的路徑,然后就是先得到測驗圖的128維度的特征向量,然后計算這個向量和你剛剛第一個程式里面保存的那些特征向量的歐式距離,np.linalg.norm 這個函式就是用來求歐式距離的,i-d_test,就是兩個向量之間的差值,np.linalg.norm就是實作

這么說吧,v1是一個128維度的向量,v2是一個128維度的向量,要求得他們的歐氏距離
此時,這里面的x1就相當于v1[0]-v2[0],這么說清晰了吧,你要是還是想不明白,你就想想初中數學,求直角坐標系中的任意兩點p1,p2的距離怎么求,p1點坐標(x1,y1),拍p2點坐標(x2,y2)
![]()
這樣說應該清楚了吧,這樣就求到了,這個測驗圖的128維度特征向量和之前每個128維特征向量的距離了,保存成了一個了串列dist
2.3開始求最小的距離
距離也就意味著最為相似,這樣我們就認為他們是同一個人,
distance_dict = dict(zip(class_name, dist))
distance_sorted = sorted(distance_dict.items(), key=lambda x:x[1])
print ("識別到的人物最有可能是: ",distance_sorted[0][0].split('(')[0])
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(test_image, distance_sorted[0][0].split('(')[0], (int(test_image.shape[0]//2)-50,test_image.shape[1]-50), font, 0.8, (0, 0, 255), 3, cv2.LINE_AA)
cv2.imshow('test_image', test_image)
cv2.waitKey()
2.4結果展示

到這里,基于dlib的人臉識別就此結束了,接下來我們要用手動搭建網路的網路的方式,進行深度學習訓練的方式來判定人臉的類別了,敬請期待
至此,敬禮,salute!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292632.html
標籤:AI
上一篇:《深度卷積神經網路原理與實踐》筆記 第一章 機器學習基礎
下一篇:Billu_b0x靶機滲透
