『人脸识别』MTCNN之Pytorch版本NMS代码实现

1.练习_从大到小排序

import numpy as np

a=np.array([[5,3],[3,2],[1,6]])
print(a)
#取出第二列数据
d=a[:,1]
print(d)
#按照第二列数据从小到大排序。排序规则为:按照第二列数从小到大对应的索引进行排序
#1.取出第二列数据从小到大对应的索引值。
index=a[:,1].argsort()
print(index)
#2.根据索引排序
print(a[index])#将索引放到a中即可

#从大到小排序。对索引添加符号即可。-a[:,1].argsort()
print(a[-a[:,1].argsort()])

打印结果:

[[5 3]
 [3 2]
 [1 6]]
[3 2 6]
[1 0 2]
[[3 2]
 [5 3]
 [1 6]]
[[1 6]
 [5 3]
 [3 2]]

2.练习_where函数

import numpy as  np

a=np.array([8,7,6,3,1,9])

print(np.where(a<5))#返回索引
print(a[np.where(a<5)])#返回索引值

打印结果:

(array([3, 4], dtype=int64),)
[3 1]

3.练习_stack函数

"""把数组组装成矩阵"""
import numpy as np

a=np.array([1,2])
b=np.array([3,4])
c=np.array([5,6])

ls=[]

ls.append(a)
ls.append(b)
ls.append(c)
print(ls)

#组装
print(np.stack(ls))

打印结果:

[array([1, 2]), array([3, 4]), array([5, 6])]
[[1 2]
 [3 4]
 [5 6]]

4.NMS代码

import numpy as np

"""IOU"""
def iou(box,boxes,isMin=False):#框的格式定义为:[X1,Y1,X2,Y2,C]。一个框和一堆框做比较。为了区分交集是与并集作比较还是和最小面积做比较,先将最小面积赋予默认值0.
    #计算每个框的面积
    box_area=(box[2]-box[0])*(box[3]-box[1])#先计算box的面积。一个框的面积计算:(X2-X1)*(Y2-Y1)。索引拿到坐标值:(box[2]-box[0])*(box[3]-box[1])
    boxes_area=(boxes[:,2]-boxes[:,0])*(boxes[:,3]-boxes[:,1])#一堆框的格式:[[],[],[],[],[],...]

    #计算交集面积
    xx1=np.maximum(box[0],boxes[:,0])#左上角X。交集左上角点坐标:两个相交原框中左上角X和Y各自取较大值,作为交集左上角坐标。用于比较的框的左上角x值:box[0];被比较的框的左上角x值:boxes[0]。去两者较大值。
    yy1=np.maximum(box[1],boxes[:,1])#同理.左上角Y。
    xx2 = np.minimum(box[2], boxes[:, 2])  # 同理.右下角X。
    yy2 = np.minimum(box[3], boxes[:, 3])  # 同理.右下角Y。

    #判断是否有交集
    w=np.maximum(0,xx2-xx1)#当xx2-xx1的值为负值时,表示没有交集,将没有交集的结果变成0即可。使用maximum函数取较大值。
    h=np.maximum(0,yy2-yy1)#同理。

    #正式计算交集面积
    inter=w*h

    if isMin:#如果isMin为True,表示除以最小面积。
        over=np.true_divide(inter,np.minimum(box_area,boxes_area))#true_divide:除法。isMin为True时,除以最小面积。如何得到最小面积呢?比较box_area和boxes_area,取最小值就可得到最小面积。
    else:#否则,除以并集面积。
        over = np.true_divide(inter, (box_area+boxes_area-inter))#两个矩形面积相加减去交集面积

    return over

"""NMS"""
def nms(boxes,thresh=0.3,isMin=False):#需要所有框、阈值、最小面积(传到IOU中,因为IOU是放在NMS里边计算的)
    #根据置信度从大到小排序。
    _boxes=boxes[(-boxes[:,4]).argsort()]       #框的格式定义为:[[X1,Y1,X2,Y2,C],[],[],[],[],...]

    #保留剩余的框
    r_boxes=[]
    #取出第一个框。因为要取很多次,使用循环。(重点)
    while _boxes.shape[0]>1:#循环取出第一个框(shape[0]),当循环过程中取出的维度大于1,说明有框;当维度小于1,表示框已经取完,循环结束。
        #取出第一个框
        a_box=_boxes[0]
        #取出剩余框
        b_boxes=_boxes[1:]
        #保留第一个框
        r_boxes.append(a_box)

        #比较IOU后,保留阈值较小的值
        index=np.where(iou(a_box,b_boxes,isMin)<thresh)#将iou于阈值作比较:iou(a_box,b_boxes,isMin)<thresh,如果iou小于阈值,保留。使用np.where,当小于为True。
        _boxes=b_boxes[index]
    if _boxes.shape[0]>0:
        r_boxes.append(_boxes[0])

    #组装为矩阵
    return np.stack(r_boxes)

if __name__ == '__main__':
    bs=np.array([[2,2,30,30,40],[3,3,25,25,60],[18,18,27,27,15]])
    print(nms(bs))

打印结果:

[[ 3  3 25 25 60]
 [18 18 27 27 15]]
发布了29 篇原创文章 · 获赞 45 · 访问量 5043

猜你喜欢

转载自blog.csdn.net/sinat_39783664/article/details/104142808