尝试使用OpenCV,Haar Cascades和Raspberry Pi来计数面孔
因此,我有一个项目,可以通过检测到他们的脸来计算进入小径的人们进入小径的项目。没有任何电源,因此出于电源原因,我使用Raspberry Pi 3 B+被卡住了。我目前正在使用OpenCV和Haar Cascades来检测面孔。我的问题是两个方面。
- 第一个是我的计数器的行为更像是计时器。它继续将其锁定在整个过程中的整个时间上。我需要的行为是仅在检测检测时才增加一次,而直到丢失该检测然后重新定位之前,它才能再次递增。如果检测到多个面孔,我还需要工作。
- 第二个问题是Haar Cascades并不擅长检测面孔。我一直在玩参数,但似乎无法获得很好的结果。还尝试了其他方法,例如DLIB,但帧率使其在PI 3上几乎无法使用。
我将在下面发布代码(通过结合一些示例将其拼凑在一起)。目前,它还设置了使用线程(另一个试图挤出更多性能的实验)。据我所知,线程正在起作用,但似乎并没有改善任何东西。大家可以提供任何帮助解决柜台问题或优化在PI上使用的HAAR级联的帮助。 **还应注意使用RASP PI高质量的相机和Ardu Cam镜头。
from __future__ import print_function
from imutils.video import VideoStream
from imutils.video.pivideostream import PiVideoStream
from imutils.video import FPS
from picamera.array import PiRGBArray
from picamera import PiCamera
import argparse
import imutils
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--cascade", type=str,
default="haarcascade_frontalface_default.xml",
help="path to haar cascade face detector")
args = vars(ap.parse_args())
detector = cv2.CascadeClassifier(args["cascade"])
size = 40
counter = 0
# created threaded video
print("[INFO] using threaded frames")
vs = PiVideoStream().start()
time.sleep(2.0)
# loop over some frames...this time using the threaded stream
while True:
# grab the frame from the threaded video stream and resize it
# to have a maximum width of 400 pixels (trying larger frame size)
frame = vs.read()
frame = imutils.resize(frame, width=450)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# perform face detection
rects = detector.detectMultiScale(gray, scaleFactor=1.05,
minNeighbors=6, minSize=(size, size),
flags=cv2.CASCADE_SCALE_IMAGE)
# loop over the bounding boxes
for (x, y, w, h) in rects:
# draw the face bounding box on the image
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Increment counter when face is found
counter += 1
print(counter)
# show the output frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()
So I have a project for a trail camera to count people entering the trail by detecting their faces. There isn't any power available so I am stuck using a Raspberry Pi 3 B+ for power reasons. I am currently using opencv and Haar cascades to detect faces. My problem is two-fold.
- The first one is that my counter behaves more like a timer. It continues to increment the entire time it is locked on whatever it thinks is a face. The behavior I need is for it to increment only once when it gets a detection and not again until that detection is lost and then re-initialized. I also need this to work if there is multiple faces detected.
- The second problem is that Haar cascades isnt great at detecting faces. I've been playing with the parameters, but cant seem to get a great result. Also tried other methods like Dlib, but the framerate makes it almost unusable on the pi 3.
I'll post my code below (cobbled together by combining a few examples). Currently, it is also set-up to use threading (another experiment trying to squeeze out some more performance). As far as I can tell, the threading is working, but doesnt really seem to improve anything. Any help you guys could provide towards solving either the counter issue or optimizing Haar Cascades for use on the Pi would be much appreciated. ** Should also note using Rasp Pi High quality camera and Ardu Cam lenses.
from __future__ import print_function
from imutils.video import VideoStream
from imutils.video.pivideostream import PiVideoStream
from imutils.video import FPS
from picamera.array import PiRGBArray
from picamera import PiCamera
import argparse
import imutils
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--cascade", type=str,
default="haarcascade_frontalface_default.xml",
help="path to haar cascade face detector")
args = vars(ap.parse_args())
detector = cv2.CascadeClassifier(args["cascade"])
size = 40
counter = 0
# created threaded video
print("[INFO] using threaded frames")
vs = PiVideoStream().start()
time.sleep(2.0)
# loop over some frames...this time using the threaded stream
while True:
# grab the frame from the threaded video stream and resize it
# to have a maximum width of 400 pixels (trying larger frame size)
frame = vs.read()
frame = imutils.resize(frame, width=450)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# perform face detection
rects = detector.detectMultiScale(gray, scaleFactor=1.05,
minNeighbors=6, minSize=(size, size),
flags=cv2.CASCADE_SCALE_IMAGE)
# loop over the bounding boxes
for (x, y, w, h) in rects:
# draw the face bounding box on the image
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Increment counter when face is found
counter += 1
print(counter)
# show the output frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您可以按照您的说法使用DLIB,但是您必须使用“ Hog”方法(定向梯度的直方图)而不是“ CNN”进行性能。
位置= face_recognition.face_locations(frame,model =“ hog”)
,但是,如果您真的想获得更快的性能,我会建议您将MediaPipe用于此目的。
在您的RPI3上下载MediaPipe:
sudo pip3 install MediaPipe-rpi3
这是来自MediaPipe Document for Face fetes检测器的示例代码:
我不确定您会得到多少FPS(但肯定比Dlib更好,而且非常非常好准确地说),但是您可以通过在每三个帧上而不是在所有帧上检测面孔来加快性能。
其次,您可以以一种幼稚的方式可以正常工作。
您可以在最后一个检测中提取边界框的中心,如果上一个帧的中心位于当前框架中面部的边界框中,则可能是同一个人。
您可以通过确定当前框架中的新面(其边界框的中心)是否足够接近最后一帧中最后一个中心之一,可以更准确地做到这一点。如果是这样,那可能是同一张脸,所以不算它。
可视化:
希望它对您有效!
First, you can use Dlib as you said but you have to use "HOG" method (Histogram of oriented gradients) instead of "CNN" for performance.
locations = face_recognition.face_locations(frame, model="hog")
But, if you really wanna get the faster performance I will recommend you to use Mediapipe for that purpose.
Download Mediapipe on your rpi3:
sudo pip3 install mediapipe-rpi3
Here is an example code from Mediapipe documentation for faces detector:
I am not sure about how much FPS you will get (but surely better than Dlib and very accurately), but you can speed up the performance by detecting faces on every third frame instead of on all of them.
Secondly, you can do a naive way that probably will work fine.
You can extract the centers of the bounding boxes in the last detection and if a center from the previous frame is inside a bounding box of a face in the current frame, it's probably the same person.
You can do it more accurately by determining if the new center of the face in the current frame (the center of his bounding box) is close enough to one of the last centers in the last frame by an offset that you choose. If it does, it's probably the same face so just don't count it.
Visualization:
Hope it will work fine for you!