百度飛槳(PaddlePaddle) - PP-OCRv3 文字檢測識(shí)別系統(tǒng) 預(yù)測部署簡介與總覽
百度飛槳(PaddlePaddle) - PP-OCRv3 文字檢測識(shí)別系統(tǒng) Paddle Inference 模型推理(離線部署)
百度飛槳(PaddlePaddle) - PP-OCRv3 文字檢測識(shí)別系統(tǒng) 基于 Paddle Serving快速使用(服務(wù)化部署 - CentOS)
百度飛槳(PaddlePaddle) - PP-OCRv3 文字檢測識(shí)別系統(tǒng) 基于 Paddle Serving快速使用(服務(wù)化部署 - Docker)
NMS(non maximum suppression)即非極大值抑制,廣泛應(yīng)用于傳統(tǒng)的特征提取和深度學(xué)習(xí)的目標(biāo)檢測算法中。
NMS原理是通過篩選出局部極大值得到最優(yōu)解。
在2維邊緣提取中體現(xiàn)在提取邊緣輪廓后將一些梯度方向變化率較小的點(diǎn)篩選掉,避免造成干擾。
在三維關(guān)鍵點(diǎn)檢測中也起到重要作用,篩選掉特征中非局部極值。
在目標(biāo)檢測方面,無論是One-stage的SSD系列算法、YOLO系列算法還是Two-stage的基于RCNN系列的算法,非極大值抑制都是其中必不可少的一個(gè)組件,可以將較小分?jǐn)?shù)的輸出框過濾掉,同樣,在三維基于點(diǎn)云的目標(biāo)檢測模型中亦有使用。
在現(xiàn)有的基于anchor的目標(biāo)檢測算法中,都會(huì)產(chǎn)生數(shù)量巨大的候選矩形框,這些矩形框有很多是指向同一目標(biāo),因此就存在大量冗余的候選矩形框。非極大值抑制算法的目的正在于此,它可以消除多余的框,找到最佳的物體檢測位置。
IoU(Intersection over Union) :定位精度評(píng)價(jià)公式。
相當(dāng)于兩個(gè)區(qū)域交叉的部分除以兩個(gè)區(qū)域的并集部分得出的結(jié)果。
IoU各個(gè)取值時(shí)的情況展示,一般來說,這個(gè) Score > 0.5 就可以被認(rèn)為一個(gè)不錯(cuò)的結(jié)果了。
IOU計(jì)算:
如何計(jì)算IoU(交并比)
選取兩個(gè)矩形框左頂角的橫,縱坐標(biāo)的最大值,x21,y21;選取兩個(gè)矩形框右下邊角的橫縱坐標(biāo)的最小值,x12,y12;
- 交集面積計(jì)算:
- 并集面積計(jì)算:
- 計(jì)算IOU公式
算法流程如下:
- 將所有框的得分排序,選中最高分及其對(duì)應(yīng)的框
- 遍歷其余的框,如果和當(dāng)前最高分框的重疊面積(IOU)大于一定閾值(常用的值為0.5左右),我們就將框刪除。(為什么要?jiǎng)h除,是因?yàn)槌^設(shè)定閾值,認(rèn)為兩個(gè)框的里面的物體屬于同一個(gè)類別,比如都屬于狗這個(gè)類別。我們只需要留下一個(gè)類別的可能性框圖即可。)
- 從未處理的框中繼續(xù)選一個(gè)得分最高的,重復(fù)上述過程。
代碼如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
NMS function(Non-Maximum Suppression, 抑制不是極大值的元素)
psedocode:
1. choose the highest score element a_1 in set B, add a_1 to the keep set C
2. compute the IOU between the chosen element(such as a_1) and others elements in set B
3. only keep the nums at set B whose IOU value is less than thresholds (can be set as >=0.5), delete the nums similiar
to a_1(the higher IOU it is , the more interseciton between a_1 and it will have)
4. choose the highest score value a_2 left at set B and add a_2 to set C
5. repeat the 2-4 until there is nothing in set B, while set C is the NMS value set
"""
import numpy as np
# boxes表示人臉框的xywh4點(diǎn)坐標(biāo)+相關(guān)置信度
boxes = np.array([[100, 100, 210, 210, 0.72],
[250, 250, 420, 420, 0.8],
[220, 220, 320, 330, 0.92],
[230, 240, 325, 330, 0.81],
[220, 230, 315, 340, 0.9]])
def py_cpu_nms(dets, thresh):
# dets:(m,5) thresh:scaler
x1 = dets[:, 0] # [100. 250. 220. 230. 220.]
y1 = dets[:, 1] # [100. 250. 220. 240. 230.]
x2 = dets[:, 2] # [210. 420. 320. 325. 315.]
y2 = dets[:, 3] # [210. 420. 330. 330. 340.]
areas = (y2 - y1 + 1) * (x2 - x1 + 1)
scores = dets[:, 4] # [0 1 3 4 2]
keep = []
# index表示按照scores從高到底的相關(guān)box的序列號(hào)
index = scores.argsort()[::-1] # [2 4 3 1 0]
while index.size > 0:
print("sorted index of boxes according to scores", index)
# 選擇得分最高的score直接加入keep列表中
i = index[0]
keep.append(i)
# 計(jì)算score最高的box和其他box分別的相關(guān)交集坐標(biāo)
x11 = np.maximum(x1[i], x1[index[1:]]) # [220. 230. 250. 220.] 最高的被提走了,所以要從1開始取后 4位
y11 = np.maximum(y1[i], y1[index[1:]]) # [230. 240. 250. 220.]
x22 = np.minimum(x2[i], x2[index[1:]]) # [315. 320. 320. 210.]
y22 = np.minimum(y2[i], y2[index[1:]]) # [330. 330. 330. 210.]
print("x1 values by original order:", x1)
print("x1 value by scores:", x1[index[:]]) # [220. 220. 230. 250. 100.]
print("x11 value means replacing the less value compared" \
" with the value by the largest score :", x11)
# 計(jì)算交集面積
w = np.maximum(0, x22 - x11 + 1) # the weights of overlap
h = np.maximum(0, y22 - y11 + 1) # the height of overlap
overlaps = w * h
# 計(jì)算相關(guān)IOU值(交集面積/并集面積,表示邊框重合程度,越大表示越相似,越該刪除)
# 重疊面積 /(面積1+面積2-重疊面積)
ious = overlaps / (areas[i] + areas[index[1:]] - overlaps)
# 只保留iou小于閾值的索引號(hào),重復(fù)上步
idx = np.where(ious <= thresh)[0]
# 因?yàn)榈谝徊絠ndex[0]已經(jīng)被劃走,所以需要原來的索引號(hào)需要多加一
index = index[idx + 1]
return keep
import matplotlib.pyplot as plt
def plot_bbox(ax, dets, c='b', title_name="title"):
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
ax.plot([x1, x2], [y1, y1], c)
ax.plot([x1, x1], [y1, y2], c)
ax.plot([x1, x2], [y2, y2], c)
ax.plot([x2, x2], [y1, y2], c)
ax.set_title(title_name)
if __name__ == '__main__':
# 1.創(chuàng)建畫板fig
fig = plt.figure(figsize=(12, 6))
# 參數(shù)解釋,前兩個(gè)參數(shù) 1,2 表示創(chuàng)建了一個(gè)一行兩列的框 第三個(gè)參數(shù)表示當(dāng)前所在的框
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)
plot_bbox(ax1, boxes, 'k', title_name="before nms") # before nms
keep = py_cpu_nms(boxes, thresh=0.7)
plot_bbox(ax2, boxes[keep], 'r', title_name="after nms") # after nms
plt.show()
文章來源:http://www.zghlxwxcb.cn/news/detail-458501.html
參考文獻(xiàn):
https://blog.csdn.net/weixin_42237113/article/details/105743296
https://blog.csdn.net/lz867422770/article/details/100019587文章來源地址http://www.zghlxwxcb.cn/news/detail-458501.html
到了這里,關(guān)于非極大值抑制(NMS)算法詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!