首页 > 编程语言 >(全网最详细的可运行的人流统计程序)基于OpenCV的实时视频处理系统

(全网最详细的可运行的人流统计程序)基于OpenCV的实时视频处理系统

时间:2024-08-07 14:54:22浏览次数:19  
标签:gray 检测 frame 全网 cv2 人流 OpenCV 人脸 time

OpenCV人脸检测

OpenCV提供了多种人脸检测方法,包括基于Haar级联的传统方法和基于深度学习的现代方法。Haar级联是一种经典的机器学习算法,适用于实时应用,因为它可以快速处理图像。

  1. 级联(Cascade)结构

    • Cascade分类器由多个简单的分类器组成,这些分类器按照一定的顺序级联起来。
    • 每个分类器都是一个弱分类器,只能对图像中的一部分区域进行简单的判断。
    • 当图像或图像中的某个区域通过所有分类器的判断时,才认为它是一个目标。

深度学习方法,如MTCNN(Multi-Task Cascade Convolutional Networks)和YOLOv3,提供了更高的检测准确度。

本文使用的是Haar特征的Cascade分类器(haarcascade_frontalface_default.xml)进行人脸检测。这是一种基于机器学习的方法,可以快速检测图像中的人脸。

detectMultiScale方法用于在灰度图像上检测多尺度的人脸,返回检测到的人脸矩形框坐标。人流

# 加载人脸检测器(这里使用的是Haar特征的Cascade分类器)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

运动检测

通过比较连续两帧图像的灰度差异来检测运动。这通过计算两帧图像之间的绝对差(cv2.absdiff)实现,对差异图像进行阈值处理(cv2.threshold),将差异较大的区域(即运动区域)转换为白色,其他区域为黑色。使用形态学操作(如膨胀cv2.dilate)来增强运动区域的特征,以便更容易地通过轮廓检测找到运动物体。cv2.findContours方法用于检测并提取图像中的轮廓,这些轮廓对应于运动物体。

    # 如果没有背景图像就将当前帧当作背景图片
    if pre_frame is None:
        pre_frame = gray_pic
    else:
        # absdiff把两幅图的差的绝对值输出到另一幅图上面来
        img_delta = cv2.absdiff(pre_frame, gray_pic)
        # threshold阈值函数(原图像应该是灰度图,对像素值进行分类的阈值,当像素值高于(有时是小于)阈值时应该被赋予的新的像素值,阈值方法)
        thresh = cv2.threshold(img_delta, 30, 255, cv2.THRESH_BINARY)[1]
        # 用一下腐蚀与膨胀
        thresh = cv2.dilate(thresh, None, iterations=2)
        # findContours检测物体轮廓(寻找轮廓的图像,轮廓的检索模式,轮廓的近似办法)
        contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

人流监测

代码能根据人脸检测结果进行相应的处理,若检测到人脸则记录,若当前未检测到人脸但之前检测到过,则认为有人脸移出,并进行计数和显示提示信息。总的来说,可以实现通过摄像头进行实时视频处理,包括运动检测和人脸检测,并对人脸的进入和移出进行计数和提示。

该代码可实现以下功能:

  • 结合人脸检测和运动检测结果,当检测到人脸且之前未检测到人脸时,认为有人进入。
  • 通过维护一个计数器J来跟踪进入的人数。
  • 如果之前检测到人脸但当前未检测到,且之前进入的人数大于0,则认为有人离开,但在这个实现中只统计了进入的人数。
    # 保存图像
                    TI = time.strftime('%Y-%m-%d', time.localtime(time.time()))
                    cv2.imwrite("D:/aopencv/" + TI + '.jpg', frame)
    
                    # 读取刚才保存的图像进行人脸检测
                    saved_image = cv2.imread("D:/aopencv/" + TI + '.jpg')
                    gray_saved = cv2.cvtColor(saved_image, cv2.COLOR_BGR2GRAY)
                    faces = face_cascade.detectMultiScale(gray_saved, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    
                    # 检测到人脸
                    if len(faces) > 0:
                        print("检测到人脸!")
                        last_detected_faces +=1
                    else:
                        # 如果上次检测到的人脸数量大于0,且当前没有检测到人脸,则认为有人脸移出
                        if last_detected_faces > 0:
                            cv2.putText(frame, f"enter  {J}  people", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
                            J += 1
                            print(f"进入{J}个人")
                            last_detected_faces = 0  # 重置检测到的人脸数量

    完整代码,该代码可完美运行:

  • import cv2
    import time
    
    # 加载人脸检测器(这里使用的是Haar特征的Cascade分类器)
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    
    # 定义摄像头对象,其参数0表示第一个摄像头
    camera = cv2.VideoCapture(0)
    # 测试用,查看视频size
    width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
    size = width, height
    # 打印一下分辨率
    print(repr(size))
    # 设置一下帧数和前背景
    fps = 5
    pre_frame = None
    
    J=0
    C=0
    last_detected_faces = 0
    
    while (1):
        start = time.time()
        # 读取视频流
        ret, frame = camera.read()
        # 转灰度图
        gray_pic = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
        if not ret:
            print("打开摄像头失败")
            break
        end = time.time()
    
        cv2.imshow("capture", frame)
    
        # 运动检测部分
        seconds = end - start
        if seconds < 1.0 / fps:
            time.sleep(1.0 / fps - seconds)
        gray_pic = cv2.resize(gray_pic, (480, 480))
        # 用高斯滤波进行模糊处理
        gray_pic = cv2.GaussianBlur(gray_pic, (21, 21), 0)
    
        # 如果没有背景图像就将当前帧当作背景图片
        if pre_frame is None:
            pre_frame = gray_pic
        else:
            # absdiff把两幅图的差的绝对值输出到另一幅图上面来
            img_delta = cv2.absdiff(pre_frame, gray_pic)
            # threshold阈值函数(原图像应该是灰度图,对像素值进行分类的阈值,当像素值高于(有时是小于)阈值时应该被赋予的新的像素值,阈值方法)
            thresh = cv2.threshold(img_delta, 30, 255, cv2.THRESH_BINARY)[1]
            # 用一下腐蚀与膨胀
            thresh = cv2.dilate(thresh, None, iterations=2)
            # findContours检测物体轮廓(寻找轮廓的图像,轮廓的检索模式,轮廓的近似办法)
            contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
            for c in contours:
                # 设置敏感度
                # contourArea计算轮廓面积
                if cv2.contourArea(c) < 1000:
                    continue
                else:
                    # 保存图像
                    TI = time.strftime('%Y-%m-%d', time.localtime(time.time()))
                    cv2.imwrite("D:/aopencv/" + TI + '.jpg', frame)
    
                    # 读取刚才保存的图像进行人脸检测
                    saved_image = cv2.imread("D:/aopencv/" + TI + '.jpg')
                    gray_saved = cv2.cvtColor(saved_image, cv2.COLOR_BGR2GRAY)
                    faces = face_cascade.detectMultiScale(gray_saved, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    
                    # 检测到人脸
                    if len(faces) > 0:
                        print("检测到人脸!")
                        last_detected_faces +=1
                    else:
                        # 如果上次检测到的人脸数量大于0,且当前没有检测到人脸,则认为有人脸移出
                        if last_detected_faces > 0:
                            cv2.putText(frame, f"enter  {J}  people", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
                            J += 1
                            print(f"进入{J}个人")
                            last_detected_faces = 0  # 重置检测到的人脸数量
    
                    cv2.imshow("capture", frame)
            pre_frame = gray_pic
        cv2.putText(frame, f"enter  {J}  people", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        cv2.imshow("capture", frame)
    
    
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # release()释放摄像头
    camera.release()
    # destroyAllWindows()关闭所有图像窗口
    cv2.destroyAllWindows()
    

标签:gray,检测,frame,全网,cv2,人流,OpenCV,人脸,time
From: https://blog.csdn.net/2301_77509548/article/details/140991542

相关文章

  • 深入解析:人工智能视觉利器OpenCV的技术奥秘
    人工智能视觉利器OpenCV的技术奥秘1.图像处理基础1.1数字图像基础知识1.1.1像素1.1.2色彩空间1.2图像处理中的常见任务1.2.1图像分割1.2.2图像识别1.2.3图像检测1.3颜色检测与图像处理的结合2.OpenCV简介2.1OpenCV的历史和发展早期发展持续演进开源社区的......
  • 图像识别与处理之Opencv——Mat_类与Mat 类的内存管理
    Mat_类Mat_类是对Mat类的一个包装,其定义如下点击查看代码template<typename_Tp>classMat_:publicMat{public://只定义了几个方法//没有定义新的属性};这是一个非常轻量级的包装,既然已经有Mat类,为何还要定义一个Mat_类?下面我们看这段代码:点击查看代码Ma......
  • python项目学习 mediapipe手势识别 opencv可视化显示
    importcv2importmediapipeimportnumpydefget_angle(vector1,vector2):#角度计算angle=numpy.dot(vector1,vector2)/(numpy.sqrt(numpy.sum(vector1*vector1))*numpy.sqrt(numpy.sum(vector2*vector2)))#cos(angle)=向量的点乘/向量的模angle=nump......
  • SciTech-BigDataAI-ImageProcessing-OpenCV-How to Use Background Subtraction Metho
    https://docs.opencv.org/3.4/d1/dc5/tutorial_background_subtraction.htmlHowtoUseBackgroundSubtractionMethodsNextTutorial:MeanshiftandCamshiftBackgroundsubtraction(BS)isacommonandwidelyusedtechniqueforgeneratingaforegroundmask(na......
  • opencv 边缘检测-拉普拉斯算子
    索贝尔算子是模拟一阶求导,导数越大的地方说明变换越剧烈,越有可能是边缘.那如果继续对f’(t)求导呢?可以发现"边缘处"的二阶导数=0.我们可以利用这一特性去寻找图像的边缘.注意有一个问题,二阶求导为0的位置也可能是无意义的位置拉普拉斯算子推导过程以x方向求解......
  • SciTech-BigDataAI-ImageProcessing-OpenCV-OpenCV modules
    OpenCVmoduleshttps://docs.opencv.org/3.4/IntroductionOpenCVTutorialsOpenCV-PythonTutorialsOpenCV.jsTutorialsTutorialsforcontribmodulesFrequentlyAskedQuestionsBibliographyMainmodules:core.Corefunctionalityimgproc.ImageProcessingim......
  • vue2 - 最新详细实现高德地图绘制动态热力图详细教程,在某区域或城市地图上做“热力图
    效果图在vue2、nuxt2项目开发中,详解引入使用高德地图接收热力图数据并渲染“热力图”效果功能,在地图上的某个区域或某个城市(可多个)、省份等自由绘制对应的热力图层,各城市地区同时加载渲染热力流量区域用以对比,根据不同的颜色代表人口密度、客流量、旅游人数、交通流量......
  • SciTech-BigDataAI-ImageProcessing-OpenCV-Splitting and Merging Channels with Ope
    Links:https://pyimagesearch.com/2021/01/23/splitting-and-merging-channels-with-opencv/OpenCVOfficial:https://docs.opencv.org/3.4/d3/df2/tutorial_py_basic_ops.htmlSplittingandMergingImageChannelsSometimesyouwillneedtoworkseparatelyonth......
  • 【全网首发】2024华数杯数学建模ABC题选题分析+解题思路代码+成品论文更新
    建议选哪道题?A题特点:数理分析题目此题难度较大与国赛难度较为贴近B题特点B题以运筹学/网络科学,图论、优化问题为主,涉及到的概念多,对基础要求较高,不建议优先选择。常用MATLAB函数例如toposort(有向无环图的拓扑顺序)、isomorphism(计算两个图之间的同构)、centrality(衡量节点......
  • MySQL的索引详细介绍(全网最详细!!!)
    目录1.什么是索引1.1索引的数据结构1.1.1Hash表1.1.2二叉查找树1.1.3平衡二叉树1.1.4B树1.1.5B+树2.索引的优缺点3.索引的使用场景4.索引的分类4.1主键索引4.2唯一索引4.3单值索引(单列索引)4.4复合索引(组合索引)4.5普通索引4.6全文索引4.7空间索引4.8......