refactor: 后处理min_size改为格子面积百分比,自适应不同分辨率

keep_largest_object: 格子面积的1%
remove_small_objects: 格子面积的2%
This commit is contained in:
2026-05-08 08:54:47 +08:00
parent 00836cd302
commit efc6704b14
+15 -7
View File
@@ -203,8 +203,9 @@ def gridding(gray: np.ndarray) -> tuple:
# 第四部分:后处理(参考choice.m, choosemaxobj.m
# ============================================================
def remove_small_objects(binary: np.ndarray, min_size: int = 20) -> np.ndarray:
"""去除面积小于min_size的连通域"""
def remove_small_objects(binary: np.ndarray, cell_area: int = 1225, pct: float = 0.02) -> np.ndarray:
"""去除面积小于 cell_area*pct 的连通域(pct默认2%"""
min_size = int(cell_area * pct)
labeled, num = ndimage.label(binary)
result = binary.copy()
for i in range(1, num + 1):
@@ -213,8 +214,9 @@ def remove_small_objects(binary: np.ndarray, min_size: int = 20) -> np.ndarray:
return result
def keep_largest_object(binary: np.ndarray, min_size: int = 20) -> np.ndarray:
"""只保留最大连通域"""
def keep_largest_object(binary: np.ndarray, cell_area: int = 1225, pct: float = 0.01) -> np.ndarray:
"""只保留最大连通域,若最大块面积 < cell_area*pct 则整块抹黑(pct默认1%"""
min_size = int(cell_area * pct)
labeled, num = ndimage.label(binary)
if num == 0:
return binary
@@ -373,6 +375,11 @@ def main() -> None:
# ---- 步骤3: 全图逐块分割(Otsu + TV去噪) ----
print("\n[步骤3] 全图逐块分割...")
# 计算每个格子的面积,用于自适应后处理阈值
cell_h = int(np.median(np.diff(y_grid))) if len(y_grid) > 1 else 35
cell_w = int(np.median(np.diff(x_grid))) if len(x_grid) > 1 else 35
cell_area = cell_h * cell_w
bw_full = np.zeros_like(gray)
if len(x_grid) >= 2 and len(y_grid) >= 2:
for i in range(len(y_grid) - 1):
@@ -396,11 +403,12 @@ def main() -> None:
bw_blk = (blk_denoised > T).astype(np.uint8)
except ValueError:
bw_blk = np.zeros(blk.shape, dtype=np.uint8)
# 后处理:保留最大连通域
bw_blk = keep_largest_object(bw_blk, min_size=8)
# 后处理:保留最大连通域(最小面积 = 格子面积的1%
bw_blk = keep_largest_object(bw_blk, cell_area=cell_area)
bw_full[r1:r2, c1:c2] = bw_blk
bw_full = remove_small_objects(bw_full, min_size=20)
# 全局去小连通域(最小面积 = 格子面积的2%)
bw_full = remove_small_objects(bw_full, cell_area=cell_area)
fig_full = plot_full_segmentation(gray, bw_full, "全图逐块Otsu分割结果")
fig_full.savefig(os.path.join(OUTPUT_DIR, 'result_full_segmentation.png'), dpi=150, bbox_inches='tight')