【函数解析】腐蚀与膨胀操作 skimage.morphology.dilation / erosion
腐蚀
腐蚀的效果是把图片变瘦,其原理是在原图的小区域内取局部最小值。用kernel
遍历原图的所有像素,每遍历一次就将对应位置的像素点更改为kernel
中的最小值。
膨胀
腐蚀的效果是把图片变胖,其原理是在原图的小区域内取局部最大值。用kernel
遍历原图的所有像素,每遍历一次就将对应位置的像素点更改为kernel
中的最大值。
函数解析
skimage.morphology.dilation
解析:
def dilation(image, footprint=None, out=None, shift_x=False, shift_y=False):"""Return grayscale morphological dilation of an image.Morphological dilation sets the value of a pixel to the maximum over allpixel values within a local neighborhood centered about it. The valueswhere the footprint is 1 define this neighborhood.Dilation enlarges bright regions and shrinks dark regions.Parameters----------image : ndarrayImage array.footprint : ndarray or tuple, optionalThe neighborhood expressed as a 2-D array of 1's and 0's.If None, use a cross-shaped footprint (connectivity=1). The footprintcan also be provided as a sequence of smaller footprints as describedin the notes below.out : ndarray, optionalThe array to store the result of the morphology. If None ispassed, a new array will be allocated.shift_x, shift_y : bool, optionalShift footprint about center point. This only affects 2Deccentric footprints (i.e., footprints with even-numberedsides).Returns-------dilated : uint8 array, same shape and type as `image`The result of the morphological dilation.Notes-----For `uint8` (and `uint16` up to a certain bit-depth) data, the loweralgorithm complexity makes the `skimage.filters.rank.maximum` function moreefficient for larger images and footprints.The footprint can also be a provided as a sequence of 2-tuples where thefirst element of each 2-tuple is a footprint ndarray and the second elementis an integer describing the number of times it should be iterated. Forexample ``footprint=[(np.ones((9, 1)), 1), (np.ones((1, 9)), 1)]``would apply a 9x1 footprint followed by a 1x9 footprint resulting in a neteffect that is the same as ``footprint=np.ones((9, 9))``, but with lowercomputational cost. Most of the builtin footprints such as``skimage.morphology.disk`` provide an option to automatically generate afootprint sequence of this type.Examples-------->>> # Dilation enlarges bright regions>>> import numpy as np>>> from skimage.morphology import square>>> bright_pixel = np.array([[0, 0, 0, 0, 0],... [0, 0, 0, 0, 0],... [0, 0, 1, 0, 0],... [0, 0, 0, 0, 0],... [0, 0, 0, 0, 0]], dtype=np.uint8)>>> dilation(bright_pixel, square(3))array([[0, 0, 0, 0, 0],[0, 1, 1, 1, 0],[0, 1, 1, 1, 0],[0, 1, 1, 1, 0],[0, 0, 0, 0, 0]], dtype=uint8)"""
参数:
image
:输入图像footprint
:kernel大小
例子:
import SimpleITK as sitk
import os
import numpy as np
from skimage.morphology import dilation, square, erosion
import matplotlib.pyplot as plt
import cv2def adjust_window(image, window_level=35, window_width=85):# 计算窗宽和窗位的最小和最大值min_value = window_level - window_width // 2max_value = window_level + window_width // 2# 将图像裁剪到指定的窗宽范围内windowed_image = np.clip(image, min_value, max_value)# 归一化图像到0-255范围windowed_image = ((windowed_image - min_value) / (max_value - min_value) * 255).astype(np.uint8)return windowed_imageich_mask_path = r"C:\Users\CodeCat\Desktop\server_test\ID_c9d6fdc6_ID_7f09be285d-ich_pred.nii.gz"
img_path = r"C:\Users\CodeCat\Desktop\server_test\ID_c9d6fdc6_ID_7f09be285d.nii.gz"
edema_mask_path = r"C:\Users\CodeCat\Desktop\server_test\ID_c9d6fdc6_ID_7f09be285d-edema_pred.nii.gz"
ich_mask = sitk.ReadImage(ich_mask_path)
ich_mask_array = sitk.GetArrayFromImage(ich_mask)
ich_mask_array = np.where(ich_mask_array > 0, 1, 0)
img = sitk.ReadImage(img_path)
img_array = sitk.GetArrayFromImage(img)
img_array = adjust_window(img_array)
edema_mask = sitk.ReadImage(edema_mask_path)
edema_mask_array = sitk.GetArrayFromImage(edema_mask)
edema_mask_array = np.where(ich_mask_array > 0, 0, edema_mask_array)slice_idx = 26
img = img_array[slice_idx, :, :]
ich = ich_mask_array[slice_idx, :, :]
edema = edema_mask_array[slice_idx, :, :]plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.title("Original image")
plt.imshow(img, cmap='gray')
plt.xticks([])
plt.yticks([])plt.subplot(1, 3, 2)
plt.title("ICH Mask")
plt.imshow(img, cmap='gray')
ich_rgb = np.zeros((img_array.shape[1], img_array.shape[2], 3))
ich_rgb[ich > 0] = [255, 0, 0]
edema_rgb = np.zeros((img_array.shape[1], img_array.shape[2], 3))
edema_rgb[edema > 0] = [0, 255, 0]
plt.imshow(ich_rgb, alpha=0.2)
plt.xticks([])
plt.yticks([])pixels = 9
dilation_size = 2 * pixels + 1
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dilation_size, dilation_size))
plt.subplot(1, 3, 3)
plt.title(f"ICH Dilated Mask")
# 膨胀操作
ich_dilated = dilation(ich, square(dilation_size))
ich_rgb_dilated = np.zeros((img_array.shape[1], img_array.shape[2], 3))
ich_rgb_dilated[ich_dilated > 0] = [255, 0, 0]
edema_rgb_dilated = np.zeros((img_array.shape[1], img_array.shape[2], 3))
edema_rgb_dilated[edema > 0] = [0, 255, 0]plt.imshow(img, cmap='gray')
plt.imshow(ich_rgb_dilated, alpha=0.2)
plt.xticks([])
plt.yticks([])
plt.show()
skimage.morphology.erosion
解析
def erosion(image, footprint=None, out=None, shift_x=False, shift_y=False):"""Return grayscale morphological erosion of an image.Morphological erosion sets a pixel at (i,j) to the minimum over all pixelsin the neighborhood centered at (i,j). Erosion shrinks bright regions andenlarges dark regions.Parameters----------image : ndarrayImage array.footprint : ndarray or tuple, optionalThe neighborhood expressed as a 2-D array of 1's and 0's.If None, use a cross-shaped footprint (connectivity=1). The footprintcan also be provided as a sequence of smaller footprints as describedin the notes below.out : ndarrays, optionalThe array to store the result of the morphology. If None ispassed, a new array will be allocated.shift_x, shift_y : bool, optionalshift footprint about center point. This only affectseccentric footprints (i.e. footprint with even numberedsides).Returns-------eroded : array, same shape as `image`The result of the morphological erosion.Notes-----For ``uint8`` (and ``uint16`` up to a certain bit-depth) data, thelower algorithm complexity makes the `skimage.filters.rank.minimum`function more efficient for larger images and footprints.The footprint can also be a provided as a sequence of 2-tuples where thefirst element of each 2-tuple is a footprint ndarray and the second elementis an integer describing the number of times it should be iterated. Forexample ``footprint=[(np.ones((9, 1)), 1), (np.ones((1, 9)), 1)]``would apply a 9x1 footprint followed by a 1x9 footprint resulting in a neteffect that is the same as ``footprint=np.ones((9, 9))``, but with lowercomputational cost. Most of the builtin footprints such as``skimage.morphology.disk`` provide an option to automatically generate afootprint sequence of this type.Examples-------->>> # Erosion shrinks bright regions>>> import numpy as np>>> from skimage.morphology import square>>> bright_square = np.array([[0, 0, 0, 0, 0],... [0, 1, 1, 1, 0],... [0, 1, 1, 1, 0],... [0, 1, 1, 1, 0],... [0, 0, 0, 0, 0]], dtype=np.uint8)>>> erosion(bright_square, square(3))array([[0, 0, 0, 0, 0],[0, 0, 0, 0, 0],[0, 0, 1, 0, 0],[0, 0, 0, 0, 0],[0, 0, 0, 0, 0]], dtype=uint8)"""
参数:
image
:输入图像footprint
:kernel大小
例子:
import SimpleITK as sitk
import os
import numpy as np
from skimage.morphology import dilation, square, erosion
import matplotlib.pyplot as plt
import cv2def adjust_window(image, window_level=35, window_width=85):# 计算窗宽和窗位的最小和最大值min_value = window_level - window_width // 2max_value = window_level + window_width // 2# 将图像裁剪到指定的窗宽范围内windowed_image = np.clip(image, min_value, max_value)# 归一化图像到0-255范围windowed_image = ((windowed_image - min_value) / (max_value - min_value) * 255).astype(np.uint8)return windowed_imageich_mask_path = r"C:\Users\CodeCat\Desktop\server_test\ID_c9d6fdc6_ID_7f09be285d-ich_pred.nii.gz"
img_path = r"C:\Users\CodeCat\Desktop\server_test\ID_c9d6fdc6_ID_7f09be285d.nii.gz"
edema_mask_path = r"C:\Users\CodeCat\Desktop\server_test\ID_c9d6fdc6_ID_7f09be285d-edema_pred.nii.gz"
ich_mask = sitk.ReadImage(ich_mask_path)
ich_mask_array = sitk.GetArrayFromImage(ich_mask)
ich_mask_array = np.where(ich_mask_array > 0, 1, 0)
img = sitk.ReadImage(img_path)
img_array = sitk.GetArrayFromImage(img)
img_array = adjust_window(img_array)
edema_mask = sitk.ReadImage(edema_mask_path)
edema_mask_array = sitk.GetArrayFromImage(edema_mask)
edema_mask_array = np.where(ich_mask_array > 0, 0, edema_mask_array)slice_idx = 26
img = img_array[slice_idx, :, :]
ich = ich_mask_array[slice_idx, :, :]
edema = edema_mask_array[slice_idx, :, :]plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.title("Original image")
plt.imshow(img, cmap='gray')
plt.xticks([])
plt.yticks([])plt.subplot(1, 3, 2)
plt.title("ICH Mask")
plt.imshow(img, cmap='gray')
ich_rgb = np.zeros((img_array.shape[1], img_array.shape[2], 3))
ich_rgb[ich > 0] = [255, 0, 0]
edema_rgb = np.zeros((img_array.shape[1], img_array.shape[2], 3))
edema_rgb[edema > 0] = [0, 255, 0]
plt.imshow(ich_rgb, alpha=0.2)
plt.xticks([])
plt.yticks([])pixels = 9
dilation_size = 2 * pixels + 1
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dilation_size, dilation_size))
plt.subplot(1, 3, 3)
plt.title(f"ICH Erosion Mask")
# 腐蚀操作
ich_dilated = erosion(ich, square(dilation_size))
ich_rgb_dilated = np.zeros((img_array.shape[1], img_array.shape[2], 3))
ich_rgb_dilated[ich_dilated > 0] = [255, 0, 0]
edema_rgb_dilated = np.zeros((img_array.shape[1], img_array.shape[2], 3))
edema_rgb_dilated[edema > 0] = [0, 255, 0]plt.imshow(img, cmap='gray')
plt.imshow(ich_rgb_dilated, alpha=0.2)
plt.xticks([])
plt.yticks([])
plt.show()
参考链接:
https://codec.wang/docs/opencv/basic/erode-and-dilate
https://blog.csdn.net/qq_43360420/article/details/125575488