ホームページ  >  記事  >  バックエンド開発  >  mtcnnとfacenetをベースにした顔ログインシステムの導入

mtcnnとfacenetをベースにした顔ログインシステムの導入

藏色散人
藏色散人オリジナル
2019-01-04 10:49:448072ブラウズ

本記事では、Python2.7.10/opencv2/tensorflow1.7.0環境をベースに、カメラからの映像読み込み、顔検出、顔の認識、つまり、mtcnn/facenet/tensorflow に基づく顔認識ログイン システムの実装です。

mtcnnとfacenetをベースにした顔ログインシステムの導入

モデル ファイルが大きすぎるため、git でアップロードできません。プロジェクトのソース コード全体が Baidu Cloud Disk に配置されています。

アドレス: https://pan.baidu.com/s/1TaalpwQwPTqlCIfXInS_LA

顔認識は、コンピューター ビジョン研究の分野でホット スポットです。現在、ラボ環境では、顔、DeepID3、FaceNetなど、多くの顔認証が手動認識の精度(精度率:0.9427~0.9920)に追いつき(超え)ています。(詳細は「顔」をご参照ください)ディープラーニングのレビューに基づいた認識技術)。

しかし、光、角度、表情、年齢などのさまざまな要因により、顔認識技術は実生活で広く使用することはできません。この記事は、python/opencv/tensorflow 環境に基づいており、FaceNet (LFW: 0.9963) を使用してリアルタイムの顔検出および認識システムを構築し、実際のアプリケーションにおける顔認識システムの難しさを調査します。

以下の主な内容は次のとおりです:

1. htm5 video タグを使用してカメラを開いてアバターを収集し、jquery.faceDeaction コンポーネントを使用して大まかに検出します顔

# 2. 顔画像をサーバーにアップロードし、mtcnn を使用して顔を検出します

#3. opencv のアフィン変換を使用して顔を位置合わせし、位置合わせした顔を保存します

4. 検出された顔を 512 次元の特徴に埋め込む事前トレーニング済みのフェイスネットを使用します;

5. 顔検出用の顔埋め込み特徴に対する効率的な迷惑インデックスを作成します

顔コレクション

HTML5 ビデオ タグを使用すると、カメラからビデオ フレームを簡単に読み取ることができます。次のコードは、カメラからビデオ フレームを読み取る実装です。faceDection が顔キャプチャを認識した後HTML ファイルとキャンバス タグにビデオを追加します

<div class="booth">
    <video id="video" width="400" height="300" muted class="abs" ></video>
    <canvas id="canvas" width="400" height="300"></canvas>
  </div>

Web カメラを開きます

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()

Detect顔がある場合は、スクリーンショットを撮り、簡単にアップロードできるように画像を 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 特徴分類器や dlib 顔検出など、多くの顔検出方法があります。 opencv に付属するメソッド。 opencv の顔検出方法はシンプルかつ高速ですが、問題は顔検出効果が良くないことです。この方法では、正面/垂直/照明が良好な顔は検出できますが、横/斜め/照明が不十分な顔は検出できません。

したがって、この方法は現場での応用には適していません。 dlib 顔検出方法の場合、効果は opencv 方法よりも優れていますが、検出強度もフィールド アプリケーションの基準を満たすことが困難です。

この記事では、深層学習手法に基づく mtcnn 顔検出システム (mtcnn: Joint Face Detection 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 を参照してください

顔の位置調整

キャプチャした顔やアバターが歪んでいる場合があります。検出するには、顔を同じ標準位置に修正する必要があります。この位置は私たちが定義します。設定した標準検出アバターは次のようであると仮定します。

と仮定します。目と鼻の 3 点の座標は a(10,30 ) b(20,30) c(15,45) です。具体的な設定については、config.ini ファイルのアラインメント ブロック設定項目を参照してください。 mtcnnとfacenetをベースにした顔ログインシステムの導入opencv アフィン変換を使用して位置合わせを行い、アフィン変換行列を取得します。

dst_point=【a,b,c】
tranform = cv2.getAffineTransform(source_point, dst_point)

アフィン変換:

img_new = cv2.warpAffine(img, tranform, imagesize)

具体的なコードについては、face_alignment.py ファイルを参照してください

#特徴の生成

アライメント後 アバターは、検出された顔を埋め込み、512 次元の特徴に埋め込んで、 (id, ベクトル) の形式の 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。