-
Notifications
You must be signed in to change notification settings - Fork 0
/
evaluate.py
68 lines (55 loc) · 2.31 KB
/
evaluate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#损失与评价指标
import torch.nn as nn
import numpy as np
import cv2
def IoU(predict,mask): #均交并比计算
predict = predict > 0.5
mask = mask > 0.5
n = predict.size(0)
predict = predict.view(n,-1)
mask = mask.view(n,-1)
intersection1 = (predict & mask).sum(1) #前景交并比
union1 = (predict | mask).sum(1)
intersection0 = (~predict & ~mask).sum(1) #背景交并比
union0 = (~predict | ~mask).sum(1)
iou = (intersection1 / union1 + intersection0 / union0)*0.5 #均交并比
return iou.sum()
def get_boundary(mask,dilation_ratio=0.02): #通过腐蚀获取实例边界,dilation_ratio腐蚀率与边界大小有关
mask = mask.data.numpy()
mask = mask > 0.5
mask = mask.astype('uint8')
b,h,w = mask.shape
new_mask = np.zeros([b,h+2,w+2])
for i in range(b):
new_mask[i] = cv2.copyMakeBorder(mask[i], 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0) # 扩展边框
r = np.sqrt(h**2+w**2) #图像对角线长
dilation = round(dilation_ratio*r) #腐蚀程度最小为1
if dilation<1:
dilation = 1
#腐蚀边界,得到腐蚀后图像,相减得到边界图像
erode_mask = np.zeros([b,h,w])
kernel = np.ones((3,3),dtype=np.uint8)
for i in range(b):
tmp = cv2.erode(src=new_mask[i],kernel=kernel,iterations=dilation)
erode_mask[i] = tmp[1:h+1,1:w+1]
return mask-erode_mask
def boundary_iou(predict,mask): #计算边界交并比
pre_boundary = get_boundary(predict.squeeze(1))
mask_boundary = get_boundary(mask)
b,h,w = mask_boundary.shape
biou = 0
for i in range(b):
intersection = ((pre_boundary[i]*mask_boundary[i])>0).sum()
union = ((pre_boundary[i]+mask_boundary[i])>0).sum()
biou += intersection/union
return biou
def Myloss(predict,mask,alpha=0.5,gammma=2): #两部分组成,一部分为交叉熵,一部分为Dice损失
n = predict.size(0)
smooth = 1e-5
temp_predict = predict.view(n,-1)
temp_mask = mask.view(n,-1)
bce_loss = nn.BCELoss()(temp_predict,temp_mask)
intersection = temp_predict*temp_mask
dice = (2.*intersection.sum(1)+smooth)/(temp_predict.sum(1)+temp_mask.sum(1)+smooth)
dice_loss = 1 - dice.mean()
return bce_loss + dice_loss