79597405

Date: 2025-04-28 23:52:13
Score: 0.5
Natty:
Report link

After some experimentation, it seems that binary_closing is the best helper. And it is important to vary the structure, to avoid artifacts with "square corners"

import scipy.ndimage as nd

bones = img_data > args.threshold
n = 5
for t in range(2):
    nd.binary_closing(bones, iterations=1, output=bones, structure=np.ones((n,n,n)))
    nd.binary_closing(bones, iterations=1, output=bones)
nd.binary_opening(bones, iterations=1, output=bones)

bone_labels, num_feat = nd.label(bones)
vals, counts = np.unique(bone_labels, return_counts=True)
vals = vals[1:]
counts = counts[1:]
print('begin erase small labels')
for i,value in enumerate(vals):
    if counts[i] < args.min_size:
        bones[bone_labels == value] = False

The bones is a binary mask. The last part labels all components and then aggressively deletes the small ones. The min_size is 1500 in my case.

Reasons:
  • Long answer (-0.5):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: John Henckel