IOU(交并比)和NMS(非极大值抑制)及其代码实现

一、IOU(交并比)

是目标检测中常用的评估指标和匹配准则之一。它衡量了两个边界框(或区域)的重叠程度,通过计算它们的交集面积除以它们的并集面积来表示。

作用:
1.目标匹配:在目标检测任务中,IoU常用于匹配预测的边界框和真实的边界框。通过计算预测边界框与真实边界框的IoU,可以判断它们之间的重叠程度,从而确定是否正确地检测到了目标。

2.边界框评估:IoU可用于评估边界框的准确性。当预测的边界框与真实边界框的IoU高于一定阈值时,通常认为该预测是正确的,否则会被视为误检。

3.非极大值抑制(NMS):IoU在非极大值抑制中起到重要的作用。在多个重叠的预测边界框中,NMS通过比较它们之间的IoU,选择具有最高置信度的边界框,并抑制其他重叠的边界框,以避免重复检测同一目标。

4.边界框回归:在一些目标检测方法中,通过回归预测边界框的位置和尺寸。IoU可以用作回归目标的一部分,用于衡量回归预测的边界框与真实边界框之间的重叠程度,从而帮助模型学习更准确的边界框回归。

二、iou的缺陷

1.敏感性于目标大小:IoU对目标大小非常敏感。当目标较小时,即使存在较小的偏移或误差,IoU也可能会受到显著影响。因此,在评估小目标的性能时,IoU可能会导致不准确的结果。

2.对目标形状不敏感:IoU仅考虑了两个边界框的重叠区域,并未考虑目标的形状信息。因此,如果目标的形状与边界框不完全匹配,IoU可能无法准确评估目标检测或分割的性能。

3.没有相交无法进行梯度计算:在目标检测任务中,当两个边界框的IoU为0时,意味着它们没有任何重叠的区域。这种情况下,由于没有共享的区域,无法计算出可靠的梯度信息。

4.相同的IOU却反映不出实际情况:在某些情况下,相同的IoU值可能无法准确反映出实际情况。
具体改进大家可以参考这篇博客:http://t.csdn.cn/rTfIz


```python
在这里插入代码片
```def Iou(box1,box2,wh=False):
    # 判断bbox的表示形式
    if wh==False:
        xmin1,ymin1,xmax1,ymax1=box1
        xmin2,ymin2,xmax2,ymax2=box2
    else:
        xmin1,ymin1=int(box1[0]-box1[2]/2.0),int(box1[1]-box1[3]/2.0)
        xmax1,ymax1=int(box1[0]+box1[2]/2.0),int(box1[1]+box1[3]/2.0)
        xmin2,ymin2=int(box2[0]-box2[2]/2.0),int(box2[1]-box2[3]/2.0)
        xmax2,ymax2=int(box2[0]+box2[2]/2.0),int(box2[1]+box2[3]/2.0)
    # 获取矩形框交集对应的左上⻆和右下⻆的坐标(intersection)
    xx1=np.max([xmin1,xmin2])
    yy1=np.max([ymin1,ymin2])
    xx2=np.min([xmax1,xmax2])
    yy2=np.min([ymax1,ymax2])
    # 计算两个矩形框⾯积
    area1=(xmax1-xmin1)*(ymax1-ymin1)
    area2=(xmax2-xmin2)*(ymax2-ymin2)
    #计算交集⾯积
    inter_area=(np.max([0,xx2-xx1]))*(np.max([0,yy2-yy1]))
    #计算交并⽐
    iou = inter_area / (area1+area2-inter_area+1e-6)
    return iou

三、NMS(非极大值抑制)

非极大值抑制(Non-Maximum Suppression,NMS)是一种常用的目标检测算法中的后处理步骤,用于抑制重复的边界框,从而提高检测结果的准确性和去除重叠的目标框,并且我们都是对同一类别的检测框使用非极大值抑制。
他的步骤是:
1.输入:NMS的输入是一系列候选边界框(bounding boxes),每个边界框通常由以下信息组成:坐标(左上角和右下角)、置信度得分等。
2.根据置信度排序:首先,根据边界框的置信度得分对所有候选框进行降序排序,确保得分最高的边界框排在前面。
3.选择最高得分的边界框:从排序后的边界框列表中选择得分最高的边界框,将其标记为最终输出的检测结果。
4.计算重叠度:从剩余的边界框中,计算与选定边界框的重叠度。常用的重叠度度量是IoU(交并比),计算方式是两个边界框的相交面积除以它们的并集面积。
5.抑制重叠边界框:对于重叠度高于预设阈值的边界框,将其从列表中移除,只保留重叠度较低的边界框。
6.重复步骤4和步骤5:重复进行步骤4和步骤5,直到所有的边界框都被处理完毕。
7.输出最终边界框:最后,输出经过非极大值抑制后得到的最终边界框列表作为目标检测的结果。
NMS的主要作用是1.去除冗余边界框,2.选择最佳边界框,3.提高检测精度

代码如下为了更好的观察,我在中间设置了一些输出。

def nms(bboxes,score,threshold):
    if len(bboxes)==0:
        return [],[]
    bboxes=np.array(bboxes)
    print(bboxes)
    score=np.array(score)
    print(score)
    x1=bboxes[:,0]
    print(x1)
    y1=bboxes[:,1]
    print(y1)
    x2=bboxes[:,2]
    y2=bboxes[:,3]
    
    picked_boxes=[]
    picked_score=[]
    
    order=np.argsort(score)
    print('排序',order)
    area=(x2-x1)*(y2-y1)
    print('面积',area)
    
    while order.size>0:
        index=order[-1]
        #保留该类剩余box中得分最⾼的⼀个
        picked_boxes.append(bboxes[index])
        picked_score.append(score[index])
        # 获取当前置信度最⼤的候选框与其他任意候选框的相交⾯积
        print(x1[order[:-1]])
        x11=np.maximum(x1[index],x1[order[:-1]])
        print('坐标x11',x11)
        y11=np.maximum(y1[index],y1[order[:-1]])
        x22=np.minimum(x2[index],x2[order[:-1]])
        print('坐标x22',x11)
        y22=np.minimum(y2[index],y2[order[:-1]])
        
        w=np.maximum(0.0,x22-x11)
        print('w的宽度',w)
        h=np.maximum(0.0,y22-y11)
        intersection=w*h
        # 利⽤相交的⾯积和两个框⾃身的⾯积计算框的交并⽐
        ratio=intersection/(area[index]+area[order[:-1]]-intersection)
        print(area[index])
        print(area[order[:-1]])
        print('比率',ratio)
        # 保留IoU⼩于阈值的box
        keep_boxes_indics=np.where(ratio<threshold)
        #保留剩余的框
        order=order[keep_boxes_indics]
        return picked_boxes,picked_score
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
NMS(Non-Maximum Suppression)非极大值抑制是目标检测中常用的一种算法,用于消除重叠的边界框,并筛选出最优的边界框。下面是Java实现NMS的完整源码。 ```java import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * NMS(Non-Maximum Suppression)非极大值抑制算法的Java实现 */ public class NMS { /** * 定义一个边界框类,用于存储边界框的坐标和置信度 */ private static class BoundingBox { float x1, y1, x2, y2; // 左上角和右下角的坐标 float confidence; // 置信度 BoundingBox(float x1, float y1, float x2, float y2, float confidence) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.confidence = confidence; } float getArea() { return (x2 - x1 + 1) * (y2 - y1 + 1); } } /** * 定义一个比较器类,用于按照置信度降序排序 */ private static class ConfidenceComparator implements Comparator<BoundingBox> { @Override public int compare(BoundingBox o1, BoundingBox o2) { if (o1.confidence > o2.confidence) { return -1; } else if (o1.confidence < o2.confidence) { return 1; } return 0; } } /** * NMS算法的主要实现 * @param boxes 边界框列表 * @param overlapThreshold IOU阈值 * @return 非极大值抑制后的边界框列表 */ public static List<BoundingBox> nms(List<BoundingBox> boxes, float overlapThreshold) { // 按照置信度降序排序 Collections.sort(boxes, new ConfidenceComparator()); List<BoundingBox> result = new ArrayList<>(); while (!boxes.isEmpty()) { BoundingBox box = boxes.remove(0); result.add(box); List<BoundingBox> toRemove = new ArrayList<>(); for (BoundingBox b : boxes) { float iou = getIOU(box, b); if (iou > overlapThreshold) { toRemove.add(b); } } boxes.removeAll(toRemove); } return result; } /** * 计算两个边界框的IOU(Intersection over Union) * @param box1 边界框1 * @param box2 边界框2 * @return IOU值 */ private static float getIOU(BoundingBox box1, BoundingBox box2) { float area1 = box1.getArea(); float area2 = box2.getArea(); float x1 = Math.max(box1.x1, box2.x1); float y1 = Math.max(box1.y1, box2.y1); float x2 = Math.min(box1.x2, box2.x2); float y2 = Math.min(box1.y2, box2.y2); float w = Math.max(0, x2 - x1 + 1); float h = Math.max(0, y2 - y1 + 1); float inter = w * h; return inter / (area1 + area2 - inter); } } ``` 使用示例: ```java public class NMSDemo { public static void main(String[] args) { List<NMS.BoundingBox> boxes = new ArrayList<>(); boxes.add(new NMS.BoundingBox(10, 10, 20, 20, 0.9f)); boxes.add(new NMS.BoundingBox(15, 15, 25, 25, 0.8f)); boxes.add(new NMS.BoundingBox(30, 30, 40, 40, 0.7f)); List<NMS.BoundingBox> result = NMS.nms(boxes, 0.5f); for (NMS.BoundingBox box : result) { System.out.println(box.x1 + "," + box.y1 + "," + box.x2 + "," + box.y2 + "," + box.confidence); } } } ``` 输出结果: ``` 10.0,10.0,20.0,20.0,0.9 30.0,30.0,40.0,40.0,0.7 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值