如何向量化指数概率热图函数,及极小概率值的处理方案
向量化改造方案
你当前的嵌套循环可以完全替换为numpy的广播运算,避免Python层的循环开销,运行效率可以提升几十到上百倍。改造思路是直接生成全图的坐标索引矩阵,批量计算所有像素点到landmark的曼哈顿距离,再整体计算概率值。
改造后的代码示例:
import numpy as np def expfunc_vectorized(image, landmark, sigma=6, threshold=0.01): a = np.sqrt(np.log(2)/2) / sigma # 生成全图像素的行、列索引矩阵,shape和输入image一致 y_idx, x_idx = np.indices(image.shape) # 批量计算所有点到关键点的曼哈顿距离 manhattan_dist = np.abs(y_idx - landmark[0]) + np.abs(x_idx - landmark[1]) # 批量计算所有位置的概率值 prob = np.exp(-a * manhattan_dist) # 阈值过滤,小于阈值的位置直接置0 prob[prob < threshold] = 0 # 赋值到输入image数组 image[:] = prob return image
如果你的输入image尺寸固定为512*512,还可以提前预生成索引矩阵,每次调用函数时不用重复生成,能进一步提速。
极小值处理方案
你当前用0.01作为阈值的方案是合理的:
- 从视觉效果看,热图中小于0.01的概率值几乎没有可见的灰度贡献,置0不会影响热图的直观表达
- 从计算效率看,置0后如果后续处理支持稀疏运算,还能降低后续计算开销
更优的处理方式可以根据你的使用场景选择:
- 如果追求更高的计算效率:可以先提前计算阈值对应的最大曼哈顿距离
d_max = -np.log(0.01)/a,只计算以landmark为中心、边长为2*d_max的矩形区域内的像素值,区域外的直接置0,不用做全图的指数运算,能进一步减少计算量 - 如果是用于深度学习关键点检测任务:可以根据你的标注误差容忍度调整阈值,比如标注误差在2像素以内的话可以适当降低阈值到0.005,保留更多周边的梯度信息
- 如果需要保留完整精度同时节省存储空间:可以将结果转为scipy的稀疏矩阵存储,不用硬置0也能降低存储开销
内容的提问来源于stack exchange,提问作者Ode
相关产品推荐
相关产品推荐

