LeetCode高频题:图像交并比IoU计算方法和手撕代码

LeetCode高频题:图像交并比IoU计算方法和手撕代码

提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
在这里插入图片描述


题目

请你说说iou怎么计算的,写出iou的计算方法


一、审题

示例:
在这里插入图片描述

给你的俩矩阵的下标为:
rect1:左上角x1,y1,右下角x2,y2
rect2:左上角a1,b1,右下角a2,b2


这个题经常在互联网大厂的笔试面试中出现

很简单的思想

啥是iou?

IoU,即 intersection over Union
就是两个矩形框的交集面积与他们并集面积的比值。
(其实也不一定是矩形框,这里以矩形框进行说明)

IoU也是一种算法性能的指标,例如在语义分割时就会用IoU来衡量分割效果的好坏。
举例说明,如下图所示:
在这里插入图片描述
给你的输入是俩数组:
rect1:左上角x1,y1,右下角x2,y2【分别是0123位置】
rect2:左上角a1,b1,右下角a2,b2【分别是0123位置】

则相交的矩形框假设为X,左上角坐标设为点A,右下角坐标设为点B;

现在要计算 IoU = area_X / (area_1 + area_2 - area_X)
在这里插入图片描述
懂?

计算思路

相交的情况

两个矩形相交情况,如上图所示,只要矩形框A和B点的坐标,即可求出相交区域的面积,从而求得IoU。
在这里插入图片描述
AB坐标计算思路如下:【你面试的时候,直接画个图就完事了,非常简单】

A的横坐标 等于 两个矩形框左上角横坐标较大的那个,即Ax = max(x1, a1)
A的纵坐标 等于 两个矩形框左上角纵坐标较大的那个,即Ay = max(y1, b1)
B的横坐标 等于 两个矩形框右下角横坐标较小的那个,即Bx = min(x2, a2)
B的纵坐标 等于 两个矩形框右下角纵坐标较小的那个,即By = min(y2, b2)
在这里插入图片描述

显然,X的宽w=Bx-Ax,X的长是h=By-Ay
如果w或者h有一个小于0,说明他们俩压根没有交集!!!

那iou必然是0

因此我们过滤掉这个条件
最后得到了X的面积Sx=w*h

S1原本也好求:S1=(x2-x1)×(y2-y1)
S2原本也好求:S2=(a2-a1)×(b2-b1)
就是长乘宽就行

并集的面积,需要减x的面积,因为S1+S2重复加了x

故iou的三个元素都出来了,Sx,S1,S2都有了,那手撕代码问题就不大了吧
遇到输入是数组rect1,rect2,建议你先把坐标转化为自己熟悉的xy和ab,这样我们就好对应了

手撕代码:

    //计算 IoU = area_X / (area_1 + area_2 - area_X)

    //给你的输入是俩数组:
    //rect1:左上角x1,y1,右下角x2,y2【分别是0123位置】
    //rect2:左上角a1,b1,右下角a2,b2【分别是0123位置】
    //转化为自己熟悉的形式

    public static double iou(int[] rect1, int[] rect2){
        if (rect1 == null || rect1.length == 0 ||
        rect2 == null || rect2.length == 0) return 0;

        int x1 = rect1[0];
        int y1 = rect1[1];
        int x2 = rect1[2];
        int y2 = rect1[3];//rect1
        int a1 = rect2[0];
        int b1 = rect2[1];
        int a2 = rect2[2];
        int b2 = rect2[3];//rect2

        //草稿纸自己画个图就知道了
        //S1//S2
        double S1 = (x2 - x1) * (y2 - y1);
        double S2 = (a2 - a1) * (b2 - b1);

        //iou
        int Ax = Math.max(x1, a1);//交集左上角
        int Ay = Math.max(y1, b1);
        int Bx = Math.min(x2, y2);//交集右下角
        int By = Math.min(y2, b2);
        int w = Bx - Ax;
        int h = By - Ay;//交集长宽
        if (w <= 0 || h <= 0) return 0;//无交集

        double Sx = w * h;
        double ans = Sx / (S1 + S2 - Sx);
        System.out.println("交集面积:"+ Sx);

        return ans;
    }

测试一把:
在这里插入图片描述

    public static void test(){
        int[] rect1 = {2,1,4,3};
        int[] rect2 = {1,2,3,4};
        //画个图看看,交集A,B在
        System.out.println(iou(rect1, rect2));
    }

    public static void main(String[] args) {
        test();
    }

结果:

交集面积:1.0
0.14285714285714285

非常OK

所以笔试面试都好说,拿个图,直接画一下就行了,不是背公式,更不是背代码的事


总结

提示:重要经验:

1)笔试面试都好说,拿个图,直接画一下就行了,不是背公式,更不是背代码的事
2)IoU = area_X / (area_1 + area_2 - area_X)
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰露可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值