如何避免OpenCV中SIFT算法重复提取同一关键点?
SIFT同一位置重复提取关键点的解决方法
SIFT出现同一位置多次提取、描述子不一致的核心原因有两个:一是尺度空间极值检测时,同一个空间坐标可能在多个尺度上满足响应阈值,被判定为多个关键点;二是主方向检测步骤会为同一个极值点分配多个方向,每个方向会单独生成关键点和对应的描述子。
可通过以下两种方式解决,得到唯一的关键点:
- 调整SIFT初始化参数
调高contrastThreshold(对比度阈值)过滤低响应极值点,调低edgeThreshold(边缘响应阈值)过滤边缘处的不稳定点,还可以减少高斯金字塔的组数降低多尺度重复的概率。OpenCV中初始化代码参考:sift = cv2.SIFT_create(contrastThreshold=0.06, edgeThreshold=8) - 提取后做去重后处理
这是最可控的解决方式,对提取到的所有关键点按空间坐标分组,同一坐标下仅保留响应值最高的单个关键点,再重新计算描述子即可。参考代码如下:
如果需要保留尺度维度的区分度,仅去掉同坐标同尺度下多方向导致的重复,可将分组键改为import cv2 img = cv2.imread("input.jpg", cv2.IMREAD_GRAYSCALE) sift = cv2.SIFT_create() kp, _ = sift.detectAndCompute(img, None) # 按坐标分组去重,坐标保留2位小数避免浮点精度误差导致的误判 kp_map = {} for p in kp: x, y = round(p.pt[0], 2), round(p.pt[1], 2) if (x, y) not in kp_map or p.response > kp_map[(x, y)].response: kp_map[(x, y)] = p # 获取唯一关键点和对应的唯一描述子 unique_kp = list(kp_map.values()) unique_kp, unique_des = sift.compute(img, unique_kp)(x, y, round(p.size, 2))即可。
内容的提问来源于stack exchange,提问作者Lorenzo
相关产品推荐
相关产品推荐

