本文主要介紹了系統涉及的人臉檢測與識別的詳細方法,該系統基於python2.7.10/opencv2/tensorflow1.7.0環境,實現了從攝像頭讀取視頻,檢測人臉,識別人臉的功能,即基於mtcnn/facenet/tensorflow 實現人臉辨識登入系統。
由於模型檔案過大,git無法上傳,整個專案原始碼放在百度雲端磁碟
位址:https://pan. baidu.com/s/1TaalpwQwPTqlCIfXInS_LA
#人臉辨識是電腦視覺研究領域的熱點。目前,在實驗室環境下,許多人臉辨識已經趕上(超過)人工辨識精度(準確率:0.9427~0.9920),例如face ,DeepID3,FaceNet等(詳情可以參考:基於深度學習的人臉辨識技術綜述)。
但是,由於光線,角度,表情,年齡等多種因素,導致人臉辨識技術無法在現實生活中廣泛應用。本文基於python/opencv/tensorflow環境,採用FaceNet(LFW:0.9963 )為基礎來建構即時人臉偵測與辨識系統,探索人臉辨識系統在現實應用上的困難點。
下文主要內容如下:
1.利用htm5 video標籤開啟攝影機擷取頭像並使用jquery.faceDeaction元件來粗略偵測人臉
# 2.將人臉影像上傳到伺服器,採用mtcnn偵測人臉
3.利用opencv的仿射變換對人臉進行對齊,保存對齊後的人臉
4.採用預先訓練的facenet對檢測的人臉進行embedding,embedding成512維度的特徵;
5.對人臉embedding特徵創建高效的annoy索引進行人臉檢測
#人臉採集
採用html5 video標籤可以很方便的實現從攝像頭讀取視頻幀,下文代碼實現了從攝像頭讀取視頻幀,faceDection識別人臉後截取圖片上傳到伺服器功能在html檔案中加入video,canvas標籤
<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('video'),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元件偵測人臉
$('#canvas').faceDetection()
偵測出人連臉的話截圖,並把圖片轉換為base64的格式,方便上傳
context.drawImage(video, 0, 0, video.width, video.height); var base64 = canvas.toDataURL('images/png');
將base64格式的圖片上傳到伺服器
//上传人脸图片 function upload(base64) { $.ajax({ "type":"POST", "url":"/upload.php", "data":{'img':base64}, 'dataType':'json', 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('/^(data:\s*image\/(\w+);base64,)/', $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], '', $base64_image_content)))){ return $new_file; }else{ return false; } }else{ return false; } }
人臉偵測
人臉偵測方法有許多,像是opencv自帶的人臉Haar特徵分類器和dlib人臉偵測方法等。對於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('mtcnn','model')) 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
#人臉對齊
有時候我們截取的人臉了頭像可能是歪的,為了提升檢測的質量,需要把人臉校正到同一個標準位置,這個位置是我們定義的,假設我們設定的標準偵測頭像是這樣的
#假設眼睛,鼻子三個點的座標分別是a(10,30 ) b(20,30) c(15,45),具體設定可參考config.ini檔案alignment區塊設定項目
採用opencv仿射變換進行對齊,取得仿射變換矩陣
dst_point=【a,b,c】 tranform = cv2.getAffineTransform(source_point, dst_point)
仿射變換:
img_new = cv2.warpAffine(img, tranform, imagesize)
具體程式碼參考face_alignment.py檔案
產生特徵
對齊得到後的頭像,放入採用預先訓練的facenet對檢測的人臉進行embedding,embedding成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('annoy','num_nn_nearst')) 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模型后等待人脸请求
未注册识别失败
人脸注册
注册后登录成功
感谢PHP中文网热心网友的投稿,其GitHub地址为:https://github.com/chenlinzhong/face-login
以上是基於mtcnn與facenet實現人臉登入系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver Mac版
視覺化網頁開發工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。