python使用opencv实现识别指定区域的行人

1、案例介绍

        案例实现对视频中的行人进行实时检测,并可在视频画面通过鼠标绘制矩形区域,行人经过区域内后,程序会进行判断行人已进入该区域,行人检测框颜色将变为蓝色。该程序主要使用python的opencv模块实现,实现流程:首先利用Haar分类器实现行人检测功能,其次利用opencv鼠标事件框选矩形区域,计算行人中心点,判断如果中心点在区域内后,就对行人检测框进行颜色的转变。

 

2、案例实现

  • 实现行人检测,加载Haar的人体识别器模型,读取视频流每一帧,使用矩形绘制方法rectangle绘制出行人。
import cv2
if __name__ == '__main__':
    # 加载Haar级联分类器模型
    cascade_classifier = cv2.CascadeClassifier('./model/haarcascade_fullbody.xml')

    # 加载视频
    video_capture = cv2.VideoCapture('./data/test.mp4')
    cv2.namedWindow('image')
    while True:
        # 获取视频的一帧
        ret, frame = video_capture.read()

        # 转换为灰度图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 检测人体
        bodies = cascade_classifier.detectMultiScale(gray, 1.1, 4)

        # 在图像上绘制人体框并显示
        for (x, y, w, h) in bodies:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

        cv2.imshow('image', frame)

        # 按'q'键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 释放资源
    video_capture.release()
    cv2.destroyAllWindows()
  • 实现鼠标事件绘制矩形,通过opencv的事件监听器,获取矩形对角线的两点并通过rectangle方法将矩形绘制出来。
import cv2
import numpy as np

# 鼠标事件
def OnMouseAction(event, x, y, flags, param):
    global position1, position2
    if event == cv2.EVENT_LBUTTONDOWN:  # 按下左键
        position1 = (x, y)
        position2 = None

    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:  # 按住左键拖曳不放开
        position2 = (x, y)

    elif event == cv2.EVENT_LBUTTONUP:  # 放开左键q
        position2 = (x, y)

if __name__ == '__main__':
    # 加载Haar级联分类器模型
    cascade_classifier = cv2.CascadeClassifier('./model/haarcascade_fullbody.xml')

    # 加载视频
    video_capture = cv2.VideoCapture('./data/test.mp4')
    cv2.namedWindow('image')
    cv2.setMouseCallback('image', OnMouseAction)
    position1 = None
    position2 = None
    x0, yo = None, None
    cnt = None
    while True:
        # 获取视频的一帧
        ret, frame = video_capture.read()

        # 转换为灰度图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 检测人体
        bodies = cascade_classifier.detectMultiScale(gray, 1.1, 4)

        # 在图像上绘制人体框并显示
        for (x, y, w, h) in bodies:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

        if ret:
            if position1 != None and position2 != None:
                cv2.rectangle(frame, position1, position2, (0, 0, 255), 1, 4)

        cv2.imshow('image', frame)

        # 按'q'键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 释放资源
    video_capture.release()
    cv2.destroyAllWindows()
  • 计算行人中心点并判断中心点是否在矩形区域内,这里设置到我们初中学习的一个数字知识点,中心点的计算公式:x0,y0 = (x1+x2)/2,(y1+y2)/2,其次通过pointPolygonTest方法判断中心点是否在指定区域内。
import cv2
import numpy as np

# 鼠标事件
def OnMouseAction(event, x, y, flags, param):
    global position1, position2
    if event == cv2.EVENT_LBUTTONDOWN:  # 按下左键
        position1 = (x, y)
        position2 = None

    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:  # 按住左键拖曳不放开
        position2 = (x, y)

    elif event == cv2.EVENT_LBUTTONUP:  # 放开左键q
        position2 = (x, y)

if __name__ == '__main__':
    # 加载Haar级联分类器模型
    cascade_classifier = cv2.CascadeClassifier('./model/haarcascade_fullbody.xml')

    # 加载视频
    video_capture = cv2.VideoCapture('./data/test.mp4')
    cv2.namedWindow('image')
    cv2.setMouseCallback('image', OnMouseAction)
    position1 = None
    position2 = None
    x0, yo = None, None
    cnt = None
    while True:
        # 获取视频的一帧
        ret, frame = video_capture.read()

        # 转换为灰度图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 检测人体
        bodies = cascade_classifier.detectMultiScale(gray, 1.1, 4)

        # 在图像上绘制人体框并显示
        for (x, y, w, h) in bodies:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

        if ret:
            if position1 != None and position2 != None:
               
                cv2.rectangle(frame, position1, position2, (0, 0, 255), 1, 4)
                for (x, y, w, h) in bodies:
                    x0, yo = int((x + x + w) / 2), int((y + y + h) / 2)
                    if cv2.pointPolygonTest(cnt, (x0, yo), False) >= 0:
                        cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

        cv2.imshow('image', frame)

        # 按'q'键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 释放资源
    video_capture.release()
    cv2.destroyAllWindows()

3、项目结构

 4、总结

        上述只是做了一个基础案例,该案例依然存在以下几点小的问题,第一点问题就是效率问题,针对视频流的处理是非常消耗内存的如果电脑是cpu的话,所以针对这个问题我查阅了一下资料,使用numba可以提升对视频流处理速度。第二点问题是行人识别准确度问题,当前使用Haar的识别器效果还是不好的,我们可以使用yolov5或者MobileNet-SSD模型对行人进行识别效果会更佳,第三个问题是绘制区域的优化,目前是默认矩形区域,实际形形况中可能是非矩形的多边形区域,所以针对这个需要进一步的优化。以上就是今天的案例分享,如果对大家有帮助可以点个赞奥~♥♥

百度网盘 请输入提取码 

猜你喜欢

转载自blog.csdn.net/m0_43432638/article/details/130031880
今日推荐