日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

OpenCV人脸识别

發布時間:2023/12/10 pytorch 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV人脸识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

OpenCV人臉識別與口罩檢測

下載文件

人臉檢測

人臉檢測的檢測方法主要有兩類:基于知識(根據眼睛,眉毛,嘴巴,鼻子等器官特征及相互幾何位置關系來檢測)和基于統計(將人臉看作一個二維像素矩陣,通過大量人臉圖像樣本構造人臉模式空間,由相似度量判斷人臉是否存在).

基于知識的檢測

  • 模板匹配
  • 人臉特征
  • 形狀邊緣
  • 紋理特征
  • 顏色特征

基于統計的檢測

  • 主成分分析與特征臉
  • 神經網絡方法
  • 支持向量機
  • 隱馬爾可夫模型
  • Adaboost算法

分類

  • 對已知物體類別總數的識別方式,訓練時數據就帶有標簽,明確是人臉還是非人臉,稱為有監督學習.

聚類

  • 處理類別總數不確定的方法或訓練的數據無標簽,無需學習階段中關于物體類別的信息,成為無監督學習.

Haar分類器

Haar分類器=Har-like特征+積分圖方法+AdaBoost+級聯

  • 使用Haar-like特征做檢測
  • 積分圖對Haar-like特征求值加速
  • 使用AdaBoost算法訓練區分人臉與非人臉的強分類器
  • 使用篩選式級聯把強分類器級聯,提高準確率

Haar-like特征

在人臉檢測時需要有一個子窗口在待檢測的圖片窗口中不斷的移位滑動,子窗口每到一個位置,就會計算出該區域的特征,再用訓練好的級聯分類器對該特征進行篩選,當這個特征通過了所有強分類器的篩選,就判定這個區域為人臉。

上面的方塊都是Haar-like特征,將上面的任意一個矩形放到人臉區域上,然后,將白色區域的像素和減去黑色區域的像素和,得到的值為人臉特征值,如果把這個矩形放到一個非人臉區域,那么計算出的特征值應該和人臉特征值是不一樣的,而且越不一樣越好,所以這些方塊的目的就是把人臉特征量化,以區分人臉和非人臉。

比如對于人臉區域,比較明顯的兩個特征是眼睛比面部和鼻梁區域顏色都要深.

為了增加區分度,對多個矩形特征計算得到區分度更大的特征值,尋找何種矩形何種特征就是AdaBoost的任務.

AdaBoost算法

AdaBoost是一種有一般性的分類器提升算法,可以幫助選擇更好的矩陣特征組合,也就是分類器,將矩陣組合以二叉決策樹的形式存儲起來.

弱學習

  • 一個學習算法對一組概念的識別率只比隨即識別好一點
  • 容易獲得,需要大量假設集合(基于某些簡單規則的組合和對樣本集的性能評估生成的)

強學習

  • 一個學習算法對一組概念的識別率很高
  • 不容易獲得的

Kearns和Valiant兩位大牛牛提出了弱學習和強學習等價的問題,證明只要有足夠數據,弱學習方法可通過集成方式生成任意高精度的強學習方法.

弱分類器和強分類器對應的就是弱學習與強學習.

弱分類器

最初的弱分類器可能只是一個最基本的Haar-like特征,計算輸入圖像的Haar-like特征值,和最初的弱分類器的特征值比較,以此來判斷輸入圖像是不是人臉,但這個弱分類器太簡陋了,可能并不比隨機判斷的效果好,對弱分類器的孵化就是訓練弱分類器成為相對誤差稍低的最優弱分類器.

決策樹

  • 一個預測模型
  • 代表對象屬性與對象值的一種映射關系
  • 分類樹: 預計結果可能為兩種類型
  • 回歸樹: 局域結果可能為實數

假設使用三個Haar-like特征f1,f2,f3判斷輸入數據是否為人臉,可建立決策樹

每個非葉子節點表示一種判斷,每個路徑代表一種判斷的輸出,每個葉子節點代表一種類別,作為最終判斷結果.一個弱分類器是一個基本與上圖類似的決策樹,最基本的弱分類器只含一個Haar-like特征,即決策樹僅一層,稱為樹樁.

最重要的就是如何決定每個結點判斷的輸出,要比較輸入圖片的特征值和弱分類器中特征,一定需要一個閾值,當輸入圖片的特征值大于該閾值時才判定其為人臉。訓練最優弱分類器的過程實際上就是在尋找合適的分類器閾值,使該分類器對所有樣本的判讀誤差最低。

強分類器

強分類器的誕生需要T輪迭代

    • S: 訓練樣本集
    • N: 樣本數量
    • X: 正樣本
    • Y: 負樣本
    • T: 最大循環數量
    • 1/N: 初始化樣本權重,訓練樣本的初始概率分布
  • 第一次迭代訓練N個樣本,得到一個最優弱分類器
  • 提高上一輪被誤判樣本權重
  • 新的樣本和上次分錯樣本放在一起進行新一輪訓練
  • 循環執行4-5步,T輪后得到T個最優弱分類器
  • 組合T個最有弱分類器得到強分類器,讓所有弱分類器投票,再對投票結果按照弱分類器的錯誤率加權求和,將投票加權求和的結果與平均投票結果比較得出最終的結果
  • 級聯

    通過AdaBoost算法訓練出了強分類器,但在現實的人臉檢測中,只靠一個強分類器還是難以保證檢測的正確率,需要訓練出多個強分類器將它們強強聯手,最終形成正確率很高的級聯分類器,即最終的目標Haar分類器。

    輸入圖片輸出大量的子窗口圖像,這些子窗口圖像經過篩選式級聯分類器會不斷地被每一個節點篩選,拋棄或通過, 這個結構也是一個決策樹。

    級聯強分類器的策略是,將若干個強分類器由簡單到復雜排列,希望經過訓練使每個強分類器都有較高檢測率,而誤識率可以放低,比幾乎99%的人臉可以通過,但50%的非人臉也可以通過,這樣如果有20個強分類器級聯,那么他們的總識別率為 0.9920=98%0.99^{20}=98\%0.9920=98% ,錯誤接受率也僅為0.520=0.0001%0.5^{20}=0.0001\%0.520=0.0001%。這樣的效果就可以滿足現實的需要了,但是如何使每個強分類器都具有較高檢測率呢,為什么單個的強分類器不可以同時具有較高檢測率和較高誤識率呢?

    AdaBoost訓練出來的強分類器一般具有較小的誤識率,但檢測率并不很高,一般高檢測率會導致高誤識率,這是強分類閾值的劃分導致的,要提高強分類器的檢測率既要降低閾值,要降低強分類器的誤識率就要提高閾值,這是個矛盾的事情。而增加分類器個數可以在提高強分類器檢測率的同時降低誤識率,所以級聯分類器在訓練時要考慮如下平衡,一是弱分類器的個數和計算時間的平衡,二是強分類器檢測率和誤識率之間的平衡。

    OpenCV

    OpenCV是計算機視覺中經典的專用庫,其支持多語言、跨平臺,功能強大。OpenCV-Python為OpenCV提供了Python接口,使得使用者在Python中能夠調用C/C++,在保證易讀性和運行效率的前提下,實現所需的功能。
    安裝教程

    OpenCV的Haar級聯分類器

    OpenCV提供了一種訓練方法或預先訓練的模型,可以在OpenCV安裝的\opencv\sources\data\haarcascades_cuda文件夾中找到, 可以使用cv2.CascadeClassifier(~)方法讀取。

    先用OpenCV開啟筆記本默認攝像頭

    import numpy as np import cv2 cap = cv2.VideoCapture(0) # 打開筆記本攝像頭 while 1:ret,frame = cap.read() # 獲取拍攝的圖像cv2.imshow("picture",frame)if cv2.waitKey(1) == 27: # 按下esc停止break cv2.destroyAllWindows() # 關閉所有窗口

    文件夾里有很多分類器, 這里用的是haarcascade_frontalface_default.xml正臉檢測分類器.

    人臉檢測

    參考文件FaceFind.py

    # 加載級聯分類器 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

    用face_cascade.detectMultiScale可以對輸入的灰度圖檢測, 返回的是一個列表, 列表的元素是人臉所在矩形區域的左上角坐標和寬高, 獲取之后我們在原圖像上畫出來,這里先把檢測和畫圖封裝成函數.

    # 人臉檢測函數 def detect_face(img):# 將測試圖像轉換為灰度圖像,因為opencv人臉檢測器需要灰度圖像gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 檢測多尺度圖像,返回值是一張臉部區域信息的列表(x,y,寬,高)faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2,minNeighbors=5,minSize=(20, 20)) #人臉的最小范圍,如果比20*20像素小忽略)# 如果未檢測到面部,則返回原始圖像if (len(faces) == 0):return None, None # 目前假設只有一張臉,xy為左上角坐標,wh為矩形的寬高(x, y, w, h) = faces[0]# 返回圖像的正面部分return gray[y:y + w, x:x + h], faces[0]# 根據給定的(x,y)坐標和寬度高度在圖像上繪制矩形 def draw_rectangle(img, rect):(x, y, w, h) = rect # 矩形跟蹤人臉cv2.rectangle(img, (x, y), (x + w, y + h), (255, 128, 0), 2)cv2.rectangle(img, (x+2, y+2), (x + w-2, y + h-2), (0, 255, 128), 2)

    然后在while循環的獲取圖像后加上

    try:face, rect = detect_face(frame) # 尋找可以識別人臉的圖片draw_rectangle(frame, rect) # 框選人臉 except: # 未能識別到人臉print("no face")

    模型訓練

    參考文件FaceTrain.py

    知道哪一個區域是人臉后, 下一步就是分辨人臉是誰了, OpenCV也提供了方便的工具, 先錄入圖片, 創建識別器, 訓練得到模型并保存.

    # 創建兩個列表分別保存所有的臉部和標簽 faces = [] labels = [] Names = ["Trump", "Putin", "TrumpTin"] NameNumber = 2 # 1Trump2Putin

    輸入參數是人臉圖片和標簽(正整數123), 一般錄入人臉是輸入姓名, 但姓名其實也是對應整數標簽, 這里偷一下懶, 用NameNumber指代姓名, 檢測時再用標簽對應到名字數組.

    在框選到人臉之后添加, 每次訓練都是創建一個新模型, 覆蓋掉原來的模型, 所以舉例的代碼得到的模型只能分辨到一張人臉.

    if face is not None:#將臉添加到臉部列表并添加相應的標簽faces.append(face)labels.append(NameNumber)times += 1print(times) if times > 15:# 創建LBPH識別器并開始訓練,當然也可以選擇Eigen或者Fisher識別器face_recognizer = cv2.face.LBPHFaceRecognizer_create()face_recognizer.train(faces, np.array(labels))# 保存訓練好的模型face_recognizer.save("face_model.xml")break

    人臉預測

    參考文件FaceDectect.py

    訓練得到的是xml后綴的文件, 在檢測程序里先加載為face_recognizer

    # 加載已訓練的模型 def Load_face_model():face_recognizer = cv2.face.LBPHFaceRecognizer_create()try:face_recognizer.read("face_model.xml")return face_recognizerexcept:print('No Module, please obtain first')noi = 1return noi face_recognizer = Load_face_model() Names = ["Trump", "Putin", "TrumpTin"]

    創建預測函數, 用face_recognizer.predict(face)對detect_face出的面部區域進行預測, 可以得到一個結果列表label[2], 其中label[0]是預測的標簽, 如果正確就是上一節輸入的標簽NameNumber, label[1]是預測輸入的圖像與這個標簽的正確度, 越小正確度越高, 這里我們取小于70認為是正確, 并用標簽label[0]映射回姓名列表, 在圖片上寫出姓名, 如果否, 就寫上陌生人stranger.

    # 此函數識別傳遞的圖像中的人物并在檢測到的臉部周圍繪制一個矩形及其名稱 def predict(test_img):#生成圖像的副本,這樣就能保留原始圖像img = test_img.copy()#檢測人臉face, rect = detect_face(img)try:#預測人臉label = face_recognizer.predict(face)print(label)# 在檢測到的臉部周圍畫一個矩形draw_rectangle(img, rect)if label[1]<70:# 獲取由人臉識別器返回的相應標簽的名稱label_text = Names[label[0]-1]# 標出預測的名字draw_text(img, label_text, rect[0], rect[1] - 15, "WHITE")else:# 未識別,wrong peopledraw_text(img, "Stranger", rect[0], rect[1] - 5, "RED")except Exception as err:print(err)#print(label) #返回預測的圖像return img

    while 1里的檢測改為

    try:predicted_img = predict(frame) except: # 未能識別到人臉print("no face")

    例子里的代碼每次訓練都是創建一個新模型, 覆蓋掉原來的模型, 程序就結束了, 所以舉例的代碼得到的模型只能分辨到一張人臉. 如果要識別多個人臉, 可以運行gui控件, 根據不同操作持續添加人臉數據, 或者每次都把不同人的圖片存下來, 訓練時統一調用訓練.

    口罩檢測

    類似的原理可以訓練出檢測是否佩戴口罩的模型

    mask_cascade = cv2.CascadeClassifier('no_mask_detect_cascade.xml') # 檢測是否佩戴口罩 def detect_facemask(img):# 將測試圖像轉換為灰度圖像,因為opencv人臉檢測器需要灰度圖像gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 檢測多尺度圖像,返回值是一張臉部區域信息的列表(x,y,寬,高)faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2,minNeighbors=5,minSize=(50, 50)) #人臉的最小范圍,如果比20*20像素小忽略# 如果未檢測到面部,則返回原始圖像if (len(faces) == 0):return None, None, None# 目前假設只有一張臉,xy為左上角坐標,wh為矩形的寬高(x, y, w, h) = faces[0]no_mask = mask_cascade.detectMultiScale(gray[y:y + w, x:x + h],scaleFactor = 1.01, minNeighbors = 4)# 返回圖像的正面部分return gray[y:y + w, x:x + h], faces[0], no_mask

    紅外測溫

    如果用的是樹莓派, 可以比較方便地用杜邦線接入mlx90614等紅外測溫模塊.

    模塊用smbus協議通訊, 附件中有現成的接口mlx90614.py, 直接調用即可.

    上面這些東西組合起來, 其實是2020年電子設計大賽的賽題

    參考

    • 淺析人臉檢測之Haar分類器方法
    • 圖像特征提取三大法寶:HOG特征,LBP特征,Haar特征
    • 級聯分類器
    • Viola–Jones object detection framework–Rapid Object Detection using a Boosted Cascade of Simple Features中文翻譯 及 matlab實現(見文末鏈接)

    關注公眾號小電動車

    回復人臉識別獲取代碼

    總結

    以上是生活随笔為你收集整理的OpenCV人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。