refactor: remove_small_objects用Otsu替代中位数25%

对连通域面积分布做Otsu自动找分界,不再拍脑袋定百分比
This commit is contained in:
2026-05-08 15:31:47 +08:00
parent b07e7a1182
commit 1041a66270
4 changed files with 57 additions and 17 deletions
+10 -3
View File
@@ -72,11 +72,18 @@ def keep_largest_object(binary):
def remove_small_objects(binary):
L, n = ndimage.label(binary)
if n == 0: return binary
areas = [int(np.sum(L==i)) for i in range(1,n+1)]
minsz = max(1, int(np.median(areas)*0.25))
areas = np.array([int(np.sum(L==i)) for i in range(1,n+1)])
if len(areas) < 2: return binary
best_T, best_cost, n_total = 0, float('inf'), len(areas)
for T in np.unique(areas):
s, l = areas[areas<=T], areas[areas>T]
w_s, w_l = len(s)/n_total, len(l)/n_total
if w_s==0 or w_l==0: continue
cost = w_s*np.var(s) + w_l*np.var(l)
if cost < best_cost: best_cost, best_T = cost, T
r = binary.copy()
for i in range(1, n+1):
if areas[i-1] < minsz: r[L==i] = 0
if int(np.sum(L==i)) < best_T: r[L==i] = 0
return r