文章目錄
- 引言
- 一、技術原理
- 二、代碼實現
- 2.1 關鍵代碼解析
- 2.1.1 模型加載
- 2.1.2 圖像翻轉
- 2.1.3 人臉檢測 + 微笑檢測
- 2.2 顯示效果
- 三、參數調優建議
- 四、總結
引言
在計算機視覺領域,人臉檢測和表情識別一直是熱門的研究方向。今天我將分享一個使用Python和OpenCV實現的實時人臉微笑檢測系統。這個系統能夠通過攝像頭捕捉視頻流,實時檢測人臉并識別微笑表情,非常適合初學者學習計算機視覺的基礎應用。
一、技術原理
本實現主要基于OpenCV提供的Haar級聯分類器,使用了兩個預訓練模型:
- haarcascade_frontalface_default.xml - 用于人臉檢測
- haarcascade_smile.xml - 用于微笑檢測
Haar級聯分類器是一種基于機器學習的物體檢測方法,由Paul Viola和Michael Jones在2001年提出。它通過訓練大量正負樣本,學習物體的特征模式,從而實現快速檢測。
二、代碼實現
import cv2# 加載預訓練模型
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
smile = cv2.CascadeClassifier("haarcascade_smile.xml")
cap = cv2.VideoCapture('smile.mp4') #初始化攝像頭while True: #處理每一幀ret,image = cap.read() #讀取一幀image = cv2.flip(image,1) #圖片翻轉,水平翻轉(鏡像)# 沒有讀到,直接退出if ret is None:break# 轉換為灰度圖像gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# 人臉檢測faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1,minNeighbors=15,minSize=(5,5) )# 處理每個人臉for (x,y,w,h) in faces:cv2.rectangle(image,(x,y),(x + w,y + h),(0,255,0),2)# 提取人臉ROI區域(灰度)roi_gray_face = gray[y:y+h,x:x+w]cv2.imshow('Face ROI',roi_gray_face)# 微笑檢測,僅在人臉區域內檢測smiles = smile.detectMultiScale(roi_gray_face,scaleFactor=1.5,minNeighbors=2,minSize=(50,50))for (sx,sy,sw,sh) in smiles:# 繪制微笑區域a = x + sxb = y + sycv2.rectangle(image,(a,b),(a+sw,b+sh),(255,0,0),2)# 顯示"smile"文字cv2.putText(image,"smile",(x,y),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(0,255,255),thickness=2)# 顯示結果cv2.imshow("Smile Detection",image)key = cv2.waitKey(25)if key ==27: # ESC鍵退出break# 釋放資源
cap.release()
cv2.destroyAllWindows()
2.1 關鍵代碼解析
2.1.1 模型加載
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
smile = cv2.CascadeClassifier("haarcascade_smile.xml")
這兩行代碼加載了OpenCV提供的預訓練Haar級聯分類器模型。
2.1.2 圖像翻轉
image = cv2.flip(image, 1)
-
cv2.flip()函數
- 作用:翻轉輸入圖像(水平、垂直或同時翻轉)。
- 參數:
- 第1個參數
image
:輸入的圖像(NumPy數組)。 - 第2個參數
1
:翻轉模式的標志。0
:垂直翻轉(沿x軸翻轉)。1
:水平翻轉(沿y軸翻轉,即鏡像效果)。-1
:同時水平和垂直翻轉。
- 第1個參數
-
flipCode=1 的效果
假設原圖為:
原圖: [A B C] → 翻轉后: [C B A][D E F] [F E D]
- 每一行的元素順序被反轉,但行的順序不變。
2.1.3 人臉檢測 + 微笑檢測
for (x,y,w,h) in faces:cv2.rectangle(image,(x,y),(x + w,y + h),(0,255,0),2)# 提取人臉所在區域,多通道形式# roiColorFace = image(y:y+h,x:x+w)# 提取人臉所在區域,單通道形式roi_gray_face = gray[y:y+h,x:x+w]cv2.imshow('lian',roi_gray_face)# 微笑檢測,僅在人臉區域內檢測smiles = smile.detectMultiScale(roi_gray_face,scaleFactor=1.5,minNeighbors=2,minSize=(50,50))for (sx,sy,sw,sh) in smiles:# 繪制微笑區域a = x + sxb = y + sycv2.rectangle(image,(a,b),(a+sw,b+sh),(255,0,0),2)# 顯示文字“smile” 表示微笑了cv2.putText(image,"smile",(x,y),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(0,255,255),thickness=2)
這段代碼是一個 人臉檢測 + 微笑檢測 的程序,主要使用了 OpenCV 的 Haar 級聯分類器(detectMultiScale
)來檢測人臉和微笑。以下是詳細解析:
代碼功能概述
- 檢測人臉(在
faces
中存儲的人臉矩形框)。 - 提取人臉區域(灰度圖
roi_gray_face
)。 - 在人臉區域內檢測微笑(
smiles
)。 - 繪制人臉框和微笑框,并標注文字“smile”。
代碼逐行解析
1. 遍歷檢測到的人臉
for (x, y, w, h) in faces:
faces
是一個包含人臉矩形框的列表,每個框由(x, y, w, h)
表示:(x, y)
:人臉左上角坐標。(w, h)
:人臉的寬度和高度。
2. 繪制人臉矩形框
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
- 在原始圖像
image
上繪制綠色矩形框(RGB(0,255,0)
),線寬為2
。
3. 提取人臉區域(灰度圖)
roi_gray_face = gray[y:y+h, x:x+w]
cv2.imshow('lian', roi_gray_face)
gray
是灰度圖像(單通道)。roi_gray_face
是從gray
中截取的人臉區域。cv2.imshow('lian', roi_gray_face)
顯示人臉區域的灰度圖(窗口名'lian'
)。
4. 在人臉區域內檢測微笑
smiles = smile.detectMultiScale(roi_gray_face,scaleFactor=1.5,minNeighbors=2,minSize=(50, 50)
)
smile
是一個訓練好的 Haar 級聯分類器(用于微笑檢測)。- 參數說明:
scaleFactor=1.5
:每次圖像縮放的比例(越大檢測越快,但可能漏檢)。minNeighbors=2
:候選框至少需要多少個鄰近檢測才被確認(越小誤檢越多)。minSize=(50, 50)
:微笑區域的最小尺寸(小于該尺寸的忽略)。
5. 遍歷檢測到的微笑區域
for (sx, sy, sw, sh) in smiles:
smiles
包含微笑矩形框(sx, sy, sw, sh)
,坐標是相對于roi_gray_face
(人臉區域)的。
6. 繪制微笑框(藍色)
a = x + sx # 轉換到原始圖像的坐標
b = y + sy
cv2.rectangle(image, (a, b), (a + sw, b + sh), (255, 0, 0), 2)
(a, b)
是微笑框在原始圖像image
中的左上角坐標。- 繪制藍色矩形框(RGB
(255,0,0)
),線寬2
。
7. 標注文字“smile”
cv2.putText(image, "smile", (x, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 255, 255), 2)
- 在人臉框左上角
(x, y)
處顯示黃色文字“smile”:- 字體:
cv2.FONT_HERSHEY_COMPLEX_SMALL
。 - 字號:
1
。 - 顏色:
(0, 255, 255)
(黃色)。 - 線寬:
2
。
- 字體:
代碼執行流程
- 輸入圖像 → 檢測人臉 → 繪制綠色人臉框。
- 提取人臉區域 → 檢測微笑 → 繪制藍色微笑框。
- 標注“smile”文字 → 顯示結果。
注意事項
- 依賴 Haar 級聯分類器:
faces
和smiles
是由cv2.CascadeClassifier
檢測得到的。- 通常需要加載預訓練模型:
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml')
- 參數調優:
scaleFactor
和minNeighbors
影響檢測精度和速度,需根據實際場景調整。
- 坐標轉換:
- 微笑檢測是在人臉區域 (
roi_gray_face
) 內進行的,繪制時需要轉換回原始圖像坐標。
- 微笑檢測是在人臉區域 (
2.2 顯示效果
# 顯示結果cv2.imshow("dect",image)key = cv2.waitKey(25)if key ==27:break
cap.release()
cv2.destroyAllWindows()
- 顯示效果如下,我們插入一段視頻,在視頻中對人物進行微笑檢測,并畫出檢測框:
三、參數調優建議
-
人臉檢測參數:
minNeighbors
值越大,檢測越嚴格,但可能漏檢scaleFactor
通常在1.01-1.5之間
-
微笑檢測參數:
- 由于微笑區域相對較小,
minSize
不宜設置過大 minNeighbors
可以適當調小以避免漏檢
- 由于微笑區域相對較小,
四、總結
本文介紹了一個基于OpenCV Haar級聯分類器的實時微笑檢測系統。雖然Haar級聯分類器在復雜場景下可能表現不佳,但它的計算效率高,非常適合初學者學習和快速原型開發。通過調整參數和優化流程,可以在實際應用中獲得不錯的效果。