了解一套工具最好的方法是:动手完成一个现有的范例
了解一门技术最好的方法是:用那套技术完整做出一个自己的应用Get your hands dirty!
介绍完目前主流的API与相关平台後,还是要回头来看看要如何自行写程序完成一样的功能。
前面提到过,使用OpenCV & Dlib来做人脸侦测,大概可以分为四种方式:
今天说这个
接下来就依序介绍各个方式吧。
注
:如同在第一天提到的,这个系列使用的主要语言是Python
,对Python不了解或有疑问的可以参考其他邦友发表的优质文章
这边推荐两种Python开发环境使用:
由於接下来的实作大部分都会围绕在自行开发上,为了能够更方便的整合专案,後续的开发环境都会使用PyCharm来作范例说明与实作,关於PyCharm的安装与使用请参考邦帮忙其他相关文章
习惯上我喜欢称呼这个方法叫哈尔特徵检测
,
它以辨识速度极快、硬体需求低,常常会被应用在各种行动装置或是树莓派(Raspberry Pi)等硬体规格相对低阶的装置上。
这个方法主要是透过滑动检测事先定义好的小矩形,由左上至右下,找寻人脸上明显的特徵:如两眼之间的鼻子区域通常比眼睛更亮,然後慢慢把非人脸区域排除。从而检测出人脸真正区域
这个技术相关的原理在网路上都可以搜寻的到,这边就让我们直接开始实作吧!
打开PyCharm IDE,新增一个专案
(可不用) 点击上方工具栏的「File」->「Settings」->「Project: your_project_name」->「Python Interpreter」,新增一个Python的虚拟运作环境
点选上方的"+"符号安装套件
依序在搜寻框输入下面的套件名称,确认版本相同後,按下方的「Install Package」安装套件
安装需要一点时间...等待安装都成功後,关闭视窗。在主视窗开启下方的「Terminal」,输入pip freeze
:
> pip freeze
确认你安装的套件与版本是否与下面相同
cmake==3.21.2
dlib==19.22.1
imutils==0.5.4
numpy==1.21.2
opencv-contrib-python==4.5.3.56
接下来在新增的专案目录下新增目录:face_detection,专门放人脸侦测相关档案用
再来新增一个Python档案:opencv_haar_cascade.py,撰写今天主程序
在新增的Python档案内输入以下内容 (相关程序码说明在注解内):
# 汇入必要套件
import argparse
import ntpath
import os
import time
import cv2
import imutils
from imutils.video import WebcamVideoStream
detectors = {
"eye": os.path.sep.join([ntpath.dirname(cv2.__file__), 'data', 'haarcascade_eye.xml']),
"face": os.path.sep.join([ntpath.dirname(cv2.__file__), 'data', 'haarcascade_frontalface_default.xml'])
}
# 定义人脸侦测函数方便重复使用
def detect(gray, part="face"):
# 初始化Haar cascades函数
detector = cv2.CascadeClassifier(detectors[part])
# 根据选择的模型侦测
rects = detector.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=5, minSize=(15, 15),
flags=cv2.CASCADE_SCALE_IMAGE)
return rects
def main():
# 初始化arguments
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--part", type=str, choices=["eye", "face"], default="face", help="detect which part of face")
args = vars(ap.parse_args())
# 启动WebCam
vs = WebcamVideoStream().start()
time.sleep(2.0)
start = time.time()
fps = vs.stream.get(cv2.CAP_PROP_FPS)
print("Frames per second using cv2.CAP_PROP_FPS : {0}".format(fps))
while True:
# 取得当前的frame,变更比例为宽300,并且转成灰阶图片
frame = vs.read()
img = frame.copy()
img = imutils.resize(img, width=300)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 呼叫侦测函数,取得结果
rects = detect(gray, args["part"])
# 绘出侦测结果 (记得将侦测的座标转回原本的frame大小)
ratio = frame.shape[1] / img.shape[1]
for rect in rects:
rect = rect * ratio
(x, y, w, h) = rect.astype("int")
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 标示FPS
end = time.time()
text = f"FPS: {str(int(1 / (end - start)))}"
cv2.putText(frame, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
start = end
# 显示影像
cv2.imshow("Frame", frame)
# 判断是否案下"q";跳离回圈
key = cv2.waitKey(1) & 0xff
if key == ord('q'):
break
# 清除画面与结束WebCam
cv2.destroyAllWindows()
vs.stop()
if __name__ == '__main__':
main()
运行程序:
python face_detection/opencv_haar_cascade.py
或执行後,会开启WebCam,并且显示类似下面的节果:
你可以试着将启动指令改成python face_detection/opencv_haar_cascade.py -p eye
跑看看会有什麽结果。
戴口罩基本上无法成功辨识,这是由於前面提到哈尔特徵检测的作法是滑动视窗的限制,你可以试着比对戴上口罩前与戴上口罩後玩看看
一般WebCam的FPS为30 (你可以透过print(vs.stream.get(cv2.CAP_PROP_FPS))
检查看看),透过哈尔特徵检测处理宽为300px的影像还是可以有约28 ~ 32 fps;後续可以跟其他方法比较看看,这个速度算是非常快了 (在实际使用下几乎感受不到延迟)
哈尔特徵检测的false-positive (失败侦测)结果会受程序码39行的detectMultiScale()
参数影响:
[1.0, MAX_VALUE]
,越小检测出的结果越多 (也需花费更多时间),通常会使用1.05 ~ 1.1
之间的数值正整数
,越小检测的结果越多 (但失败侦测的可能性也变大),通常会使用3 ~ 10
之间的数值(正整数, 正整数)
的格式,通常会从(30, 30)
开始使用,根据结果再调整cv2.CASCADE_SCALE_IMAGE
以上的参数的调整会非常容易改变最终的结果,这边建议根据你实际执行的情况来做调整,顺序建议为:
minSize -> minNeighbors -> scaleFactor
OpenCV内建的检测模型还有其他很多可以使用,如侦测眼睛、微笑、上半身、全身等等,可以参考程序码20-21行的路径目录;有兴趣可以到该目录下看看
参考程序码在这
就这样,想到再补充。
明天见!
206. Reverse Linked List https://leetcode.com/prob...
SQL Server 1.一个一个TABLE去点,汇出Scripts 2.SQL Server 汇出...
该文章同步发布於:我的部落格 改变数值的时候 昨天提到变动性的问题是什麽呢? 我们到现在的测试都是...
小弟近日工作刚好会用到Azure,公司希望我们可以以考取AZ204为目标,所以接下来会照着这个目标发...
WhatsApp 聊天记录消失了? 如何恢复 WhatsApp 照片和信息? 我们都有过 Whats...