refactor: remove_small_objects用Otsu替代中位数25%
对连通域面积分布做Otsu自动找分界,不再拍脑袋定百分比
This commit is contained in:
+10
-3
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user