天天看點

用mtcnn+keras+facenet實作簡易的人臉識别人工智能-人臉識别

人工智能-人臉識别

采用mtcnn+keras+facenet深度學習算法

文章目錄

  • 人工智能-人臉識别
    • 采用mtcnn+keras+facenet深度學習算法
        • 前言:
          • 在前段時間的挑闆杯和網際網路+的雙賽中,我們和校企合作的項目疲勞駕駛檢測預警,在經專家點評後發現其中的人臉識别功能算法需要完善,是以經過多方學習,根據哔站大牛[**Bubbliiiing**](https://space.bilibili.com/472467171)的項目,決定用python來實作簡單的人臉檢測和識别
        • 環境介紹:
          • 基礎環境:
        • 代碼結構
        • 核心代碼:
        • 核心原理:
          • 附:論文下載下傳位址:
        • 實作步驟:
        • 實作結果
        • 代碼位址:
        • 緻謝:

前言:

在前段時間的挑闆杯和網際網路+的雙賽中,我們和校企合作的項目疲勞駕駛檢測預警,在經專家點評後發現其中的人臉識别功能算法需要完善,是以經過多方學習,根據哔站大牛Bubbliiiing的項目,決定用python來實作簡單的人臉檢測和識别

環境介紹:

采用主流的深度學習算法tensorflow-gpu、opencv、keras 、mtcnn、facenet等
           
基礎環境:

​ tensorflow-gpu==1.15.0

​ keras ==2.1.5

​ opencv-python==3.4.3

有關tensorflow的相關說明:

​ 注釋:[安裝tensorflow注意安裝的是gpu版本,如果用cpu版本會使電腦cpu跑滿,影響運作速度(在tensorflow2.0版本之後gpu和cpu版本整合在一起,需要手動去切換)安裝gpu版本時需要提前安裝其對應版本的附屬環境cuda和cudnn,如果版本出不比對,則還是用cpu跑程式,詳細安裝可參考win10安裝tensorflow(GPU版本)]

​ 1、檢驗tensorflow是否安裝成功:

import tensorflow as tf
	# Create TensorFlow object called tensor
	hello_constant = tf.constant('Hello World!')

	with tf.Session() as sess:
    # Run the tf.constant operation in the session
    	output = sess.run(hello_constant)
   		print(output.decode())# bytestring decode to string.
           

​ 如果出現以下則表示成功

2021-01-15 12:22:08.731542: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1304] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 2917 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1650, pci bus id: 0000:01:00.0, compute capability: 7.5)
Hello World!
           

​ 2、檢驗程式是否用gpu跑:

import tensorflow as tf
	a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
	b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
	c = tf.matmul(a, b)
	sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
	print(sess.run(c))
           

​ 如果出現以下則表示成功:

2021-01-15 12:29:48.283362: I tensorflow/core/common_runtime/direct_session.cc:359] Device mapping:
/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: GeForce GTX 1650, pci bus id: 0000:01:00.0, compute capability: 7.5
MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
           

代碼結構

用mtcnn+keras+facenet實作簡易的人臉識别人工智能-人臉識别
  1. 其中face_dataset為人臉存放資料
  2. model_data為mtcnn模型存放位置 (其中包含mtcnn三個神經網絡模型和一個Keras FaceNet 模型(由Hiroki Taniai提供!))
  3. net為調用mtcnn代碼存放位置

核心代碼:

​ face_recognize.py(根據資料庫中的檔案和實時檢測的人臉進行檢測識别)

# face_recognize
import cv2
import os
import numpy as np
from net.mtcnn import mtcnn
import utils.utils as utils
from net.inception import InceptionResNetV1
import tensorflow as tf 
config = tf.ConfigProto()#//對session進行參數配置
config.allow_soft_placement=False #如果你指定的裝置不存在,允許tensorflow自動配置設定裝置
config.gpu_options.per_process_gpu_memory_fraction=0.5#配置設定百分之七十的顯存給程式使用,避免記憶體溢出,可以自己調整
config.gpu_options.allow_growth = True#//按需配置設定顯存,這個比較重要
session = tf.Session(config=config)    
config = tf.ConfigProto() 
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 使用第一塊GPU
class face_rec():
    def __init__(self):     
        self.mtcnn_model = mtcnn()        
        self.threshold = [0.5,0.8,0.9]     
        self.facenet_model = InceptionResNetV1()
        model_path = 'model_data/facenet_keras.h5'
        self.facenet_model.load_weights(model_path)
        face_list = os.listdir('face_dataset')
        self.known_face_encodings=[]
        self.known_face_names=[]
        for face in face_list:
            name = face.split(".")[0]
            img = cv2.imread('face_dataset/'+face)
            img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
            rectangles = self.mtcnn_model.detectFace(img, self.threshold)
            rectangles = utils.rect2square(np.array(rectangles))
            rectangle = rectangles[0]
            landmark = (np.reshape(rectangle[5:15],(5,2)) - np.array([int(rectangle[0]),int(rectangle[1])]))/(rectangle[3]-rectangle[1])*160
            crop_img = img[int(rectangle[1]):int(rectangle[3]), int(rectangle[0]):int(rectangle[2])]
            crop_img = cv2.resize(crop_img,(160,160))
            new_img,_ = utils.Alignment_1(crop_img,landmark)
            new_img = np.expand_dims(new_img,0)
            face_encoding = utils.calc_128_vec(self.facenet_model,new_img)
            self.known_face_encodings.append(face_encoding)
            self.known_face_names.append(name)
    def recognize(self,draw):
        height,width,_ = np.shape(draw)
        draw_rgb = cv2.cvtColor(draw,cv2.COLOR_BGR2RGB)
        rectangles = self.mtcnn_model.detectFace(draw_rgb, self.threshold)
        if len(rectangles)==0:
            return
        rectangles = utils.rect2square(np.array(rectangles,dtype=np.int32))
        rectangles[:,0] = np.clip(rectangles[:,0],0,width)
        rectangles[:,1] = np.clip(rectangles[:,1],0,height)
        rectangles[:,2] = np.clip(rectangles[:,2],0,width)
        rectangles[:,3] = np.clip(rectangles[:,3],0,height)
        face_encodings = []
        for rectangle in rectangles:
            landmark = (np.reshape(rectangle[5:15],(5,2)) - np.array([int(rectangle[0]),int(rectangle[1])]))/(rectangle[3]-rectangle[1])*160
            crop_img = draw_rgb[int(rectangle[1]):int(rectangle[3]), int(rectangle[0]):int(rectangle[2])]
            crop_img = cv2.resize(crop_img,(160,160))
            new_img,_ = utils.Alignment_1(crop_img,landmark)
            new_img = np.expand_dims(new_img,0)
            face_encoding = utils.calc_128_vec(self.facenet_model,new_img)
            face_encodings.append(face_encoding)
        face_names = []
        for face_encoding in face_encodings:            
            matches = utils.compare_faces(self.known_face_encodings, face_encoding, tolerance = 0.9)
            name = "Unknown"
            face_distances = utils.face_distance(self.known_face_encodings, face_encoding)            
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = self.known_face_names[best_match_index]
            face_names.append(name)
        rectangles = rectangles[:,0:4]
        for (left, top, right, bottom), name in zip(rectangles, face_names):
            cv2.rectangle(draw, (left, top), (right, bottom), (0, 0, 255), 2)   
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(draw, name, (left , bottom - 15), font, 0.75, (255, 255, 255), 2) 
        return draw
if __name__ == "__main__":
    dududu = face_rec()
    video_capture = cv2.VideoCapture(0)
    while True:
        ret, draw = video_capture.read()
        dududu.recognize(draw) 
        cv2.imshow('Video', draw)
        if cv2.waitKey(2) & 0xFF == ord('q'):
            break
    video_capture.release()
    cv2.destroyAllWindows()

           

​ face_data.py (用于捕捉人臉,并儲存到資料庫中)

import cv2
face = cv2.CascadeClassifier('D:\OpenCV\Face_Identify\haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
name = input('enter your name: ')
while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face.detectMultiScale(gray,1.3,5)  
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
        cv2.imwrite("face_dataset/" + str(name) + ".jpg", gray[y:y + h, x:x + w])
    cv2.namedWindow('frame',0)
    cv2.imshow('frame', img)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
           

核心原理:

MTCNN原名為:多任務級聯卷積神經網絡,這個架構利用了檢測和對準之間固有的關系來增強他們的性能,通過3個CNN級聯的方式對任務進行從粗到精的處理,分為三個階段:

***階段1:***使用P-Net是一個全卷積網絡,用來生成候選窗和邊框回歸向量(bounding box regression vectors)。使用Bounding box regression的方法來校正這些候選窗,使用非極大值抑制(NMS)合并重疊的候選框。全卷積網絡和Faster R-CNN中的RPN一脈相承。

***階段2:***使用R-Net改善候選窗。将通過P-Net的候選窗輸入R-Net中,拒絕掉大部分false的視窗,繼續使用Bounding box regression和NMS合并。

***階段3:***最後使用O-Net輸出最終的人臉框和特征點位置。和第二步類似,但是不同的是生成5個特征點位置。

用mtcnn+keras+facenet實作簡易的人臉識别人工智能-人臉識别
附:論文下載下傳位址:

Joint Face Detection and Alignment using

Multi-task Cascaded Convolutional Networks

實作步驟:

  1. 點選face_data.py檔案捕捉人臉并将捕捉的人臉圖像儲存在face_dataset檔案夾中
  2. 點選face_recognize.py檔案通過檢測資料庫中的人臉和實時檢測到的人臉進行判斷

實作結果

用mtcnn+keras+facenet實作簡易的人臉識别人工智能-人臉識别

代碼位址:

https://github.com/2837657164/face-recognize/tree/v1.0

緻謝:

https://blog.csdn.net/weixin_44791964

https://kpzhang93.github.io/

繼續閱讀