語義分割的標準度量MIoU

看大海發表於2020-10-28

參考:https://blog.csdn.net/u012370185/article/details/94409933?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-8-94409933.nonecase&utm_term=%E5%88%A9%E7%94%A8mask%E8%AE%A1%E7%AE%97%E4%BA%A4%E5%B9%B6%E6%AF%94&spm=1000.2123.3001.4430

https://blog.csdn.net/u014593748/article/details/71698246

mIoU原始碼解析:https://tianws.github.io/skill/2018/10/30/miou/

Mean Intersection over Union(MIoU,均交併比):為語義分割的標準度量。其計算兩個集合的交集和並集之比.

在語義分割的問題中,這兩個集合為真實值(ground truth)和預測值(predicted segmentation)。

這個比例可以變形為正真數(intersection)比上真正、假負、假正(並集)之和。在每個類上計算IoU,之後平均。

對於21個類別,分別求IOU:

例如,對於類別1的IOU定義如下:

(1)統計在ground truth中屬於類別1的畫素數

(2)統計在預測結果中每個類別1的畫素數

(1) + (2)就是二者的並集畫素數(類比於兩塊區域的面積加和, 注:二者交集部分的面積加重複了)

再減去二者的交集(既在ground truth集合中又在預測結果集合中的畫素),得到的就是二者的並集(所有跟類別1有關係的畫素:包括TP,FP,FN)

擴充套件提示:

TP(真正): 預測正確, 預測結果是正類, 真實是正類

FP(假正): 預測錯誤, 預測結果是正類, 真實是負類

FN(假負): 預測錯誤, 預測結果是負類, 真實是正類

TN(真負): 預測正確, 預測結果是負類, 真實是負類 #跟類別1無關,所以不包含在並集中

(本例中, 正類:是類別1, 負類:不是類別1)

mIoU:

對於每個類別計算出的IoU求和取平均
最近跑了個語義分割的模型,調查了下分割的測試標準

1,首先要用模型跑出(單類或多類)每張測試影像的分割結果,即分割識別的每個畫素點的位置(x,y),x是橫座標,y座標;不管是maskrcnn或者deeplab在跑出每張影像的測試結果都要轉化下,
在轉換的時候遇到了兩個問題點:
1, 當檢測結果是輪廓的座標時候,需要將輪廓轉換為整個框的座標,需要用到cv2.fillPoly,
有三個個方法

針對檢測結果是array

import cv2
import numpy as np
img = np.zeros((1080, 1920), np.uint8)
area1 = np.array([[250, 200], [300, 100], [750, 800], [100, 1000]])
area2 = np.array([[1000, 200], [1500, 200], [1500, 400], [1000, 400]])
cv2.fillPoly(img, [area1, area2], 255)
cv2.imshow('img', img)
cv2.waitKey(0)

針對檢測結果是list, 二維的

import cv2
import numpy as np
img = np.zeros((900, 1200), np.uint8)
points = [[250, 200], [300, 100], [750, 800], [100, 1000]]

points_array = np.array([points])#不指定dtype
cv2.fillPoly(seg_matrix, points_array, 255)
或者
points_array = np.array(points)#不指定dtype
cv2.fillPoly(seg_matrix, [points_array], 255)

2, 需要找到numpy陣列中所有大於0的座標,並以(x,y)的形式儲存在list裡面

y_loc, x_loc = np.where(mask_detect > 0)
localtion = map(lambda x, y: [x, y], x_loc, y_loc)#返回的是map object at 0x000002EB3C7E4080 需要轉list
localtion_list = list(localtion)

我跑出的結果是三維陣列(多個檢測框的所有座標集合),然後將其轉換成二維的(將所有的檢測框當作一個),然後儲存到json檔案裡面例項

detect_info = detect.get_masks_coordinate(detect_detect_masks)#是[array1,array2]型別的,就是list裡面包含array陣列
json_name = img_name.split('.')[0]+'.json'
json_data = {'image_name':img_name}

if detects_info != None:# 將每個框分別畫在mask_detect上,一起畫結果不對
    for detect in detects_info:
        detect = detect.reshape(1, -1, 2)
        cv2.fillPoly(mask_detect, detect, 255)
y_loc, x_loc = np.where(mask_detect > 0) 
localtion = list(map(lambda x, y: [x, y], x_loc, y_loc))
detect_results = [{"class": "detect", "point_value": str(localtion)}]
json_data['detect_results'] = detect_results
if len(detects_info) > 0:
    print('json_name: ',json_name)
    with open('../data/json/%s'%json_name,'w') as f:
        json.dump(json_data,f)

 

相關文章