OpenCV调用drawMatches绘制特征匹配点时报(-215:Assertion failed)错误
问题根因
匹配结果的索引顺序和cv2.drawMatches要求的顺序不匹配,触发了索引越界的断言校验。
错误原理说明
cv2.BFMatcher.match()的参数顺序为(查询描述子, 训练描述子),返回的每个DMatch对象中,queryIdx对应查询描述子所属的关键点索引,trainIdx对应训练描述子所属的关键点索引。你代码中调用的是bf.match(des2, des1),生成的匹配是needle图特征到src图特征的映射,queryIdx对应kp2(needle的关键点),trainIdx对应kp1(src的关键点)。cv2.drawMatches()的参数要求是:传入的匹配列表必须是第一个输入图像的特征到第二个输入图像的特征的映射。你调用时传入的前四个参数是src,kp1,needle,kp2,要求匹配的queryIdx对应kp1、trainIdx对应kp2,和你现有匹配的索引顺序完全相反,就会出现索引越界的-215错误。
修复方案
两种方案二选一即可:
- 调整匹配调用的参数顺序,生成符合drawMatches要求的匹配结果
将matches = bf.match(des2,des1)修改为matches = bf.match(des1, des2) - 调整drawMatches的参数顺序,和现有匹配的索引对应
将cv2.drawMatches(src,kp1,needle,kp2,matches[:10],None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)修改为cv2.drawMatches(needle,kp2,src,kp1,matches[:10],None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
健壮性优化补充
建议增加特征检测为空的判断,避免ORB未检测到有效特征时出现其他异常,优化后代码如下:
def j_feature_match(src, needle): orb = cv2.ORB_create() kp1, des1 = orb.detectAndCompute(src, None) kp2, des2 = orb.detectAndCompute(needle, None) # 空特征判断,可根据业务需求调整返回逻辑 if des1 is None or des2 is None or len(kp1) == 0 or len(kp2) == 0: return cv2.hconcat([src, needle]), 0 bf = cv2.BFMatcher(cv2.NORM_HAMMING2, crossCheck=False) matches = bf.match(des1,des2) matches = sorted(matches, key = lambda x:x.distance) src_img = cv2.drawMatches(src,kp1,needle,kp2,matches[:10],None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) return(src_img, len(matches))
内容的提问来源于stack exchange,提问作者Gog
相关产品推荐
相关产品推荐

