opencv快速入門人臉檢測與人臉識別

讓“它”認得你

——利用opencv快速入門人臉檢測與人臉識別

opencv,顧名思義“開源,計算機視覺”。OpenCV就是這樣的一個特殊的框架,一羣大牛然繞自己的時間,製作了一個開源的計算機視覺框架。藉助它我們可以快速的創建計算機視覺的應用。而我們這裏將會使用更更加快速的OpenCV-Python,也就是OpenCV的Python接口。假如你已經安裝了Python和pip,那麼只需簡單的執行“pip install opencv-python”即可。如果你沒有安裝Python,那麼也很簡單,下載Anaconda3,然後安裝,其就自帶近乎完整的Python科學計算環境。之後繼續pip即可。

有了以上工具的幫助,我們只需要簡單地使用幾十行代碼就可以快速的實現人臉檢測與人臉識別。讓“它”認得你。

在這裏插入圖片描述

人臉檢測

人臉檢測技術算得上是計算機視覺的基礎級的技術之一。甚至在前深度學習時代,該技術就已經得到了很高程度的發展。在深度學習時代,人臉識別一般是利用卷積神經網絡進行監督式學習,也就是通過讓算法(神經網絡)自己去發現規律的方式,創造出有用的卷積核(一種矩陣),然後利用其進行尋找圖片和視頻中的人臉。而在這之前,人們需要的則是自己去設計算法,尋找人臉。不過後來人們發明了一種近似於深度學習思路的人臉尋找算法,那就是haar算法。

這個算法簡單點來說,就是計算一個區域內不同像素之間的灰度差別,來判斷是不是人臉。原理就是一種有規律的圖像,比如一個物體,無論光線明亮與否,其不同區域之間的像素差總是有一定規律的。就是憑藉這種特殊的思路,科學家們第一次創造出了一種及其有效的人臉識別算法。而且其運算性能要求真的很低。甚至在樹莓派1,2這種計算性能及其低的硬件設備上都能夠快速運行。

OpenCV內部集成了人臉檢測算法,並且OpenCV提供了訓練好的人臉檢測haar模型,使用yml保存。我們只需要簡單的調用其中的類庫就可以對照片或者視頻進行人臉檢測。下面我們就可以利用OpenCV中的攝像頭調用和圖片處理模塊和人臉檢測模塊共同創建一個能夠實時從攝像頭中檢測人臉數據,並將有關數據切割保存下來的程序。有了它,我們就可以創建一個帶標籤的人臉數據庫,然後用於人臉識別。

在這裏插入圖片描述

代碼實現

第一步:加載haar數據,訓練好的數據可以去github下載,或者從我的github下載:https://github.com/FontTian/DS-Exhibitio

face_cascade =cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
   face_cascade.load('./haarcascades/haarcascade_frontalface_default.xml')

第二步:我們需要調取攝像頭,讀取有關數據。同時由於我們需要實時顯示,因此創建循環,在循環中不斷調用獲取攝像頭中的圖片,並進行後續處理。

# 獲取攝像頭
camera = cv2.VideoCapture(0)
# 計數器,用於之後文件的保存
count = 0
# 創建 循環
while (True):
    # 調用攝像頭,獲取圖像
    ret, frame = camera.read()
    # 判斷圖像是否真實存在
    if ret == True:
        ...
        else:
            print("no ret")
            # 使用OpenCV獲取鍵盤輸入,如果輸入q則退出窗口
            if cv2.waitKey(int(1000 / 12)) & 0xFF == ord('q'):
                break

第三步:我們需要創建灰度圖,然後使用人臉檢測器對處理後的圖像進行人臉檢測。同時我們利用人臉檢測器返回的數據,在原圖片中繪製一個方框,並實時顯示。

# 轉換爲灰度圖
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 調用人臉檢測器檢測
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# 繪製檢測出的所有人臉
for (x, y, w, h) in faces:
    # 畫方框
    img = cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
    # 獲取人臉,並轉換爲200,200的統一格式
    # 原始數據返回的是正方形
    f = cv2.resize(gray[y:y + h, x:x + w], (200, 200))

    # 保存圖片
    cv2.imwrite('./data/at/tfs/%s.pgm' % str(count), f)
    count += 1

    # 展示圖片
    cv2.imshow('camera', frame)

這樣一番操作後,我們就獲得了一份人臉數據庫,我們通過文件夾的名字來標識圖片。

人臉識別

在完成人臉檢測之後,我們就得到了一份可以用於人臉識別的人臉數據庫。之後我們就可以調取OpenCV中的人臉識別方法進行人臉識別,但是人臉識別的方法是有很多種實現方式的。如果現在就要將深度學習免不了長篇大論。因此這裏我們將會使用OpenCV中的三種非深度學習方法進行人臉識別,並詳細介紹其使用,簡單介紹其原理。

妹子

代碼實現

OpenCV的人臉識別在face這個類庫中,其自帶三種人臉識別器。我們可以直接調用有關類庫進行訓練和測試以及使用。在這之前我們首先創建鏈表將原來保存的圖片以矩陣形式加載。

import numpy as np

#  創建空鏈表
images = []
# 使用OpenCV加載fonttian的幾張人臉照片
images.append(cv2.imread("data/at/fonttian/15.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/fonttian/17.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/fonttian/55.pgm",cv2.IMREAD_GRAYSCALE))

# 使用OpenCV加載zjz的幾章人臉照片
images.append(cv2.imread("data/at/zjz/15.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/zjz/17.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/zjz/60.pgm",cv2.IMREAD_GRAYSCALE))

# 創建標籤
labels = [0,0,0,1,1,1]

之後我們就可以調取不同人臉識別器來進行人臉識別了。OpenCV中自帶三種人臉識別器——LBPH,EigenFace,Fisher。我們首先創建一個方法,來展示不同人臉識別器的判斷結果和輸出的置信度,置信度的範圍選擇我們在下一步會詳細描述。

# 創建測試文件路徑
imgPath = "data/at/fonttian/570.pgm"

# 傳入測試圖片路徑,識別器,原始人臉數據庫,人臉數據庫標籤
def showConfidence(imgPath,recognizer,images,labels):
    # 訓練識別器
    recognizer.train(images,np.array(labels))
    # 加載測試圖片
    predict_image=cv2.imread(imgPath,cv2.IMREAD_GRAYSCALE)
    # 預測並打印結果
    labels,confidence = recognizer.predict(predict_image)
    print("label=",labels)
    print("conficence=",confidence)

上面的幾個步驟就是人臉識別器的一般步驟,本質上來說人臉識別器與一般的機器學習模型都是一樣的。需要有標籤的數據,然後來做分類。所以首先需要使用標記好的數據來進行訓練,並用新的數據進行預測。而人臉識別器的關鍵則在於如何從人臉中提取特徵,並使用特徵進行人臉識別。這是人臉識別的永恆套路,以前如此,現在也如此。

在這裏插入圖片描述

EigenFace是基於PCA的人臉識別器,一般置信程度5000以下判斷爲可靠,PCA就是主成分分析,其在人臉識別中的作用就是提取出人臉的主要信息,以此來判斷不同人。

LBPH是局部二值模式直方圖,局部二值,指的是某一點像素與周圍點的大小差別,0和1指的就是其大小關係。其核心原理類似於haar都是計算局部像素之間的差異關係來進行圖像識別。

Fisher是基於線性判別的人臉識別器。線性判別廣泛應用於機器學習的多個領域,分類,聚類,推薦中都存儲在其身影。在這裏其基本思想與PCA一致,都是降維獲得該人臉的人臉特徵然後通過人臉特徵來進行人臉識別。

具體的置信度如下所示,我們如果直接選擇打印labels,那麼程序會直接從給出最佳結果,對於測試而言或許是足夠的。但是使用置信度來進行檢測纔是更好地方法。

# EigenFace(PCA,5000以下判斷可靠)
recognizer = cv2.face.EigenFaceRecognizer_create()
showConfidence(imgPath,recognizer,images,labels)
# LBPH(局部二值模式直方圖,0完全匹配,50以下可接受,80不可靠)
recognizer = cv2.face.LBPHFaceRecognizer_create()
showConfidence(imgPath,recognizer,images,labels)
# Fisher(線判別分析 , 5000以下判斷爲可靠)
recognizer = cv2.face.FisherFaceRecognizer_create()
showConfidence(imgPath,recognizer,images,labels)

現在運行上面的代就可以告訴我們最終結果了。下面就是運行結果

在這裏插入圖片描述

人臉識別,人臉檢測的技術雖然一直都在發展,準確度和計算量都在不斷提升。但是作爲一項應用或者說一個領域,萬變不離其宗。我們可以首先從OpenCV的幾十行代碼起步,逐步掌握深度學習下的人臉識別。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章