Allen Cell Discussion Forum

Segmentation, clear_border

Hi,
I am trying to use the Allen Cell Structure Segmenter on some slide images. The segmenter works and I am able to navigate it fairly well. I am trying to add in a scikit image function ‘clear_border’ in order to remove objects on the edge of the image. In previous code this was coupled with ‘label_image’ from scikit. I have tried a couple configurations, using one or both, moving it to various points in the code. But nothing seems to give me the output I am looking for. The typical outcome is that if I can get it to work it just clears the entire image.

Any ideas how I could fix this issue or use another function to do a similar operation?

I would be more than happy to help. First of all, I would like to know which code are you trying to modify? A specific jupyter notebook? Or a specific structure wrapper for batch processing?

Hi Jianxu,
I was using the ‘playground_npm1.ipynb’ jupyter notebook. A coworker, Nathan, figured out that if I add dimensions and and use np.zeros_like() it seems to fix the problem.
So this was the bit of code we added:

cleared = clear_border(seg[0, :, :])
cb = np.zeros_like(seg)
cb[0, :, :] = cleared

I would be curious about your solutions and thoughts as well.

Is your image 2D or 3D?

It is a 2D image

I see. In theory, our algorithms should be applicable to both 2D and 3D images. But the default settings, e.g, the pre-set jupyter notebooks, are made with the assumption of 3D images. So, when you use the current version of our segmenter on 2D images, you may have to make some tweaks like what you have already done above. I am glad you worked it out :slight_smile:

Regarding your quesiton about clearing borders, the clear_border() function is a good one. In some situation, i want to not only clear all the objects touching the border, but also all objects that are less than K pixels away from the border. I would use the following code:

# suppose bw is your binary segmentation
K=4
bw_label = label(bw, connectivity=1)

boundary_mask = np.zeros_like(bw)
boundary_mask[:, :K, :] = 1
boundary_mask[:,-K:, :] = 1
boundary_mask[:, :, :K] = 1
boundary_mask[:, :,-K:] = 1

bd_idx = list(np.unique(bw_label[boundary_mask>0]))
for index, cid in enumerate(bd_idx):
    if cid>0:
        # you may also add other criteria here, e.g. size < 100, etc.
        bw_label [bw_label==cid]=0

This will give you lots of flexibity to make a “more careful” border clearing.

That works beautifully. Thanks Jianxu.