使用 Haar 級聯分類器的 OpenCV 人臉檢測

Salman Mehmood 2022年6月7日
使用 Haar 級聯分類器的 OpenCV 人臉檢測

在這個演示中,我們將藉助基於 haar 特徵的級聯分類器學習人臉檢測的基礎知識,並學習如何在 OpenCV 中從影象和視訊中檢測人臉。

在 OpenCV 中使用 Haar 級聯分類器建立人臉檢測專案

使用基於 Haar 特徵的級聯分類器進行物件檢測是 Paul Viola 和 Michael Jones 在他們的研究中提出的一種有效的物件檢測方法。Haar 基於特徵的級聯分類器是一種基於機器學習的方法,其中針對許多正負影象訓練級聯函式。

那麼這些正面和負面的形象是什麼?分類器使用特定物件的數百個樣本檢視進行訓練,這些物件可能是人臉、汽車或任何其他稱為正例的物件。

例如,如果要檢測人臉,則必須使用包含人臉的影象數量來訓練分類器。然後,它被稱為正面影象。

在另一種情況下,如果要檢測人臉並且影象中不包含人臉,則稱為負像。

訓練分類器後,可以將其應用於輸入影象中的感興趣區域。如果區域可能顯示物件,則分類器輸出為 1;否則為 0。

讓我們看看如何在 OpenCV 中使用 Haar Cascade 檢測。

OpenCV 帶有一個訓練器和一個檢測器。如果你想針對手錶、汽車或任何物體等任何物件訓練分類器,則可以使用此分類器。

我們可以在 OpenCV GitHub 頁面上找到一些經過訓練的分類器 XML 檔案。這個儲存庫中有大量訓練有素的分類器。

OpenCV GitHub 訓練的分類器 XML 檔案

你只需要開啟這個突出顯示的檔案,然後通過單擊原始圖示按鈕下載它。當它開啟時,你可以右鍵單擊並將其儲存在你的計算機上。

讓我們開啟程式碼編輯器並定義我們的分類器。

有一個名為 CascadeClassifier() 的方法,我們可以在其中提供分類器路徑。一旦我們定義了分類器,然後我們讀取影象。

F_C = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

由於此分類器將處理灰度影象,因此我們需要將影象轉換為灰度影象。實現影象轉換將非常容易。

IMG = cv2.imread('inp.png')
G_scale = cv2.cvtColor(IMG, cv2.COLOR_BGR2GRAY)

下一步是檢測這張圖片中的人臉;為此,我們將宣告一個名為 Faces 的變數。我們將呼叫 detectMultiScale() 方法,該方法接受三個引數。

第一個是灰度影象,我們要使用的第二個引數是比例因子,用於指定在每個影象比例下影象尺寸縮小多少。接下來是最小鄰居引數,它指定每個候選矩形應該有多少鄰居來保留它。

Faces = F_C.detectMultiScale(G_scale, 1.1, 4)

最後一步是遍歷我們檢測到的所有面部,然後繪製一個矩形。這個 Faces 變數將是矩形的向量,其中每個矩形都包含一個檢測到的物件,在我們的例子中,它將是檢測到的人臉。

我們將從 Faces 物件中獲取引數 (x,y,w,h)。這些是物件矩形的值。

在獲取座標時,我們將使用 rectangle() 方法繪製矩形。

它需要一些引數。第一個是影象,第二個是我們使用 Faces 向量得到的點 (x,y),下一個引數是矩形的第二個點。

接下來的兩個引數是顏色和厚度。

import cv2

F_C = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

IMG = cv2.imread('inp.png')
G_scale = cv2.cvtColor(IMG, cv2.COLOR_BGR2GRAY)
Faces = F_C.detectMultiScale(G_scale, 1.1, 4)

for (x, y , w ,h) in Faces:
    cv2.rectangle(IMG, (x,y), (x+w, y+h), (255, 0 , 0), 3)

cv2.imshow('IMG', IMG)

cv2.waitKey()

現在我們可以看到在影象中檢測到人臉。

OpenCV Haar 級聯影象人臉檢測輸出

讓我們嘗試檢測視訊中的人臉,所以這不會是一種不同的方法。我們只需要將這種方法應用於每一幀,因此我們將使用 VideoCapture() 方法來捕獲視訊,而不是讀取影象。

為了捕捉幀,我們需要定義一個 Video 變數並使其等於 VideoCapture() 並提供一個 mp4 檔案。如果你有相機,你可以提供它 0。

現在我們將所有上述程式碼包含在一個 while 迴圈中,並且在 while 迴圈中,我們定義 isOpened() 方法。如果此方法返回真值,則程式將繼續讀取幀;我們將呼叫 Video.read(),這意味著我們正在讀取每一幀。

當有人按下 q 鍵時,我們將定義一個條件,然後程式將跳出 while 迴圈。最後,在我們的 while 迴圈之外,我們將釋出我們的視訊。

import cv2

F_C = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

Video = cv2.VideoCapture('inp.mp4')

while Video.isOpened():
    _, IMG = Video.read()

    G_scale = cv2.cvtColor(IMG, cv2.COLOR_BGR2GRAY)
    Faces = F_C.detectMultiScale(G_scale, 1.1, 4)

    for (x, y , w ,h) in Faces:
        cv2.rectangle(IMG, (x,y), (x+w, y+h), (255, 0 , 0), 3)

    cv2.imshow('Window', IMG)
    K=cv2.waitKey(1)
    if K & 0xFF == ord('q'):
        break

Video.release()

在這段視訊中,我們可以看到實時視訊中檢測到的人臉。

OpenCV Haar 級聯視訊人臉檢測輸出

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

相關文章 - Python OpenCV