TensorFlow非极大值抑制(NMS)使用:如何获取筛选后框的坐标?
解决TensorFlow NMS输出拿不到框坐标的问题
嘿,我来帮你捋清楚这个问题!你现在遇到的情况主要有两个关键点:一是代码参数传错了,二是没搞懂NMS返回值的含义,咱们一步步来解决:
首先,先修正tf.image.non_max_suppression的参数错误
你现在第二个参数传了空列表[],这可不行!tf.image.non_max_suppression的第二个参数是每个检测框的置信度得分(scores),得传一个和框数量对应的一维数组才行。比如你的prediction[0]是形状为[num_boxes, 4]的框坐标数组(TF默认要求格式是[y_min, x_min, y_max, x_max]),那你得拿出对应的scores数组,形状是[num_boxes],每个元素对应一个框的置信度。
然后,搞懂NMS返回的是什么
tf.image.non_max_suppression返回的不是直接的框坐标,而是保留下来的框在原prediction[0]数组里的索引。所以你得用这些索引去原数组里“捞”出对应的坐标才行。
最后,获取具体的框坐标(分两种常用场景)
场景1:用TensorFlow 2.x(默认即时执行模式)
TF2.x默认是即时执行,不用写会话,直接转numpy就能拿到具体数值:
# 先假设你已经有了对应的scores数组(不能是空的!) selected_indices = tf.image.non_max_suppression( boxes=prediction[0], scores=scores, # 这里填你的置信度数组 max_output_size=15, iou_threshold=0.5 ) # 用索引从原框数组里提取选中的框 selected_boxes = tf.gather(prediction[0], selected_indices) # 转成numpy数组,就能看到具体的坐标值了 selected_boxes_np = selected_boxes.numpy() print(selected_boxes_np)
场景2:用TensorFlow 1.x或者手动关闭了即时执行
这种情况需要用会话来运行张量:
import tensorflow as tf # 先把数据转成TF常量 boxes = tf.constant(prediction[0], dtype=tf.float32) scores = tf.constant(your_scores_array, dtype=tf.float32) # 计算NMS选中的索引 selected_indices = tf.image.non_max_suppression( boxes=boxes, scores=scores, max_output_size=15, iou_threshold=0.5 ) # 提取选中的框 selected_boxes = tf.gather(boxes, selected_indices) # 运行会话拿到具体数值 with tf.Session() as sess: final_boxes = sess.run(selected_boxes) print(final_boxes)
额外小提醒
- 确认你的
prediction[0]坐标格式对不对:TF的NMS要求框是[y_min, x_min, y_max, x_max],而且数值最好是归一化到[0,1]之间的(如果是像素坐标,记得先除以图片宽高)。 - 如果你的模型输出里同时包含框和得分,记得正确拆分出scores数组,千万别再传空列表啦!
内容的提问来源于stack exchange,提问作者Dingo




