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:
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?
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:
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!
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:
Output image:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With