如何通过人脸检测获得准确的人数?

时间:2018-03-19 18:18:31

标签: python opencv

我正在使用opencv来获取视频流中的总人数。问题是我的代码只捕获帧中的人数而不考虑流中的所有帧。我想过提取从视频或网络摄像头检测到的所有面部,然后比较它们。我的问题是如何通过比较提取的面来获得确切的人数?或者还有其他方法可以获得总数吗?

这是检测面部并提供性别和计数的功能(但仅适用于该帧)

def start_webcam(model_gender, window_size, window_name='live', update_time=50):
cv2.namedWindow(window_name, WINDOW_NORMAL)
if window_size:
    width, height = window_size
    cv2.resizeWindow(window_name, width, height)

video_feed = cv2.VideoCapture(0)
video_feed.set(3, width)
video_feed.set(4, height)
read_value, webcam_image = video_feed.read()


delay = 0
init = True
while read_value:
    read_value, webcam_image = video_feed.read()
    webcam_image=cv2.flip(webcam_image,1,0)
    faces = face_cascade.detectMultiScale(webcam_image)
    for normalized_face, (x, y, w, h) in find_faces(webcam_image):
      if init or delay == 0:
        init = False
        gender_prediction = model_gender.predict(normalized_face)
      if (gender_prediction[0] == 0):
          cv2.rectangle(webcam_image, (x,y), (x+w, y+h), (0,0,255), 2)
          cv2.putText(webcam_image, 'female', (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
      else:
          cv2.rectangle(webcam_image, (x,y), (x+w, y+h), (255,0,0), 2)
          cv2.putText(webcam_image, 'male', (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255,0,0), 2)

    delay += 1
    delay %= 20

    cv2.putText(webcam_image, "Number of faces detected: " + str(len(faces)), (0,webcam_image.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.7,  (255,255,255), 1)
    cv2.imshow(window_name, webcam_image)
    key = cv2.waitKey(update_time)
    if key == ESC:
        break

cv2.destroyWindow(window_name)

2 个答案:

答案 0 :(得分:2)

如果我理解你的问题,简而言之,你的问题可分为以下几个部分:

0 - 检测:每帧检测零个或多个面部。该步骤的输出是一系列“事件”。每个事件都是一个面部和图像中检测到面部的区域的坐标:

evts = {{face0, (x0,y0,w0,h0)}, {face1, (x1,y1,w1,h1)}, ..., {faceN, (xN,yN,wN,hN)}} 

对于N + 1个检测到的面孔。

1 - 识别:此步骤的目标是为上一步骤中检测到的每个事件(面部/区域)提供ID。所以,对于evts中的每个面孔或: I.面部是“新面孔”,因此,生成新ID并将其分配给面部 II。面部是在前一帧中检测到的相同面部,因此您应为该面部分配先前相同的ID。此步骤的输出是已分配ID的集合:

ids = {id0, id1, id2, ..., idM}

2 - 计数:重复步骤1和2直到最后一帧。 ids集合的大小是视频流中不同面孔的数量

真正的问题

真正的问题是:如何确定第X帧中的事件(在这种情况下是一个脸)是否是帧Y中的“相同”脸?是的,这是关键问题。在您的情况下,您应该使用多种方法:

  • 执行脸部识别(脸部识别与脸部检测不同)。幸运的是,去年这个领域有很多改进,您可以或多或少地在代码中轻松使用openface或类似的API来满足您的需求。不要浪费你的时间来尝试Viola's based algorithms进行人脸识别(它们是在2001年推出的,而且可能对今天的实际需求不那么准确)。
  • 考虑空间和时间局部性原则,并最大化在邻域中为连续帧找到相同面部的合理性

给出关于姿势改变,光照和遮挡的问题,使用先前检测到的面部的位置来识别当前可以比面部识别算法更稳健。这取决于您的视频和场景。

为此问题实施强大的解决方案有几个操作问题:

  • 不同姿势的相同面孔
  • 面对不同规模
  • 遮挡(总是有问题)
  • 实时要求

所有与CV相关的挑战。所以,准备好处理误报率/负面率。

提示:

  • 针对多个不同的视频试用您的解决方案,以避免过度拟合。
  • 如果在视频中脸部正在移动,Kalman Estimator可能会有用。

我写了这么多。希望我真的理解你的问题。

答案 1 :(得分:0)

尝试对每个帧的所有面进行散列处理。然后将每个哈希存储在一个集合中并获取其大小以查找视频源中的面数。