IOU,全稱爲intersection of union, 中文名“交併比”。這個概念理解起來不難,本文將從原理以及代碼實踐來解讀IOU。
首先要說明的是,IOU在檢測領域和分割領域都有應用,但這兩個領域的IOU計算方式是不一樣的。所以本文就分爲兩個部分。分別講解在分割和檢測兩個領域的IOU計算方式。
分割領域的IOU計算方式
假設白色區域爲1,黑色區域爲0。
根據IOU計算公式:
假設網絡輸出爲A,GT爲B。
那麼A交B非常好算。
intersection = (A * B).sum()
A並B的計算方式,就是A的白色面積+B的白色面積, 減去A和B的交集。
union = A.sum() + B.sum() - intersection
最終的IOU就是:
IOU = intersection / union
對於多類的語義分割任務計算IOU
上面講解的例子屬於二類分割,語義分割所要處理的數據集往往都是很多類的。網絡輸出的map的shape是[Batchsize, N, H, W], N是數據集的類別。這個時候我們如何計算IOU呢。
假設label的shape是[Batchsize , H, W], 值的範圍是[0-N-1]
A = net(X) # A是網絡輸出,shape爲[Batchsize, N, H, W]
A = np.argmax(A, axis=1) # A的shape現在爲 [Batchsize, H, W],和Gt一致
A += 1
Gt += 1
intersection = A * (A == Gt)
area_inter, _ = np.histogram(intersection, bins= NUMCLASS, range=(1, NUMCLASS))
area_pred, _ = np.histogram(A, bins= NUMCLASS, range=(1, NUMCLASS))
area_label, _ = np.histogram(Gt, bins= NUMCLASS, range=(1, NUMCLASS))
area_union = area_pred + area_label - area_inter
iou = area_inter / area_union
miou = iou.mean()
做一下解釋。np.histogram是統計直方圖的函數,通過該函數,
- 我們得知交集中每一個類別的像素值數目是多少
area_inter, _ = np.histogram(intersection, bins= NUMCLASS, range=(1, NUMCLASS))
- 得知預測結果的每一類別的像素值數目是多少
area_pred, _ = np.histogram(A, bins= NUMCLASS, range=(1, NUMCLASS))
- 得知label中每一個類別的像素值數目是多少
area_label, _ = np.histogram(Gt, bins= NUMCLASS, range=(1, NUMCLASS))
然後還是利用了兩個集合的並集等於兩個集合相加減去公共的部分
area_union = area_pred + area_label - area_inter
這裏得到了每一個類的IOU,Miou就是求均值,這就是最後兩句代碼的含義。
檢測任務中的IOU計算方式
依然是根據IOU的計算公式:
假設A是預測,B是GT。
先求交集。
我這裏僅分析如何獲得X軸上的交集區域的寬。另一個維度的分析類似的。
問號所指的長度使我們想求的。
然後我們使用相同的分析方法,得到。交集區域的面積就是
知道了交集,並集就好求了。
還是根據並集定理,A和B的並集是A和B的相加減去A和B的交集。
代碼實踐:
def iou(axmin,aymin,axmax,aymax, bxmin,bymin, bxmax, bymax):
width = min(axmin,bxmin) + (axmax-axmin) + (bxmax-bxmin) - max(axmax,bxmax)
height = min(aymin,bymin) + (aymax-aymin) + (bymax-bymin) - max(aymax,bymax)
return max(width*height/(
(ymax-ymin)*(xmax-xmin) + (aymax-aymin)*(axmax-axmin) - width*height
), 0)
最後結果的結果要和0比較,因爲如果得到的IOU小於0,說明沒有交集,iou爲0.但是分子的面積仍然是非0數字,是負數。所以最後需要和0比較。