项目背景
现在一固定场所有相机处于开启工作状态,在该场所有大量的人员的进出活动,每当人员的进出时候相机都会有较长时间持续性不断地拍到进出人员的人脸部分。人员都是逐一进出的。现在需要对该场所的进出人流量进行统计。
需求分析
由于设备是一直开始的状态,所以摄像头也会是一直处于启动的状态;那么这里需要我们完成一个人脸检测的model进行检测人脸(因为需要完成的任务是人流量统计工作)。
在这里我们的重点在人流量的统计任务,对于人脸检测任务大家可以详细参考巧借haarcascade系列frontalface_alt2完成人脸检测。我将稍微动下里面的检测代码进行人脸检测,后续的人流量
逻辑分析
在这里我将分为功能模块和业务模块进行分析。其中的功能逻辑是指对人脸检测的功能;业务逻辑部分是指对人流量统计。在逻辑分析中我着重讲述人流量统计部分的业务逻辑。
人脸检测功能
由于在需求分析中对人脸检测部分提供量参考部分。这里对函数的return 新加一个逻辑:当检测到人类的时候(len(faces)>0)对 COUNT 赋值:1 ,其它情况COUNT赋值为:0。其余的函数return 值保持不变。
def format_image(image): if len(image.shape) > 2 and image.shape[2] == 3: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) CASC_PATH = './include/FindFace.xml' # cascade_classifier = cv2.CascadeClassifier(CASC_PATH) faces = cascade_classifier.detectMultiScale(image, scaleFactor=1.1, minNeighbors=5) # 如果图片中没有检测到人脸,则返回None if not len(faces) > 0: return None, None, 0 max_are_face = faces[0] for face in faces: # 在所有人脸中选一张最大的脸 if face[2] * face[3] > max_are_face[2] * max_are_face[3]: max_are_face = face face_coor = max_are_face image = image[face_coor[1]:(face_coor[1] + face_coor[2]), face_coor[0]:(face_coor[0] + face_coor[3])] if len(faces) > 0: COUNT = 1 else:COUNT = 0 return image, face_coor, COUNT 复制代码
人流量统计功能
进行统计人流量的过程中,相机是一直处于在获取实时画面的那么我们的人脸检测函数同样是一直在执行的,这里需要解决的一个问题就是:“每当人员的进出时候相机都会有较长时间持续性不断地拍到进出人员的人脸部分” 相机能够长时间持续性不断地拍到人脸,这里既确保了人脸检测的精度(确保画面部分满足了人脸检测部分),但是我们在业务逻辑这里就有一个问题需要考虑的了,由于被检测的人的人脸是一直处于被检测的状态,但是我们的检测函数又是一直处于运行状态,那么我们就需要对一段检测到人脸的过程只对人脸总数+1操作 即可。
设计的时候需要个给定一个状态值它的初始状态赋值为0同时对人脸总数初始状态也为0,当没有检测到人脸的时候状态值保持为0,当检测到人脸的时候对人脸总数+1,此时需要更改状态值了,更改状态后下一次的检测结果为1时(即:检测到了人脸)就会与状态值相同,从而不会对一段视频中的人脸检测过程中一直对人脸总数+1了。
示例检验思路demo
RawNum = 0 # 初始状态值&状态值 LabNum = 0 # 人脸总数 while True: a = int(input("请输入检测到的值:")) if RawNum != a: RawNum = a if a == 1: LabNum += 1 else: RawNum = a print("此时的检测到的人脸总数", LabNum) 复制代码
总结
在这里我们初步完成了人脸检测部分与人流量统计部分,其中难免有疏忽的部分,还望大家多多指正。
完整业务逻辑代码
if __name__ == "__main__": capture = cv2.VideoCapture(0) fps = 0.0 RawData = 0 lab_num = 0 while 1: t1 = time.time() # 读取某一帧 ref, frame = capture.read() # 格式转变,BGRtoRGB frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 进行检测 (p_image, face_coor, COUNT) = format_image(frame) if COUNT != RawData: RawData = COUNT if COUNT == 1: lab_num += 1 else: RawData = COUNT if face_coor is not None: # 获取人脸的坐标,并用矩形框出 [x, y, w, h] = face_coor cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 1) frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) fps = (fps + (1. / (time.time() - t1))) / 2 cv2.putText(frame, "fps= %.2f" % fps, (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.putText(frame, "face_num= %.1f" % lab_num, (0, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow("video", frame) c = cv2.waitKey(1) & 0xff if c == 27: capture.release() break capture.release() cv2.destroyAllWindows()
示例视频