1. 級聯(lián)分類器: OpenCV提供的級聯(lián)分類器有Harr、HOG、LBP這3種,這些分類器以XML文件保存,這里主要演示Harr檢測人臉(OpenCV提供的分類器不僅限于檢測人臉,還包括下表特征檢測,當(dāng)然OpenCV還支持訓(xùn)練自己的級聯(lián)分類器,這里不做說明。。。)。
2. 函數(shù)介紹:
object = cv2.CascadeClassifier(filename) 加載分類器
- object:分類器對象。
- filename:分類器xml路徑+文件名。
object= faceCascade.detectMultiScale(img,scaleFactor,minNeighbors,minSize,maxSize) 檢測對象
- object:返回值(目標(biāo)對象的x、y、w、h信息)。
- scaleFactor:縮放比例。
- minNeighbors:檢測目標(biāo)的相鄰矩形的最小個數(shù)。默認(rèn)為3,表示滿足3個以上的檢測標(biāo)記才會認(rèn)為是人臉。該值越大越準(zhǔn)確,但是會導(dǎo)致一些人臉檢測不到。
- minSize:目標(biāo)最小尺寸,小于會被忽略。
上代碼:檢測圖片中的人臉
import cv2
# 1 原始圖像處理
image = cv2.imread('model1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# 2 加載分類器
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 3 人臉檢測
faces = faceCascade.detectMultiScale(
gray,
scaleFactor = 1.01,
minNeighbors = 15,
minSize = (8,8))
# 4 打印輸出的實(shí)現(xiàn)
print("發(fā)現(xiàn){0}張人臉!".format(len(faces)))
print("其位置分別是:")
print(faces)
# 5 遍歷檢測對象
for(x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2) # 繪制矩形(x、y、w、h)
cv2.imshow("result",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
運(yùn)行:
上代碼:通過攝像頭檢測人臉
import cv2
# 1 加載分類器
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 2 處理攝像頭視頻
# 初始化攝像頭
cap=cv2.VideoCapture(0,cv2.CAP_DSHOW)
# 處理每一幀
while True:
# 讀取一幀
ret,image=cap.read()
image=cv2.flip(image,1)
# 沒有讀到,直接退出
if ret is None:
break
# 灰度化(彩色BGR-->灰度Gray)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# 人臉檢測
faces = faceCascade.detectMultiScale(gray,
scaleFactor = 1.1,
minNeighbors = 5,
minSize = (5,5))
# 處理每個人臉
for(x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
# 提取人臉?biāo)趨^(qū)域,單通道形式
roi=gray[y:y+h,x:x+w] #image[起點(diǎn),終點(diǎn)]
# 顯示結(jié)果
cv2.imshow("dect",image)
cv2.imshow("roi",cutFace)
key=cv2.waitKey(25)
if key==27:
break
cap.release()
cv2.destroyAllWindows()
運(yùn)行:
3. dlib庫檢測人臉: 免費(fèi)的開源庫,雖然測試速度不及前面的Harr級聯(lián)分類器,但是準(zhǔn)確率非常高。
- 檢測人臉:
① detector=dlib.get_frontal_face_detector() 構(gòu)造dlib檢測器
② faces=detector(img,n) 檢測人臉
faces:人臉集合。
n:上采樣次數(shù),圖像會變大,但是準(zhǔn)確率會提高,這個參數(shù)對速度影響極大。
上代碼:
import cv2
import dlib
# dlib初始化
detector=dlib.get_frontal_face_detector()
# 讀取原始圖像
img=cv2.imread("imgs/3.jpg")
# 使用人臉檢測器返回檢測到的人臉框
faces=detector(img,1)
# 遍歷人臉集合
for face in faces:
# 獲取人臉框的坐標(biāo)
x1=face.left()
y1=face.top()
x2=face.right()
y2=face.bottom()
# 繪制人臉框
cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),2)
# 顯示捕獲到的各個人臉框
cv2.imshow("result",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
運(yùn)行:
- 檢測關(guān)鍵點(diǎn):
① detector=dlib.get_frontal_face_detector() 構(gòu)造dlib檢測器
② faces=detector(img,n) 檢測人臉
③ predictor = dlib.shape_predictor(dat) 加載預(yù)測
dat:模型文件
predictor:預(yù)測器對象,返回68個臉部關(guān)鍵點(diǎn)。
上代碼:
import numpy as np
import cv2
import dlib
# 讀取圖像
srcImg = cv2.imread("model.jpg")
img=srcImg.copy()
# Step 1:構(gòu)造人臉檢測器(dlib初始化)
detector = dlib.get_frontal_face_detector()
# Step 2:檢測人臉框(使用人臉檢測器返回檢測到的人臉框)
faces = detector(img, 1)
# Step 3:載入模型(加載預(yù)測器)
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
index=0
# Step 4:獲取每一張臉的關(guān)鍵點(diǎn)(實(shí)現(xiàn)檢測)
for face in faces:
index+=1
# 檢測當(dāng)前人臉的關(guān)鍵點(diǎn)
shape=predictor(img, face)
# 下面對這句代碼進(jìn)行了分解
# landmarks = np.matrix([[p.x, p.y] for p in shape.parts()])
# 通過shape.parts()方法遍歷關(guān)鍵點(diǎn)
for i, p in enumerate(shape.parts()):
print('face:'+str(index)+' predictor:'+str(i)+' x:'+str(p.x)+' y:'+str(p.y))
# 將關(guān)鍵點(diǎn)的x,y放入一個2列68行的矩陣中,需要知道的是,人臉的每個特征對應(yīng)的關(guān)鍵點(diǎn)索引是固定的,比如36-42描述的右眼。
landmarks = np.matrix([[p.x, p.y]])
# Step 5:繪制每一張臉的關(guān)鍵點(diǎn)(繪制shape中的每個點(diǎn))
for idx, point in enumerate(landmarks):
# 當(dāng)前關(guān)鍵的坐標(biāo):[0,1]表示第0行第1個元素
pos = (point[0, 0], point[0, 1])
# 針對當(dāng)前關(guān)鍵點(diǎn),繪制一個實(shí)心圓
cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1)
# 字體
font = cv2.FONT_HERSHEY_SIMPLEX
# 利用cv2.putText輸出1-68,索引序號加1,顯示時從1開始。
cv2.putText(img, str(i + 1), pos, font, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
# 繪制結(jié)果
cv2.imshow("img", img)
cv2.imshow("src", srcImg)
cv2.waitKey()
cv2.destroyAllWindows()
- 勾勒五官輪廓:
關(guān)鍵點(diǎn)檢測實(shí)現(xiàn)步驟和前面一樣,唯一不同的是:
臉部輪廓、眉毛這種起點(diǎn)和終點(diǎn)分開的區(qū)域,首先找到輪廓所在的關(guān)鍵點(diǎn),然后使用點(diǎn)到點(diǎn)之間繪制直線的方式繪制邊緣。
臉部眼睛、嘴巴這種起點(diǎn)和終點(diǎn)最終匯聚在一起的區(qū)域,首先找到輪廓所在的關(guān)鍵點(diǎn),然后將這一組關(guān)鍵點(diǎn)坐標(biāo)作為輪廓數(shù)組傳入convexHull()函數(shù)進(jìn)行凸包繪制。
凸包:找到圖形最外側(cè)的端點(diǎn),然后將其連接起來。
凸包示例代碼:
import cv2
img = cv2.imread("shape2.png") # 讀取原始圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)為灰度圖像
ret, binary = cv2.threshold(gray, 127, 225, cv2.THRESH_BINARY) # 二值化閾值處理
# 檢測圖像中出現(xiàn)的所有輪廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
hull = cv2.convexHull(contours[0]) # 獲取輪廓的凸包
cv2.drawContours(img, [hull], -1, (0, 255, 0), 2)
cv2.imshow("img", img) # 顯示圖像
cv2.waitKey() # 按下任何鍵盤按鍵后
cv2.destroyAllWindows() # 釋放所有窗體
凸包運(yùn)行結(jié)果:
勾勒五官輪廓代碼:
import numpy as np
import dlib
import cv2
# 模型初始化
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 自定義函數(shù)drawLine,將指定的點(diǎn)連接起來
def drawLine(start,end):
# 獲取點(diǎn)集
pts = shape[start:end]
# 遍歷點(diǎn)集,將各個點(diǎn)用直線連接起來
for l in range(1, len(pts)):
ptA = tuple(pts[l - 1])
ptB = tuple(pts[l])
cv2.line(image, ptA, ptB, (0, 255, 0), 2)
# 自定義函數(shù),將指定的點(diǎn)構(gòu)成一個凸包、繪制其輪廓
def drawConvexHull(start,end):
# 注意,凸包用來繪制眼睛、嘴
# 眼睛、嘴也可以用drawLine通過直線繪制
# 但是,使用凸包繪制輪廓,更方便進(jìn)行顏色填充等設(shè)置
# 獲取某個特定五官的點(diǎn)集
Facial = shape[start:end]
# 針對該五官構(gòu)造凸包
mouthHull = cv2.convexHull(Facial)
# 把凸包輪廓繪制出來
cv2.drawContours(image, [mouthHull], -1, (0, 255, 0), 2)
# 讀取圖像
srcImg=cv2.imread("model2.jpg")
image=srcImg.copy()
# 色彩空間轉(zhuǎn)換彩色(BGR)-->灰度(Gray)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 獲取人臉
faces = detector(gray, 3)
# 對檢測到的rects,逐個遍歷
for face in faces:
# 針對臉部的關(guān)鍵點(diǎn)進(jìn)行處理,構(gòu)成坐標(biāo)(x,y)形式
shape = np.matrix([[p.x, p.y] for p in predictor(gray, face).parts()])
# ============使用函數(shù)drawConexHull繪制嘴、眼睛=========================
#獲取嘴部的關(guān)鍵點(diǎn)集(在整個臉部索引中,其索引范圍為[48,60],不包含61)
drawConvexHull(48,59)
# 嘴內(nèi)部
drawConvexHull(60,68)
# 左眼
drawConvexHull(42,48)
# 右眼
drawConvexHull(36,42)
# ============使用函數(shù)drawLine繪制臉頰、眉毛、鼻子=========================
# 將shape轉(zhuǎn)換為np.array
shape=np.array(shape)
# 繪制臉頰,把臉頰的各個關(guān)鍵點(diǎn)(索引0-16,不含17)用線條連接起來
drawLine(0,17)
# 繪制左眉毛,通過將關(guān)鍵點(diǎn)連接實(shí)現(xiàn)(索引18-21)
drawLine(17,22)
# 繪制右眉毛(索引23-26)
drawLine(22,27)
# 鼻子(索引27-36)
drawLine(27,36)
cv2.imshow("Frame", image)
cv2.imshow("Src",srcImg)
cv2.waitKey()
cv2.destroyAllWindows()
運(yùn)行:文章來源:http://www.zghlxwxcb.cn/news/detail-815580.html
以上,如有錯誤,歡迎指正批評!文章來源地址http://www.zghlxwxcb.cn/news/detail-815580.html
到了這里,關(guān)于OpenCV筆記整理【人臉檢測之Harr級聯(lián)分類器&&dlib庫】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!