一、什麼是非極大值抑制
非極大值抑制(Non-Maximum Suppression,簡稱NMS)是一種用於邊緣檢測和目標檢測中的常用技術,其作用是對檢測到的邊緣或目標進行篩選和過濾,只保留最明顯、最顯著的部分。
在邊緣檢測中,Canny演算法常常會產生較多的細節邊緣,而非極大值抑制可以將這些邊緣過濾掉,只保留最明顯的邊緣;同樣,在目標檢測中,非極大值抑制有助於消除重複或遮蓋的目標,並只留下一些最突出的目標。
二、非極大值抑制的原理
非極大值抑制的原理非常簡單:對於檢測到的每個邊緣點或目標,取其周圍一個窗口內的所有相鄰點的灰度值,如果該點的灰度值最大,那麼就將其保留,否則將其丟棄。
以邊緣檢測為例,當Canny演算法對圖像進行邊緣檢測後,會得到很多邊緣點。由於像素點的灰度值往往會出現較大的變化,我們可以將這些邊緣點看作是局部的”山峰”,其周圍的邊緣點則是”山峰”的”山峰麓”。我們希望保留的是”山峰”最高、最明顯的點,而將其他點抑制掉。
三、非極大值抑制的實現
下面是一個使用Python實現的非極大值抑制的代碼示例:
import cv2
def non_max_suppression(boxes, overlapThresh):
# 如果框的數量為空,直接返回空列表
if len(boxes) == 0:
return []
# 如果輸入的框的數據類型為整數,將其轉換為浮點數
if boxes.dtype.kind == "i":
boxes = boxes.astype("float")
# 初始化選擇框的列表
pick = []
# 分別獲取框的坐標軸信息
startX = boxes[:, 0]
startY = boxes[:, 1]
endX = boxes[:, 2]
endY = boxes[:, 3]
# 計算矩形框的面積和排序
area = (endX - startX + 1) * (endY - startY + 1)
idxs = np.argsort(endY)
# 循環遍歷排序後的框的索引
while len(idxs) > 0:
# 取出框列表中的最後一個索引,並將其添加到已選擇的列表中
last = len(idxs) - 1
i = idxs[last]
pick.append(i)
# 尋找其他矩形與當前矩形交叉的面積
xx1 = np.maximum(startX[i], startX[idxs[:last]])
yy1 = np.maximum(startY[i], startY[idxs[:last]])
xx2 = np.minimum(endX[i], endX[idxs[:last]])
yy2 = np.minimum(endY[i], endY[idxs[:last]])
# 計算矩形框之間的交叉面積
w = np.maximum(0, xx2 - xx1 + 1)
h = np.maximum(0, yy2 - yy1 + 1)
# 計算交叉面積比
overlap = (w * h) / area[idxs[:last]]
# 將交叉面積比小於給定閾值的索引從列表中刪除
idxs = np.delete(idxs, np.concatenate(([last],np.where(overlap > overlapThresh)[0])))
# 返回選擇框的列表
return boxes[pick].astype("int")
該代碼實現了一個基於IoU重疊度的非極大值抑制演算法,其中的參數boxes代表一組含有x、y、w、h四個坐標的框,overlapThresh代表給定的IoU重疊度閾值。該演算法會對輸入的框進行遍歷,依次計算每個框和其他框的IoU重疊度,並選擇IoU大於給定閾值的框保留。
四、非極大值抑制的應用
在實際應用中,非極大值抑制被廣泛應用於目標檢測、人臉識別、OCR等領域。例如,當我們要對一組人臉圖像進行檢測時,非極大值抑制可以幫助我們消除重複或遮蓋的人臉,並只保留一些最明顯、最突出的人臉。
下面是一個基於非極大值抑制演算法的人臉檢測示例代碼:
import cv2
def detect_faces(image, face_cascade):
# 將圖像轉灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用分類器檢測圖像中的人臉
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
# 對檢測到的矩形框進行非極大值抑制,保留最突出的人臉
faces = non_max_suppression(faces, 0.3)
# 返回人臉框的坐標信息及圖像
return faces, image
# 初始化人臉檢測器
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# 讀取輸入圖像
image = cv2.imread("test.jpg")
# 檢測圖像中的人臉
faces, image = detect_faces(image, face_cascade)
# 循環遍歷檢測到的人臉,並在圖像上進行標註
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 顯示標註後的圖像
cv2.imshow("Faces found", image)
cv2.waitKey(0)
該代碼利用OpenCV庫提供的分類器,從一張圖像中檢測到其中的人臉框,然後使用非極大值抑制方法,從中選擇最突出、最明顯的人臉框。最後,程序對圖像中的每個人臉框進行標記,並在圖像上顯示標記後的結果。
原創文章,作者:KUBRN,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/332039.html
微信掃一掃
支付寶掃一掃