[Day 19] Facial Recognition: 使用孪生网路做辨识

只要你资料集越完整,辨识模型就越强大

这个系列偏重於方法的介绍与使用,因此今天我们不会重头开始训练模型,而是使用:

此模型是由Hiroki Taniai的github网站中取得

模型的快速下载点在这

本文开始

接下来我们就一样用之前文章中下载的资料集来做孪生网路的人脸辨识吧!

  1. 开启你的专案 (前面系列建立的),我们需要下载一个新的套件来载入FaceNet模型
    • tensorflow == 2.0.4
      (这里的tensorflow为求方便是使用CPU的版本;你可以依据喜好使用GPU版本tensorflow-gpu或是其他更高版号的tensorflow)
  2. 安装完後,在face_recognition目录下新建一个档案siamese.py
  3. 将上面模型facenet_keras.h5下载下来
  4. 相关程序码与说明 (images_to_faces函数在Day15文章中):
    import ntpath
    import sys
    
    # resolve module import error in PyCharm
    import cv2
    import numpy as np
    
    sys.path.append(ntpath.dirname(ntpath.dirname(ntpath.abspath(__file__))))
    
    import argparse
    import random
    
    from scipy.spatial import distance
    from sklearn.preprocessing import normalize
    from tensorflow.keras.models import load_model
    
    from dataset.load_dataset import images_to_faces
    
    
    def l2_normalize(x, axis=-1, epsilon=1e-10):
        output = x / np.sqrt(np.maximum(np.sum(np.square(x), axis=axis, keepdims=True), epsilon))
        return output
    
    def main():
        # 初始化arguments
        ap = argparse.ArgumentParser()
        ap.add_argument("-i", "--input", type=str, required=True, help="the input dataset path")
        ap.add_argument("-m", "--model", type=str, required=True, help="the facenet model path")
        args = vars(ap.parse_args())
    
        # 载入模型 (模型输入为(160, 160)大小的图片,输出为128-dimensions embeddings)
        model = load_model(args["model"])
        # 你可以取消下方的注解看看这个模型的长相
        # print(model.summary())
    
        print("[INFO] loading dataset....")
        (faces, labels) = images_to_faces(args["input"])
        print(f"[INFO] {len(faces)} images in dataset")
    
        # 随机抽取图片检查相似度 (抽取两组:一组为同样的人、一组为不同的人)
        classes = np.unique(labels)
        idxs = [np.where(labels == cls)[0] for cls in classes]
        idx = random.choice(idxs)
        pos_ids = random.sample(list(idx), 2)
        pos_faces = faces[pos_ids]
        pos_label = labels[pos_ids[0]]
        neg_face = faces[random.choice(np.where(labels != pos_label)[0])]
    
        # 对这两组资料进行相似度比对
        for compares in (pos_faces, [pos_faces[0], neg_face]):
            # 将照片改为模型输入的大小
            img1 = cv2.resize(compares[0], (160, 160))
            img2 = cv2.resize(compares[1], (160, 160))
            # 将照片由灰阶扩展到3-channels
            img1 = np.dstack([img1] * 3)
            img2 = np.dstack([img2] * 3)
            # 预测图片的embeddings
            p1 = model.predict(np.expand_dims(img1, axis=0))
            p2 = model.predict(np.expand_dims(img2, axis=0))
            # 将结果正规化到[0 ,1]
            p1 = normalize(p1)
            p2 = normalize(p2)
            # 透过判断欧式距离来比较相似度 (数值越小越相似)
            dist = distance.euclidean(p1, p2)
            final = np.hstack([img1, img2])
            cv2.putText(final, f"similarity: {round(dist, 3)}", (10, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
            cv2.imshow("result", final)
            cv2.waitKey(0)
    
    
    if __name__ == '__main__':
        main()
    
    
  5. 开启terminal,执行python face_recognition/siamese.py -i dataset/caltech_faces -m facenet_keras.h5
    相似的人比对结果
    siamese_2
    不相似的人比对结果
    siamese_3

结论

  1. 人脸做alignment会有更好的结果
  2. 这个方式可以透过比对资料库内所有的照片,找出最小的值来判断为同一人作为人脸辨识的结果
  3. 针对实际使用的人脸资料库建议训练一个专属的模型,可以获得比较好的辨识结果

程序码在这里


<<:  Day 19 [Python ML、资料视觉化] Seaborn介绍

>>:  模型的内容07 train()

AE自动消除画面动态物件-Day27

今天来练习怎麽让动态的物件在影片中消除, 影片范例 但因为没有付钱买,有浮水印,所以不知道能不能去掉...

2.4.13 Design System - Loading Indicator

时常为自己排序 这是一个老生常谈的问题了,工作、家庭、财富、人际、健康,什麽对我们来说是最重要的?...

panel data regression in r

废话不多说,直接附上code 影片含有程序码详细解说,若有误再烦请告知,谢谢 library(plm...

Day18:图形搜寻-戴克斯特拉演算法(Dijkstra's algorithm)

贪婪(Greedy)演算法 贪婪演算法是考虑局部最佳解,在子结构中解决问题是相当有利的,但放入整体问...

故事二十九:今晚,简单练习就好!

     再过一天,比赛就结束了。时间真的过得好快啊!   今晚我从 open data 网站,下载...