背景
这篇博文是因为想复现这篇博客远距离行人检测:从标注方式出发。它使用了两个点来标注行人,并用高斯分布为两个点生成热力图,作为模型预测目标。那么很自然,第一个问题就是高斯分布热力图如何生成。其中高斯分布$e$项之前的$\frac 1 {\sqrt {2\pi} \sigma}$系数被省去,因为不同尺度的行人拟合的分布的$\sigma$必定不同,省去才能使热力图的值一致。代码写好了,数据集还没下载完,就撸篇博客吧。
自己的实现(逐点运算)
看了一些博客后自己实现了一个版本,代码如下:
%matplotlib inline |
分布的$\sigma$可以通过想要拟合的大小及改点的值算出,也就是代码中的$cal_sigma$函数。gaussian是修改版的二维高斯分布概率密度函数(Probability Density Function,pdf),逐点运算版本。为了提高速度,在$draw_heatmap$中对遍历范围进行了约束。
生成的热力图如下:
Numpy版本(向量计算)
逐点遍历速度当然不如向量计算来得快,通过面向Google编程后,用scipy的multivariate_normal方法实现了向量版。但因为我需要修改版的高斯分布,故用numpy实现了向量计算。代码如下:
import numpy as np |
这里的gaussion函数就是向量版本的。热力图如下:
速度测试
测试显示逐点版本在这个参数下计算一次高斯热力图需要142ms,而向量版本仅需21.4ms。逐点版本已经通过坐标限制了计算范围了,向量版本是对全图进行的计算就已领先这么多,如果也限制计算范围,估计速度还能提升一大截。
作为多年的程序员,遍历已经写了不知道多少次了。啥问题拿过来脑子里想的都是怎么遍历。然而很多时候矩阵计算才是王道,还需好好学习科学计算的各种库,学习矩阵计算的思想。
参考资料
How to efficiently compute the heat map of two Gaussian distribution in Python?
tf-openpose人体姿态估计标签生成—heatmap—vectormap