面经-手撕代码

IoU

矩形框的IoU

def compute_iou(rec1, rec2):
    """
    computing IoU
    param rec1: (y0, x0, y1, x1) , which reflects (top, left, bottom, right)
    param rec2: (y0, x0, y1, x1) , which reflects (top, left, bottom, right)
    return : scale value of IoU
    """
    S_rec1 =(rec1[2] -rec1[0]) *(rec1[3] -rec1[1])
    S_rec2 =(rec2[2] -rec2[0]) *(rec2[3] -rec2[1])
    #computing the sum area
    sum_area =S_rec1 +S_rec2
    #find the each edge of interest rectangle
    in_h = min(rec1[2], rec2[2]) - max(rec1[0], rec2[0])
    in_w = min(rec1[3], rec2[3]) - max(rec1[1], rec2[1])
    #judge if interact
    inter = 0 if in_h<0 or in_w<0 else in_h*in_w
    return intersect /(sum_area -intersect)

旋转目标的IoU

from shapely.geometry import Polygon

def intersection(g, p):
    g=np.asarray(g)
    p=np.asarray(p)
    g = Polygon(g[:8].reshape((4, 2)))
    p = Polygon(p[:8].reshape((4, 2)))
    if not g.is_valid or not p.is_valid:
        return 0
    inter = Polygon(g).intersection(Polygon(p)).area
    union = g.area + p.area - inter
    if union == 0:
        return 0
    else:
        return inter/union

语义分割的IoU

NMS

矩形框NMS

def nms_cpu(dets, thresh):
    dets = dets.numpy()
    x1 = dets[:, 0]  # 取出所有的边界框左上角点的x坐标放入x1
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]
 
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)  # 计算所有边界框的面积
    # numpyargsort()函数:返回数组值从小到大的索引值,
    # 再加上[::-1]返回数组值从大到小的索引值,
    # 也可以order = np.argsort(-score)
    order = scores.argsort()[::-1] #分数从大到小排列的索引值
 
    # 每次选出scores中最大的那个边界框
    keep = []
    while order.size > 0:
        i = order[0]
        keep.append(i)  # 保留该类剩余box中得分最高的索引
        xx1 = np.maximum(x1[i], x1[order[1:]])#获取得分最高的边界框与其他所有框的的重叠区域的左上角x坐标
        yy1 = np.maximum(y1[i], y1[order[1:]])#标量和numpy取最值,结果是一个numpy
        xx2 = np.minimum(x2[i], x2[order[1:]])#此处是minimun,不是maximum。求得分最高的边界框与其他所有框的的重叠区域的右下角x坐标
        yy2 = np.minimum(y2[i], y2[order[1:]])
 
        # 计算重叠的面积,不重叠时面积为0
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h#得到最大得分框和其他框的重叠面积
 
        # 计算IOU=重叠面积/(得分最大的框面积+当前的框面积-重叠面积)
        ovr = inter / (areas[i] + areas[order[1:]] - inter)
        # 保留iou小于等于阈值的边界框,其它则被过滤了
        # numpy.where() 有两种用法:
        # 1.np.where(condition, x, y):满足条件(condition),输出x,不满足输出y。
        # 2.np.where(condition):输出满足条件(即非0)元素的坐标(等价于numpy.nonzero)
        inds = np.where(ovr <= thresh)[0]#重叠面积小表示要保留
        # 因为ovr数组的长度比order数组少一个,所以这里要将所有下标后移一位,
        # 获得下一个目标区域的得分最高的一个的索引
        order = order[inds + 1]
 
    return torch.IntTensor(keep)

soft_NMS

def soft_nms(boxes, sigma=0.5, threshold1=0.7, threshold2=0.1, method=1):
    '''
    paper:Improving Object Detection With One Line of Code
    '''
    N = boxes.shape[0]
    pos = 0
    maxscore = 0
    maxpos = 0

    for i in range(N):
    # 用冒泡排序法找到分数最高的预测框,并将该预测框放在第i个位置
        maxscore = boxes[i, 4]
        maxpos = i
 # 先用一些中间变量存储第i个预测框
        tx1 = boxes[i, 0]
        ty1 = boxes[i, 1]
        tx2 = boxes[i, 2]
        ty2 = boxes[i, 3]
        ts = boxes[i, 4]

        pos = i + 1
        # 得到评分最高的box
        while pos < N:
            if maxscore < boxes[pos, 4]:
                maxscore = boxes[pos, 4]
                maxpos = pos
            pos = pos + 1

        # 交换第i个box和评分最高的box,将评分最高的box放到第i个位置
        boxes[i, 0] = boxes[maxpos, 0]
        boxes[i, 1] = boxes[maxpos, 1]
        boxes[i, 2] = boxes[maxpos, 2]
        boxes[i, 3] = boxes[maxpos, 3]
        boxes[i, 4] = boxes[maxpos, 4]
		# 将原先第i个预测框放在分数最高的位置
        boxes[maxpos, 0] = tx1
        boxes[maxpos, 1] = ty1
        boxes[maxpos, 2] = tx2
        boxes[maxpos, 3] = ty2
        boxes[maxpos, 4] = ts
# 程序到此实现了:寻找第i至第N个预测框中分数最高的框,并将其与第i个预测框互换位置。
# 预测框M,前缀"t"表示target
        tx1 = boxes[i, 0]
        ty1 = boxes[i, 1]
        tx2 = boxes[i, 2]
        ty2 = boxes[i, 3]
        ts = boxes[i, 4]
        
	    # 下面针对M进行NMS迭代过程,
        # 需要注意的是,如果soft-NMS将score削弱至某阈值threshold以下,则将其删除掉
        # 在程序中体现为,将要删除的框放在了最后,并使 N = N-1
        pos = i + 1
        # softNMS迭代
        while pos < N:
            x1 = boxes[pos, 0]
            y1 = boxes[pos, 1]
            x2 = boxes[pos, 2]
            y2 = boxes[pos, 3]
            s = boxes[pos, 4]

            area = (x2 - x1 + 1) * (y2 - y1 + 1)
            iw = (min(tx2, x2) - max(tx1, x1) + 1)
            if iw > 0:
                ih = (min(ty2, y2) - max(ty1, y1) + 1)
                if ih > 0:
                    uinon = float((tx2 - tx1 + 1) *
                                  (ty2 - ty1 + 1) + area - iw * ih)
                    iou = iw * ih / uinon  # 计算iou
                    if method == 1:  # 线性更新分数
                        if iou > threshold1:
                            weight = 1 - iou
                        else:
                            weight = 1
                    elif method == 2:  # 高斯权重
                        weight = np.exp(-(iou * iou) / sigma)
                    else:  # 传统 NMS
                        if iou > threshold1:
                            weight = 0
                        else:
                            weight = 1

                    boxes[pos, 4] = weight * boxes[pos, 4]  # 根据和最高分数box的iou来更新分数

                    # 如果box分数太低,舍弃(把他放到最后,同时N-1)
                    if boxes[pos, 4] < threshold2:
                        boxes[pos, 0] = boxes[N - 1, 0]
                        boxes[pos, 1] = boxes[N - 1, 1]
                        boxes[pos, 2] = boxes[N - 1, 2]
                        boxes[pos, 3] = boxes[N - 1, 3]
                        boxes[pos, 4] = boxes[N - 1, 4]
                        N = N - 1  # 注意这里N改变
                        pos = pos - 1

            pos = pos + 1

    keep = [i for i in range(N)]
    return keep
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《java面经-百度准入职老哥整理.pdf》是一份关于百度准入职面试的Java面经整理。这份面经是由百度准入职的老哥整理而成,其中记录了一些面试时可能会遇到的问题以及解答方法。 这份面经对于准备参加百度准入职面试的人来说非常有价值。首先,它列出了一些常见的面试问题,涵盖了Java语言的各个方面,包括基础知识、数据结构与算法、设计模式、多线程、网络编程等等。通过仔细研究和复习这些问题的答案,可以帮助面试者全面了解Java语言的特性和应用。 其次,这份面经还提供了问题的解答思路和方法,帮助面试者理清思路,正确回答问题。这对于很多面试者来说特别有帮助,因为在面试时有时会遇到一些棘的问题,有了这份面经的指导,面试者可以更好地掌握应对策略。 不过需要注意的是,面经作为一份参考资料,不能完全依赖于它来准备面试。面试官可能会问一些不在面经中列出的问题,因此考生还是需要自己对Java语言有充分的了解,并能够熟练运用。同时,面试官还会关注考生的沟通能力、解决问题的能力以及对新技术的学习和掌握能力。 总体来说,《java面经-百度准入职老哥整理.pdf》是一份非常宝贵的资料,可以帮助面试者对Java面试中可能会遇到的问题有更深入的了解,提供了解答思路和方法。但记住,面试准备还需要多方面的知识积累和实践经验的积累,才能在面试中展现自己的优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值