在上一篇博客中已经得出视频帧的光流信息,这里接着根据已有数据做人群异常检测。
实验思路:
首先跟踪所有的角点,计算出它们的运动速度。接着对所有角点的速度求平均得出人群的平均速度。然后监测是否存在某个角点运动速度明显高于人群的平均速度。设置一个合适的阈值,当满足条件时,判断为异常。
实验代码:
首先封装Point类和距离计算方法,这里采用欧氏距离。
# 定义点的函数
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def getx(self):
return self.x
def gety(self):
return self.y
# 定义直线函数
class Getlen:
def __init__(self, p1, p2):
self.x = p1.getx() - p2.getx()
self.y = p1.gety() - p2.gety()
# 用math.sqrt()求平方根
self.len = math.sqrt((self.x**2) + (self.y**2))
# 定义得到直线长度的函数
def getlen(self):
return self.len
定义人群平均速度、单点运动速度和求最快单点三个方法。其中单点运动速度根据前10个状态做平均求得。
# 计算人群平均速度
def calAverageSpeed(arr, f_i):
idx = 0
dist = 0
for i in range(len(arr)):
for j in range(f_i):
dist = dist + arr[i][j]
idx = idx + 1
avgSpeed = dist / idx
return avgSpeed
# 计算单点速度
def calSingleSpeed(arr, idx, f_i):
if f_i < 10:
return -1
dist = 0
for i in range(10):
dist = dist + arr[idx][f_i - 10 + i]
speed = dist / 10
return speed
# 得出速度最快的点
def calFastestPoint(arr):
idx = -1
maxSpeed = 0;
for i in range(len(arr)):
if arr[i] > maxSpeed:
maxSpeed = arr[i]
idx = i
return idx, maxSpeed
构建一个蒙版,用来绘制异常检测框。这里阈值设置为2(单点速度-人群平均速度 > 2)。
# 创建一个蒙版用来画异常检测框
mask_ab = np.zeros_like(first_rgbframe)
# 存储跟踪点的运动速度
v_p = np.zeros((len(p0), 205))
v_s = np.zeros(len(p0))
crowd_speed = 0
v_i = 1
for frame_i in frames:
# N lines of code are omitted
# 判定速度最快的点为异常点,并以矩形框标记
crowd_speed = calAverageSpeed(v_p, v_i + 1)
fastest_point, fastest_speed = calFastestPoint(v_s)
imgAC = rgbframe
if v_i > 10 and fastest_point < len(good_new) and fastest_point >= 0 and\
fastest_speed-crowd_speed > 2:
x, y = good_new[fastest_point]; x = int(x); y = int(y)
mask_ab = cv2.rectangle(mask_ab, (x - 7, y - 10), (x + 7, y + 10), (0, 0, 255), 2)
imgAC = cv2.add(rgbframe, mask_ab)
mask_ab = np.zeros_like(first_rgbframe)
cv2.imwrite(frameAC_path + frame_i, imgAC)
# N lines of code are omitted
实验结果
场景一(UCSDped1/Train/Train007):
场景二(UCSDped1/Test/Test014):
扫描二维码关注公众号,回复:
10051282 查看本文章
两个片段中的单车都被正确标记,但是标记时间过度延迟。除此之外还存在较多的误判。
后续工作
改进和优化异常检测策略,提高异常检测的准确率和实时性。