>백엔드 개발 >PHP 튜토리얼 >mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

藏色散人
藏色散人원래의
2019-01-04 10:49:448143검색

이 글에서는 시스템에 관련된 얼굴 검출 및 인식의 세부 방법을 주로 소개합니다. 시스템은 python2.7.10/opencv2/tensorflow1.7.0 환경을 기반으로 하며 카메라에서 영상을 읽어 얼굴을 인식하고 인식하는 기능을 구현합니다. faces. 즉, mtcnn/facenet/tensorflow를 기반으로 얼굴인식 로그인 시스템을 구현하는 기능입니다.

mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

모델 파일이 너무 커서 git이 업로드할 수 없고 전체 프로젝트 소스코드는 바이두 클라우드 디스크에 올려져 있습니다

# 🎜🎜#주소: #🎜 🎜#https://pan.baidu.com/s/1TaalpwQwPTqlCIfXInS_LA

얼굴 인식은 컴퓨터 비전 연구 분야에서 핫스팟입니다. 현재 실험실 환경에서는 Face++, DeepID3, FaceNet 등 많은 얼굴 인식이 수동 인식의 정확도(정확도: 0.9427~0.9920)를 따라잡았습니다(초과). (자세한 내용은 Face를 참조하세요.) 딥러닝 리뷰 기반 인식 기술)

하지만 빛, 각도, 표정, 연령 등 다양한 요인으로 인해 얼굴인식 기술은 실생활에서 널리 활용되기는 어렵습니다. 이 기사는 python/opencv/tensorflow 환경을 기반으로 하며 FaceNet(LFW: 0.9963)을 사용하여 실시간 얼굴 감지 및 인식 시스템을 구축하여 실제 애플리케이션에서 얼굴 인식 시스템의 어려움을 탐구합니다.

아래 주요 내용은 다음과 같습니다.

1 htm5 비디오 태그를 사용하여 카메라를 열고 아바타를 수집하고 jquery를 사용합니다. .faceDeaction 구성 요소를 사용하여 얼굴을 대략적으로 감지합니다

2. 얼굴 이미지를 서버에 업로드하고 mtcnn을 사용하여 얼굴을 감지합니다

3. opencv의 아핀 변환을 사용하여 얼굴을 정렬합니다. 정렬된 사람 얼굴 저장

4. 사전 학습된 Facenet을 사용하여 감지된 얼굴을 512차원 특징에 삽입합니다.

5. 기능 얼굴 감지용 색인#

얼굴 모음

html5 비디오 태그를 사용하면 The에서 쉽게 구현할 수 있습니다. 카메라가 비디오 프레임을 읽습니다. 다음 코드는 FaceDection이 얼굴을 인식한 다음 이미지를 가로채서 서버에 업로드합니다.

<div class="booth">
    <video id="video" width="400" height="300" muted class="abs" ></video>
    <canvas id="canvas" width="400" height="300"></canvas>
  </div>
웹캠 열기# 🎜🎜#
var video = document.getElementById(&#39;video&#39;),var vendorUrl = window.URL || window.webkitURL;
//媒体对象
navigator.getMedia = navigator.getUserMedia || navagator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getMedia({video: true, //使用摄像头对象audio: false  //不适用音频}, function(strem){
    video.src = vendorUrl.createObjectURL(strem);
    video.play();
});

jquery의 facetDection 구성 요소를 사용하여 얼굴 감지

$(&#39;#canvas&#39;).faceDetection()

사람의 얼굴이 감지되면 스크린샷을 찍고 이미지를 base64 형식으로 변환하세요. 쉬운 업로드

context.drawImage(video, 0, 0, video.width, video.height);
var base64 = canvas.toDataURL(&#39;images/png&#39;);
# 🎜🎜#base64 형식의 사진을 서버에 업로드

//上传人脸图片
function upload(base64) {
  $.ajax({
      "type":"POST",
      "url":"/upload.php",
      "data":{&#39;img&#39;:base64},
      &#39;dataType&#39;:&#39;json&#39;,
      beforeSend:function(){},
      success:function(result){
          console.log(result)
          img_path = result.data.file_path
      }
  });
}

사진 서버는 코드, PHP 언어 구현을 허용합니다

function base64_image_content($base64_image_content,$path){
    //匹配出图片的格式
    if (preg_match(&#39;/^(data:\s*image\/(\w+);base64,)/&#39;, $base64_image_content, $result)){
        $type = $result[2];
        $new_file = $path."/";
        if(!file_exists($new_file)){
            //检查是否有该文件夹,如果没有就创建,并给予最高权限
            mkdir($new_file, 0700,true);
        }
        $new_file = $new_file.time().".{$type}";
        if (file_put_contents($new_file, base64_decode(str_replace($result[1], &#39;&#39;, $base64_image_content)))){
            return $new_file;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

#🎜 🎜#얼굴 감지#🎜 🎜#

얼굴 Haar 기능 분류기, opencv와 함께 제공되는 dlib 얼굴 감지 방법 등 다양한 얼굴 감지 방법이 있습니다. opencv의 얼굴 검출 방법은 간단하고 빠르지만, 문제는 얼굴 검출 효과가 좋지 않다는 것입니다. 이 방법은 정면/수직/조명이 좋은 얼굴을 감지할 수 있지만, 옆으로/비뚤어져 있거나 조명이 약한 얼굴은 감지할 수 없습니다.

따라서 이 방법은 현장 적용에는 적합하지 않습니다. dlib 얼굴 검출 방식의 경우 opencv 방식에 비해 효과는 좋지만 검출 강도 역시 현장 적용 기준을 충족하기 어렵다. 이 기사에서는 딥러닝 방법을 기반으로 하는 mtcnn 얼굴 감지 시스템(mtcnn: Joint FaceDetection and Alignment using Multi-task Cascaded Convolutional Neural Networks)을 사용합니다. mtcnn 얼굴 감지 방법은 자연 환경에서 빛, 각도, 얼굴 표정의 변화에 ​​더욱 강력하며 동시에 얼굴 감지 효과도 더 좋고 메모리 소모도 크지 않습니다. 실시간 얼굴 감지로 감지가 가능합니다.

이 글에서 사용된 mtcnn은 python과 tensorflow의 구현을 기반으로 합니다. (코드는 davidsandberg에서 왔고, caffe 구현 코드는 kpzhang93에서 찾을 수 있습니다.)

model= os.path.abspath(face_comm.get_conf(&#39;mtcnn&#39;,&#39;model&#39;))
class Detect:
    def __init__(self):
        self.detector = MtcnnDetector(model_folder=model, ctx=mx.cpu(0), num_worker=4, accurate_landmark=False)
    def detect_face(self,image):
        img = cv2.imread(image)
        results =self.detector.detect_face(img)
        boxes=[]
        key_points = []
        if results is not None:  
            #box框
            boxes=results[0]
            #人脸5个关键点
            points = results[1]
            for i in results[0]:
                faceKeyPoint = []
                for p in points:
                    for i in range(5):
                        faceKeyPoint.append([p[i], p[i + 5]])
                key_points.append(faceKeyPoint)
        return {"boxes":boxes,"face_key_point":key_points}

구체적인 코드는 fcce_Detect.py#🎜🎜 #

face alignment

때때로 얼굴과 아바타를 참조하세요. 가로채기가 비뚤어질 수 있으므로 감지 품질을 높이기 위해 얼굴을 동일한 표준 위치로 수정해야 합니다. 이 위치는 우리가 설정한 표준 감지 아바타가 다음과 같다고 가정합니다

#🎜🎜 #

#🎜🎜 # 눈과 코의 세 점의 좌표를 a(10,30) b(20,30) c(15,45)라고 가정합니다. config.ini 파일 정렬 블록 구성 항목을 참조하세요#🎜🎜 #opencv 아핀 변환을 사용하여 아핀 변환 행렬 정렬 및 얻기

dst_point=【a,b,c】
tranform = cv2.getAffineTransform(source_point, dst_point)
아핀 변환:
img_new = cv2.warpAffine(img, tranform, imagesize)
# 🎜🎜#특정 코드는 face_alignment.py 파일을 참고하세요

#🎜🎜 #

Generate feature

mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

이후 아바타를 정렬하고 사전 훈련된 Facenet에 넣어 감지된 얼굴을 임베딩하면 512차원 특징이 (id, vector) 형식으로 lmdb 파일에 저장됩니다.

facenet.load_model(facenet_model_checkpoint)
 images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
 embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
 phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
 
 face=self.dectection.find_faces(image)
 prewhiten_face = facenet.prewhiten(face.image)
 # Run forward pass to calculate embeddings
 feed_dict = {images_placeholder: [prewhiten_face], phase_train_placeholder: False}
 return self.sess.run(embeddings, feed_dict=feed_dict)[0]

구체적인 코드는 face_encoder.py

얼굴 기능 색인: #🎜🎜 #을 참조하세요.

人脸识别的时候不能对每一个人脸都进行比较,太慢了,相同的人得到的特征索引都是比较类似,可以采用KNN分类算法去识别,这里采用是更高效annoy算法对人脸特征创建索引,annoy索引算法的有个假设就是,每个人脸特征可以看做是在高维空间的一个点,如果两个很接近(相识),任何超平面 都无法把他们分开,也就是说如果空间的点很接近,用超平面去分隔,相似的点一定会分在同一个平面空间(具体参看:https://github.com/spotify/annoy)

#人脸特征先存储在lmdb文件中格式(id,vector),所以这里从lmdb文件中加载
lmdb_file = self.lmdb_file
if os.path.isdir(lmdb_file):
    evn = lmdb.open(lmdb_file)
    wfp = evn.begin()
    annoy = AnnoyIndex(self.f)
    for key, value in wfp.cursor():
        key = int(key)
        value = face_comm.str_to_embed(value)
        annoy.add_item(key,value)
        
    annoy.build(self.num_trees)
    annoy.save(self.annoy_index_path)

具体代码可参看face_annoy.py

人脸识别

经过上面三个步骤后,得到人脸特征,在索引中查询最近几个点并就按欧式距离,如果距离小于0.6(更据实际情况设置的阈值)则认为是同一个人,然后根据id在数据库查找到对应人的信息即可

#根据人脸特征找到相似的
def query_vector(self,face_vector):
    n=int(face_comm.get_conf(&#39;annoy&#39;,&#39;num_nn_nearst&#39;))
    return self.annoy.get_nns_by_vector(face_vector,n,include_distances=True)

具体代码可参看face_annoy.py

安装部署

系统采用有两个模块组成:

  • face_web:提供用户注册登录,人脸采集,php语言实现

  • face_server: 提供人脸检测,裁剪,对齐,识别功能,python语言实现

模块间采用socket方式通信通信格式为: length+content

face_server相关的配置在config.ini文件中

1.使用镜像

  • face_serverdocker镜像: shareclz/python2.7.10-face-image

  • face_web镜像: skiychan/nginx-php7

假设项目路径为/data1/face-login

2.安装face_server容器

docker run -it --name=face_server --net=host  -v /data1:/data1  shareclz/python2.7.10-face-image /bin/bash
cd /data1/face-login
python face_server.py

3.安装face_web容器

docker run -it --name=face_web --net=host  -v /data1:/data1  skiychan/nginx-php7 /bin/bash
cd /data1/face-login;
php -S 0.0.0.0:9988 -t ./web/

最终效果:

face_server加载mtcnn模型和facenet模型后等待人脸请求 

5 (1).png

未注册识别失败 

mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

人脸注册 

mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

注册后登录成功 

mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현

感谢PHP中文网热心网友的投稿,其GitHub地址为:https://github.com/chenlinzhong/face-login

위 내용은 mtcnn 및 Facenet 기반의 얼굴 로그인 시스템 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.