How to leave only the largest blob in an image?
Asked Answered
A

2

10

I have a binary image of a brain. I only want to leave the blob in the center and remove the surrounding "noise" that is in this circular looking shape.

Here's an example image:

brain mr

I tried using OpenCV and getting countours, but that failed miserably. I also don't need a bounding rectangle box, at all, I just want to leave the center blob in the image, as it looks in the image I provided, and remove the surrounding noise/circle. Is this possible?

Anabolite answered 13/6, 2019 at 23:26 Comment(1)
Could you provide an example output image?Scorpio
A
13

I assume, you want to keep the actual brain ("blob in the center") and get rid of the skull ("noise circular looking shape").

Unfortunately, you didn't show any code, so I'm not sure, what failed for you in using contours, but here's my suggestion:

import cv2
import numpy as np

# Read input
img = cv2.imread('images/t6igVVk.png', cv2.IMREAD_GRAYSCALE)

# Generate intermediate image; use morphological closing to keep parts of the brain together
inter = cv2.morphologyEx(img, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))

# Find largest contour in intermediate image
cnts, _ = cv2.findContours(inter, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnt = max(cnts, key=cv2.contourArea)

# Output
out = np.zeros(img.shape, np.uint8)
cv2.drawContours(out, [cnt], -1, 255, cv2.FILLED)
out = cv2.bitwise_and(img, out)

cv2.imshow('img', img)
cv2.imshow('inter', inter)
cv2.imshow('out', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

The final output out.png looks like this:

Output

I do some morphological closing (morphologyEx, getStructuringElement) on the input image to keep the actual parts of the brain together. On that intermediate image, I look for the largest contour. In my findContours call, I use theRETR_EXTERNAL mode to only get all "external contours". That means, when later drawing this contour, it'll be also filled in the middle (i.e. the lateral ventricles). So, finally I just use a bitwise_and on both images to fix that. That also fixes the too large parts from the intermediate image as well.

Hope that helps!

Andrien answered 14/6, 2019 at 4:37 Comment(0)
U
4

By using cv2.morphologyEx I was loosing a lot of details from my binary image. I am using the following code to just keep the largest white area of an image -

import skimage
from skimage import measure

labels_mask = measure.label(input_mask)                       
regions = measure.regionprops(labels_mask)
regions.sort(key=lambda x: x.area, reverse=True)
if len(regions) > 1:
    for rg in regions[1:]:
        labels_mask[rg.coords[:,0], rg.coords[:,1]] = 0
labels_mask[labels_mask!=0] = 1
mask = labels_mask

Input image:

enter image description here

Output image:

enter image description here

Undine answered 1/3, 2020 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.