import cv2 import numpy as np def clean(m, amin=30): n, cc, st, _ = cv2.connectedComponentsWithStats(m.astype(np.uint8), 8) keep = np.zeros(n, bool); keep[1:] = st[1:, cv2.CC_STAT_AREA] >= amin return keep[cc] def score(prob, gts): k3 = np.ones((3, 3), np.uint8); tp = fp = fn = tn = 0; shp = [] for p, g in zip(prob, gts): pm = clean(p > 0.5); pp, gp = pm.sum() >= 20, g.sum() >= 20 tp += pp and gp; fp += pp and not gp; fn += gp and not pp; tn += (not pp) and (not gp) if gp: if not pp: shp.append(0.0); continue gd = cv2.dilate(g.astype(np.uint8), k3).astype(bool); pd = cv2.dilate(pm.astype(np.uint8), k3).astype(bool) pr = (pm & gd).sum() / pm.sum(); rc = (g & pd).sum() / g.sum() shp.append(2 * pr * rc / (pr + rc + 1e-9)) f1p = 2 * tp / max(2 * tp + fp + fn, 1); f1n = 2 * tn / max(2 * tn + fn + fp, 1) return 0.5 * (f1p + f1n) / 2 + 0.5 * (float(np.mean(shp)) if shp else 0.0), (tp, fp, fn, tn)