欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于树莓派opencv—Python的人脸面部特征框选(眼睛和微笑)

程序员文章站 2022-07-13 10:19:55
...

基于树莓派opencv—Python的人脸面部特征框选(眼睛和微笑)
广西●河池学院

广西高校重点实验室培训基地

系统控制与信息处理重点实验室

本篇博客来自河池学院: 智控无人机小组

写作时间: 2020年8月16日

一、测试相机

在树莓派上新建一个.py文件,将以下代码放入运行。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)
cap.set(3,640) # 宽
cap.set(4,480) # 高
 
while(True):
    ret, frame = cap.read()
    frame = cv2.flip(frame, -1) # 相机垂直翻转
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    cv2.imshow('frame', frame)
    cv2.imshow('gray', gray)
    
    k = cv2.waitKey(30) & 0xff
    if k == 27: # press 'ESC' to quit
        break

cap.release()
cv2.destroyAllWindows()

效果为:
基于树莓派opencv—Python的人脸面部特征框选(眼睛和微笑)
如果产生画面翻转的现象将 代码中
frame = cv2.flip(frame, -1)替换为frame = cv2.flip(frame, 1)即可。

二、脸部侦测

检测人脸(或任何物体)的最常见方法是使用“ Haar Cascade分类器 ”使用基于Haar特征的级联分类器的对象检测是Paul Viola和Michael Jones在其论文“使用简单特征的增强级联进行快速对象检测”中于2001年提出的一种有效的对象检测方法。这是一种基于机器学习的方法,其中从许多正负图像中训练级联函数。然后用于检测其他图像中的对象。
如果想要为任何物体训练自己的分类器,就可以使用opencv自己建一个,详细信息在下面网址
https://docs.opencv.org/3.3.0/dc/d88/tutorial_traincascade.html
如果不想创建自己的分类器,OpenCV已经包含许多针对面部,眼睛,微笑等的经过预先训练的分类器。可以从haarcascades目录中招待这些XML文件并调用。
检测人脸:

import numpy as np
import cv2

# multiple cascades: https://github.com/Itseez/opencv/tree/master/data/haarcascades
faceCascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')
eyeCascade = cv2.CascadeClassifier('Cascades/haarcascade_eye.xml')
smileCascade = cv2.CascadeClassifier('Cascades/haarcascade_smile.xml')

cap = cv2.VideoCapture(0)
cap.set(3,640) # set Width
cap.set(4,480) # set Height

while True:
    ret, img = cap.read()
    img = cv2.flip(img, -1)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.3,
        minNeighbors=5,      
        minSize=(30, 30)
    )

    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        
        eyes = eyeCascade.detectMultiScale(
            roi_gray,
            scaleFactor= 1.5,
            minNeighbors=5,
            minSize=(5, 5),
            )
        
        for (ex, ey, ew, eh) in eyes:
            cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
               
        
        smile = smileCascade.detectMultiScale(
            roi_gray,
            scaleFactor= 1.5,
            minNeighbors=15,
            minSize=(25, 25),
            )
        
        for (xx, yy, ww, hh) in smile:
            cv2.rectangle(roi_color, (xx, yy), (xx + ww, yy + hh), (0, 255, 0), 2)
        
        cv2.imshow('video', img)

    k = cv2.waitKey(30) & 0xff
    if k == 27: # press 'ESC' to quit
        break

cap.release()
cv2.destroyAllWindows()

注意下面这行代码

faceCascade = cv2.CascadeClassifier('Cascades / haarcascade_frontalface_default.xml')

这是加载“分类器”的行,也就是我们调用opencv本身含有的预先训练的分类器。(眼睛和微笑同理)

faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.3,
        minNeighbors=5,      
        minSize=(30, 30)
    )

这是分类器函数可以设置比例因子,邻居数和所要检测面部的最小尺寸。
gray:是输入的灰度图像。
scaleFactor:是一个参数,用于指定每个图像比例缩小多少图像。它用于创建比例金字塔。
minNeighbors:是一个参数,用于指定每个候选矩形要保留多少个邻居。数字越大,误报率越低。
minSize:是被视为面的最小矩形大小。
用蓝色矩形在图像中“标记”面部,代码如下(眼睛和微笑同理):

   for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]

如果找到了脸部,则将检测到的脸部的位置返回为矩形,其矩形的左上角(x,y),宽度为“ w”,高度为“ h” ==>(x,y,w, H)。
一旦获得这些位置,就可以为该面部创建一个“ ROI”(绘制的矩形),并使用imshow()函数显示结果。