Skip to content

Instantly share code, notes, and snippets.

@hanspinckaers
Last active August 29, 2019 08:34
Show Gist options
  • Save hanspinckaers/281fe48b8a9bfad3f873f21041ffc600 to your computer and use it in GitHub Desktop.
Save hanspinckaers/281fe48b8a9bfad3f873f21041ffc600 to your computer and use it in GitHub Desktop.
Metrics of GlaS challenge in python
import numpy as np
from scipy import stats
from sklearn.neighbors import NearestNeighbors
def ObjectHausdorff(S=None, G=None):
S = np.array(S).astype(np.uint8)
G = np.array(G).astype(np.uint8)
totalAreaS = (S > 0).sum()
totalAreaG = (G > 0).sum()
listLabelS = np.unique(S)
listLabelS = np.delete(listLabelS, np.where(listLabelS == 0))
listLabelG = np.unique(G)
listLabelG = np.delete(listLabelG, np.where(listLabelG == 0))
temp1 = 0
for iLabelS in range(len(listLabelS)):
Si = (S == listLabelS[iLabelS])
intersectlist = G[Si]
if intersectlist.any():
indexGi = stats.mode(intersectlist).mode
Gi = (G == indexGi)
else:
tempDist = np.zeros((len(listLabelG), 1))
for iLabelG in range(len(listLabelG)):
Gi = (G == listLabelG[iLabelG])
tempDist[iLabelG] = Hausdorff(Gi, Si)
minIdx = np.argmin(tempDist)
Gi = (G == listLabelG[minIdx])
omegai = Si.sum() / totalAreaS
temp1 = temp1 + omegai * Hausdorff(Gi, Si)
temp2 = 0
for iLabelG in range(len(listLabelG)):
tildeGi = (G == listLabelG[iLabelG])
intersectlist = S[tildeGi]
if intersectlist.any():
indextildeSi = stats.mode(intersectlist).mode
tildeSi = (S == indextildeSi)
else:
tempDist = np.zeros((len(listLabelS), 1))
for iLabelS in range(len(listLabelS)):
tildeSi = (S == listLabelS[iLabelS])
tempDist[iLabelS] = Hausdorff(tildeGi, tildeSi)
minIdx = np.argmin(tempDist)
tildeSi = (S == listLabelS[minIdx])
tildeOmegai = tildeGi.sum() / totalAreaG
temp2 = temp2 + tildeOmegai * Hausdorff(tildeGi, tildeSi)
objHausdorff = (temp1 + temp2) / 2
return objHausdorff
def Hausdorff(S=None, G=None):
S = np.array(S).astype(np.uint8)
G = np.array(G).astype(np.uint8)
listS = np.unique(S)
listS = np.delete(listS, np.where(listS == 0))
listG = np.unique(G)
listG = np.delete(listG, np.where(listG == 0))
numS = len(listS)
numG = len(listG)
if numS == 0 and numG == 0:
hausdorffDistance = 0
return hausdorffDistance
else:
if numS == 0 or numG == 0:
hausdorffDistance = np.Inf
return hausdorffDistance
y = np.where(S > 0)
x = np.where(G > 0)
x = np.vstack((x[0], x[1])).transpose()
y = np.vstack((y[0], y[1])).transpose()
nbrs = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(x)
distances, indices = nbrs.kneighbors(y)
dist1 = np.max(distances)
nbrs = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(y)
distances, indices = nbrs.kneighbors(x)
dist2 = np.max(distances)
hausdorffDistance = np.max((dist1, dist2))
return hausdorffDistance
def F1score(S=None, G=None):
S = np.array(S).astype(np.uint8)
G = np.array(G).astype(np.uint8)
listS = np.unique(S)
listS = np.delete(listS, np.where(listS == 0))
numS = len(listS)
listG = np.unique(G)
listG = np.delete(listG, np.where(listG == 0))
numG = len(listG)
if numS == 0 and numG == 0:
return 1
elif numS == 0 or numG == 0:
return 0
tempMat = np.zeros((numS, 3))
tempMat[:, 0] = listS
for iSegmentedObj in range(numS):
intersectGTObjs = G[S == tempMat[iSegmentedObj, 0]]
if intersectGTObjs.any():
intersectGTObjs_flat = np.delete(intersectGTObjs.flatten(),
np.where(intersectGTObjs.flatten() == 0))
if len(intersectGTObjs_flat) == 0: maxGTi = 0
else: maxGTi = stats.mode(intersectGTObjs_flat).mode
tempMat[iSegmentedObj, 1] = maxGTi
for iSegmentedObj in range(numS):
if tempMat[iSegmentedObj, 1] != 0:
SegObj = (S == tempMat[iSegmentedObj, 0])
GTObj = (G == tempMat[iSegmentedObj, 1])
overlap = np.logical_and(SegObj, GTObj)
areaOverlap = overlap.sum()
areaGTObj = GTObj.sum()
if areaOverlap / areaGTObj > 0.5:
tempMat[iSegmentedObj, 2] = 1
TP = (tempMat[:, 2] == 1).sum()
FP = (tempMat[:, 2] == 0).sum()
FN = numG - TP
precision = TP / (TP + FP)
recall = TP / (TP + FN)
if precision + recall == 0:
return 0
score = (2 * precision * recall) / (precision + recall)
return score
def ObjectDice(S, G):
S = np.array(S).astype(np.uint8)
G = np.array(G).astype(np.uint8)
totalAreaG = (G > 0).sum()
listLabelS = np.unique(S)
listLabelS = np.delete(listLabelS, np.where(listLabelS == 0))
numS = len(listLabelS)
listLabelG = np.unique(G)
listLabelG = np.delete(listLabelG, np.where(listLabelG == 0))
numG = len(listLabelG)
if numS == 0 and numG == 0:
return 1
elif numS == 0 or numG == 0:
return 0
temp1 = 0
totalAreaS = (S > 0).sum()
for iLabelS in range(len(listLabelS)):
Si = (S == listLabelS[iLabelS])
intersectlist = G[Si]
if intersectlist.any():
indexG1 = stats.mode(intersectlist).mode
Gi = (G == indexG1)
else:
Gi = np.zeros(G.shape)
omegai = Si.sum() / totalAreaS
temp1 += omegai * Dice(Gi, Si)
temp2 = 0
totalAreaG = (G > 0).sum()
for iLabelG in range(len(listLabelG)):
tildeGi = (G == listLabelG[iLabelG])
intersectlist = S[tildeGi]
if intersectlist.any():
indextildeSi = stats.mode(intersectlist).mode
tildeSi = (S == indextildeSi)
else:
tildeSi = np.zeros(S.shape)
tildeOmegai = tildeGi.sum() / totalAreaG
temp2 += tildeOmegai * Dice(tildeGi, tildeSi)
return (temp1 + temp2) / 2
def Dice(A, B):
intersection = np.logical_and(A, B)
return 2. * intersection.sum() / (A.sum() + B.sum())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment