如何只提取核磁共振图像中心的大脑部分?
How to extract only brain part in center in MRI image?
我有大脑的 MRI 图像。我需要从 MRI 中移除颅骨(头骨),然后裁剪大脑周围的背景区域。我如何在 python 中使用图像处理来做到这一点?。我试过使用 openCV
这是我试过的代码:
def crop_brain_contour(image, plot=False):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU)
ret, markers = cv2.connectedComponents(thresh)
marker_area = [np.sum(markers==m) for m in range(np.max(markers)) if m!=0]
largest_component = np.argmax(marker_area)+1
brain_mask = markers==largest_component
brain_out = image.copy()
brain_out[brain_mask==False] = (0,0,0)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# extreme points
extLeft = tuple(c[c[:, :, 0].argmin()][0])
extRight = tuple(c[c[:, :, 0].argmax()][0])
extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])
new_image = image[extTop[1]:extBot[1], extLeft[0]:extRight[0]]
return new_image
这些图片与我需要的相似:
当我运行这个代码我得到这个图像
感谢您的帮助!!
这是 Python/OpenCV 中的一种方法。
- Read the input
- Convert to grayscale
- Threshold
- Apply morphology close
- Get the largest contour
- Draw the largest contour as white filled on a black background as a mask
- OPTIONALLY: erode the mask
- Get the dimensions of the contour (after optional eroding)
- Crop the input image and mask to those dimensions
- Put the mask into the alpha channel of the image to make the outside transparent
- Save the results
import cv2
import numpy as np
# load image
img = cv2.imread('mri.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# apply morphology
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# get external contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
# draw white filled contour on black background as mask
mask = np.zeros_like(thresh, dtype=np.uint8)
cv2.drawContours(mask, [big_contour], 0, 255, -1)
# get bounds of contour
x,y,w,h = cv2.boundingRect(big_contour)
# crop image and mask
img_crop = img[y:y+h, x:x+w]
mask_crop = mask[y:y+h, x:x+w]
# put mask in alpha channel of image
result = cv2.cvtColor(img_crop, cv2.COLOR_BGR2BGRA)
result[:,:,3] = mask_crop
# save resulting masked image
cv2.imwrite('mri_thresh.png', thresh)
cv2.imwrite('mri_cropped.png', img_crop)
cv2.imwrite('mri_cropped_alpha.png', result)
# ALTERNATE ERODE mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh2 = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
# get external contour
contours2 = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours2 = contours2[0] if len(contours2) == 2 else contours2[1]
big_contour2 = max(contours2, key=cv2.contourArea)
# draw white filled contour on black background as mask
mask2 = np.zeros_like(thresh2, dtype=np.uint8)
cv2.drawContours(mask2, [big_contour2], 0, 255, -1)
# get bounds of contour
x,y,w,h = cv2.boundingRect(big_contour2)
# crop image and mask
img_crop2 = img[y:y+h, x:x+w]
mask_crop2 = mask2[y:y+h, x:x+w]
# put mask in alpha channel of image
result2 = cv2.cvtColor(img_crop2, cv2.COLOR_BGR2BGRA)
result2[:,:,3] = mask_crop2
# save results
cv2.imwrite("mri_thresh.png", thresh)
cv2.imwrite("mri_cropped.png", img_crop)
cv2.imwrite("mri_cropped_alpha.png", result)
cv2.imwrite("mri_thresh2.png", thresh2)
cv2.imwrite("mri_cropped2.png", img_crop2)
cv2.imwrite("mri_cropped_alpha2.png", result2)
# display result
cv2.imshow("thresh", thresh)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.imshow("thresh2", thresh2)
cv2.imshow("mask2", mask2)
cv2.imshow("result2", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
输入:
阈值图像:
蒙版图片:
简单裁剪图像:
带 alpha 通道的裁剪图像:
带有可选侵蚀的 alpha 通道的裁剪图像:
我有大脑的 MRI 图像。我需要从 MRI 中移除颅骨(头骨),然后裁剪大脑周围的背景区域。我如何在 python 中使用图像处理来做到这一点?。我试过使用 openCV
这是我试过的代码:
def crop_brain_contour(image, plot=False):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU)
ret, markers = cv2.connectedComponents(thresh)
marker_area = [np.sum(markers==m) for m in range(np.max(markers)) if m!=0]
largest_component = np.argmax(marker_area)+1
brain_mask = markers==largest_component
brain_out = image.copy()
brain_out[brain_mask==False] = (0,0,0)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# extreme points
extLeft = tuple(c[c[:, :, 0].argmin()][0])
extRight = tuple(c[c[:, :, 0].argmax()][0])
extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])
new_image = image[extTop[1]:extBot[1], extLeft[0]:extRight[0]]
return new_image
这些图片与我需要的相似:
当我运行这个代码我得到这个图像
感谢您的帮助!!
这是 Python/OpenCV 中的一种方法。
- Read the input
- Convert to grayscale
- Threshold
- Apply morphology close
- Get the largest contour
- Draw the largest contour as white filled on a black background as a mask
- OPTIONALLY: erode the mask
- Get the dimensions of the contour (after optional eroding)
- Crop the input image and mask to those dimensions
- Put the mask into the alpha channel of the image to make the outside transparent
- Save the results
import cv2
import numpy as np
# load image
img = cv2.imread('mri.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# apply morphology
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# get external contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
# draw white filled contour on black background as mask
mask = np.zeros_like(thresh, dtype=np.uint8)
cv2.drawContours(mask, [big_contour], 0, 255, -1)
# get bounds of contour
x,y,w,h = cv2.boundingRect(big_contour)
# crop image and mask
img_crop = img[y:y+h, x:x+w]
mask_crop = mask[y:y+h, x:x+w]
# put mask in alpha channel of image
result = cv2.cvtColor(img_crop, cv2.COLOR_BGR2BGRA)
result[:,:,3] = mask_crop
# save resulting masked image
cv2.imwrite('mri_thresh.png', thresh)
cv2.imwrite('mri_cropped.png', img_crop)
cv2.imwrite('mri_cropped_alpha.png', result)
# ALTERNATE ERODE mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh2 = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
# get external contour
contours2 = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours2 = contours2[0] if len(contours2) == 2 else contours2[1]
big_contour2 = max(contours2, key=cv2.contourArea)
# draw white filled contour on black background as mask
mask2 = np.zeros_like(thresh2, dtype=np.uint8)
cv2.drawContours(mask2, [big_contour2], 0, 255, -1)
# get bounds of contour
x,y,w,h = cv2.boundingRect(big_contour2)
# crop image and mask
img_crop2 = img[y:y+h, x:x+w]
mask_crop2 = mask2[y:y+h, x:x+w]
# put mask in alpha channel of image
result2 = cv2.cvtColor(img_crop2, cv2.COLOR_BGR2BGRA)
result2[:,:,3] = mask_crop2
# save results
cv2.imwrite("mri_thresh.png", thresh)
cv2.imwrite("mri_cropped.png", img_crop)
cv2.imwrite("mri_cropped_alpha.png", result)
cv2.imwrite("mri_thresh2.png", thresh2)
cv2.imwrite("mri_cropped2.png", img_crop2)
cv2.imwrite("mri_cropped_alpha2.png", result2)
# display result
cv2.imshow("thresh", thresh)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.imshow("thresh2", thresh2)
cv2.imshow("mask2", mask2)
cv2.imshow("result2", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
输入:
阈值图像:
蒙版图片:
简单裁剪图像:
带 alpha 通道的裁剪图像:
带有可选侵蚀的 alpha 通道的裁剪图像: