做一个特定场景的视频监控,当有人进入指定区域时报警。
1、 实现检测人
2、 实现设置任意指定检测区域
3、 报警
硬件:树莓派+配套的CSI摄像头
软件:python3+OpenCV
HOG+SVM+NMS实现行人检测。
HOG (方向梯度直方图)是应用在计算机视觉和图像处理领域,用于目标检测的特征描述器。它主要是利用了图片中特征点的梯度信息作为特征值,可以用来做行人、一些物品的检测。
SVM(支持向量机)是常见的一种判别方法。在机器学习领域,是一个有监督的学习模型,通常用来进行模式识别、分类以及回归分析, 在行人检测中可以用作区分行人和非行人的分类器。
HOG 特征结合 SVM 分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。
对ROI区域进行检测,检测范围框为蓝色,对比框为绿色,对整张图片进行展示。当人物运动、正面、直立时检测效果较好。
import cv2
import numpy as np
from imutils.object_detection import non_max_suppression
import imutils
定义HOG对象,采用默认参数。设置SVM分类器,用默认分类器。设置视频获取来源为摄像头。
#初始化方向梯度直方图描述子
hog = cv2.HOGDescriptor()
#设置支持向量机使得它成为一个预先训练好了的行人检测器
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
#读取摄像头视频
cap = cv2.VideoCapture(0)
先用滑动窗口选取图片上的某一块区域,利用opencv提取该区域的hog特征,将特征向量输入svm中,利用svm进行分类,判别是否是待检测目标。
while True:
# 按帧读取视频
ret, img = cap.read()
# 将每一帧图像ROI区域抠出来
#img_roi = img1[img_roi_y:(img_roi_y + img_roi_height), img_roi_x:(img_roi_x + img_roi_width)]
roi = img[50:450, 350:600]
# 通过调用detectMultiScale的hog描述子方法,对图像中的行人进行检测。
(rects, weights) = hog.detectMultiScale(roi, winStride=(4, 4), padding=(8, 8), scale=1.05)
# 应用非极大值抑制,通过设置一个阈值来抑制重叠的框。
rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)
# 绘制红色人体矩形框
for (x, y, w, h) in pick:
cv2.rectangle(roi, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 绘制绿色对比框
cv2.rectangle(img, (50, 50), (600, 450), (0, 255, 0), 2)
# 绘制蓝色危险区域框
cv2.rectangle(img, (350, 50), (600, 450), (255, 0, 0), 2)
#打印检测到的目标个数
print("检测到进入危险区域行人个数为{}".format(len(pick)))
# 展示每一帧图像
cv2.imshow("HOG+SVM+NMS", img)
# 按esc键退出循环
if cv2.waitKey(1) & 0xff == 27:
break
停止捕获视频并关闭显示窗口。
#释放资源
cap.release()
cv2.destroyAllWindows()
1、 利用opencv自带的img[50:450, 350:600]函数可以方便的设置矩形检测区域,但是opencv没有提供设置圆形检测区域的函数,或许因此见到的矩形检测区域较多,今天在就业大楼进门看见一个体温检测的东西,屏幕中间显示的就是一个矩形的检测区域。
2、 用HOG+SVM的检测方式会在同一个目标上重复检测,可以采用NMS的方法将非极大值边框抑制,只留下一个边框。
3、 边框无法恰好将人框住,部分原因可能是检测速度慢,如果是对单张图片进行检测,检测效果会有肉眼可见的提高。
4、视频播放时会有一定的卡顿,具体原因暂时不清楚是由于树莓派性能限制还是算法原因。