小言_互联网的博客

opencv实现视频里人数统计

377人阅读  评论(0)

小编有个群193369905,相关毕设也可找群主,里面分享的均是机器视觉的资料。基于图像的人数统计属于模式识别问题,可应用于安防领域。
先放个最近的人数教室人头统计图
前两张效果图为caffe训练完成

看到最近好多留言大多数都是小白学生,一直在留言,所以我又继续更新了一下

传统的方法包括:1)视频捕获;2)目标提取(背景建模、前景分析)——常见方法有高斯背景建模、帧差法、三帧差法等;3)目标识别(模式识别、特征点分析),如人脸识别,头肩部识别等,OpenCV里可以使用Hear特征、级联分类器来进行特征检测;4)目标跟踪——基本方法有直方图特征匹配和运动目标连续性匹配,opencv里可以使用CamShift算法直接对彩色图像进行分析;5)轨迹分析——根据目标的运动轨迹计算目标目标运动方向和位移,判断目标是进入还是离开指定区域,从而对目标进行数目统计。
前段时间我接到一个项目,需要统计公交车的人数,于是我就利用python-opencv对人头统计了一下,然后利用轨迹分析计算目标运动的方向和位移,来判断目标是上公交还是下公交。
下面我先贴出如何利用python-opencv来统计一下图片中的人脸数目吧,人脸检测注释请参考我的上一篇博客:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import cv2
import numpy as np
face_cascade=cv2.CascadeClassifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml")
eye_cascade=cv2.CascadeClassifier("/usr/share/opencv/haarcascades/haarcascade_eye.xml")
i = cv2.imread('1.jpg')
print i.shape
gray=cv2.cvtColor(i,cv2.COLOR_BGR2GRAY)
faces=face_cascade.detectMultiScale(gray,1.3,5)
l=len(faces)
print l
for (x,y,w,h) in faces:
    cv2.rectangle(i,(x,y),(x+w,y+h),(255,0,0),2)
    cv2.putText(i,'face',(w/2+x,y-h/5),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = i[y:y+h, x:x+w]
    eyes = eye_cascade.detectMultiScale(roi_gray)
	cv2.putText(i,"face count",(20,20),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
	cv2.putText(i,str(l),(230,20),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)	
#cv2.putText(i,"eyes count",(20,60),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
	print i.shape	#cv2.putText(i,str(r),(230,60),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
cv2.imshow("img",i)
cv2.waitKey(0) 

我们看一下原图

处理完之后的效果:

从图片中看到,检测效果有点不准,我们只需要数框就可以得到人脸的个数了,并用上篇博客中降到的putText函数将人数在图片中打印出来。
接下来,我们可以检测视频中的人脸数目,然后进行统计,同样也可以自己训练分类器,实现人头检测然后统计,我在这只给出系统已经训练好的分类器。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import cv2
import numpy as np
face_cascade=cv2.CascadeClassifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml")
eye_cascade=cv2.CascadeClassifier("/usr/share/opencv/haarcascades/haarcascade_eye.xml")
cap=cv2.VideoCapture('test.avi')
while True:
    ret,frame=cap.read()
    i=frame
       # print i.shape
    gray=cv2.cvtColor(i,cv2.COLOR_BGR2GRAY)
    faces=face_cascade.detectMultiScale(gray,1.3,5)
    l=len(faces)
    print l
    for (x,y,w,h) in faces:
    	cv2.rectangle(i,(x,y),(x+w,y+h),(255,0,0),2)
	    cv2.putText(i,'face',(w/2+x,y-h/5),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = i[y:y+h, x:x+w]
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
	        cv2.putText(i,"face count",(20,20),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
	        cv2.putText(i,str(l),(230,20),cv2.FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1)
	cv2.imshow("rstp",i)
	if cv2.waitKey(1) & 0xFF == ord('q'):
	    exit(0)

copy以上代码就可以检测视频中人脸的个数了,大家可自行玩开,由于上传匆忙,代码可能出现错行,大家如果需要完整代码,可留下邮箱,小编将完整项目代码发入邮箱,有错欢迎大家指正。
更新于2021年3月7日

以上是非常简单的版本人脸检测统计,现在opencv4版本基本都是深度学习版本了,精度更高,也更加鲁棒,我们看下效果:

接下来我放下代码;

import numpy as np
import argparse
import cv2
import time
 
input_shape = (80, 80)
mean = (104.0, 177.0, 123.0)
 
def get_args():
    ap = argparse.ArgumentParser()
    ap.add_argument("--prototxt", default="face_detector/deploy.prototxt")
    ap.add_argument("--model", default="face_detector/res10_300x300_ssd_iter_140000.caffemodel")
    ap.add_argument("--confidence", default=0.5)
    args = ap.parse_args()
    return args
 
if __name__=="__main__":
    args = get_args()
    net = cv2.dnn.readNetFromCaffe(args.prototxt, args.model)
    cap = cv2.VideoCapture(0)
    while True:
        ret, image = cap.read()
        if not ret:
            brack
        (h, w) = image.shape[:2]
        blob = cv2.dnn.blobFromImage(cv2.resize(image, input_shape), 1.0,input_shape, mean)
        net.setInput(blob)
        start = time.time()
        detections = net.forward()
        end = time.time()
        cost = "%0.2fms" %((end-start)*1000)
        detections = detections.reshape(-1, 7)
        for i in range(0, detections.shape[0]):
            confidence = detections[i, 2]
            if confidence > args.confidence:
                box = detections[i, 3:7] * np.array([w, h, w, h])
                (startX, startY, endX, endY) = box.astype("int")
                text = "{:.2f} ".format(confidence * 100)+cost
                y = startY - 10 if startY - 10 > 10 else startY + 10
                cv2.rectangle(image, (startX, startY), (endX, endY),
                    (255, 0, 0), 2)
                cv2.putText(image, text, (startX, y), 1, 1, (0, 0, 255), 2)
        cv2.imshow("img", image)
        cv2.waitKey(1)

所需要的model文件跟protxt的地址为:
例如我的opencv路径是:D:\Program Files\OpenCV\opencv\sources\samples\dnn\face_detector,打开之后:里面有个download_weights.py,使用pycharm执行下就可以自动下载模型(2种模型)了。或者直接点击下方的链接直接下载:

https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodel


转载:https://blog.csdn.net/xiao__run/article/details/76513275
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场