vibe是一个又简单又牛逼的算法,没有什么数学公式,就只有三步
1.初始化背景模型,总共有20个背景模型样本,每个样本中的每个点由其八邻域初始化(论文里面没有用到自己这个像素点,看了其他的改进,有用自己的,这个没必要较真,大家都是试出来的,不一定适合每个场景)。
2.前景背景判定 新来的每一帧与背景模型做比较,如果新的帧的点与背景模型中样本的点的像素值大小不超过20(20是个经验值
在网上搜了一下,实现的版本,emm,速度真的是太慢了,慢的想要哭,but自己要用啊,这个速度真的是不能接受的,那怎么办呢,只好优化一下,虽然自己也是菜鸡,只能简单的搞一搞了。
添加了动态阈值与后处理,有效的减少了误检。
感觉后处理是万能的,可以过滤掉好多东西
参考的代码
https://github.com/yangshiyu89/VIBE
通过profile分析了一下,瓶颈主要是在随机数生成上,所以,要减少随机数生成的次数。然后就是for循环慢,能改就尽量改成numpy。
def bg_update(I_gray,seg_mask,samples, sub_factor, fg_mask_counts):
height, width = seg_mask.shape
x_y_set = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]]
neighbor_num = len(x_y_set)
for i in range(height):
for j in range(width):
if not seg_mask[i,j]:
fg_mask_counts[i, j] = 0
r = np.random.randint(0, sub_factor)
if r == 0:
r = np.random.randint(0, sample_num)
samples[i, j, r] = I_gray[i, j]
r = np.random.randint(0, sub_factor)
if r == 0:
# x, y = random.choice(x_y_set)
rnd = np.random.randint(0, neighbor_num)
r = np.random.randint(0, sample_num)
ri = i + x_y_set[rnd][0]
rj = j + x_y_set[rnd][1]
try:
if not seg_mask[ri, rj]:
samples[ri, rj, r] = I_gray[i, j]
except:
pass
else:
fg_mask_counts[i, j] += 1
if fg_mask_counts[i, j] > 200:
r = np.random.randint(0, sub_factor)
if r == 0:
r = np.random.randint(0, sample_num)
samples[i, j, r] = I_gray[i, j]
return samples, fg_mask_counts
def get_segmap(I_gray, samples, _min, sample_num, radius):
height = I_gray.shape[0]
width = I_gray.shape[1]
distance = np.zeros((height, width, sample_num)).astype(np.int8)
for i in range(sample_num):
distance[:, :, i] = I_gray - samples[:, :, i]
distance = np.abs(distance)
'''动态阈值'''
mean_distance = np.average(distance, axis=-1).astype(np.uint8)
#radius_adp= np.where((5 * mean_distance)后处理才是万能的,怎么去处理缝隙啊,还有阴影啊。虽然文章挺老的,但是效果好啊。
最后就是Python真的是蜗牛,和c++比的话,所以,要是对时间有要求的话,还是转投c++的怀抱吧。一个想哭的我,不说话。