根据标签最大层面ROI提取原始图像区域(二)

今天要实现的任务还是提取肿瘤的感兴趣区域。

有两个文件,一个是nii的原始图像文件,一个是nii的标签文件。我们要实现的是:在标签文件上选出最大层面,然后把最大层面的ROI映射到原始图像区域,在原始图像上提裁剪出ROI区域,这次裁剪的方法和上期的不同,上次是将ROI的整个边界区域提取出来,插值到224*224。这次是在标签上找到勾画ROI的最多的那一层,找到这个ROI区域的中心点在整个图像的坐标,然后根据这个坐标在映射到原始图像上,向四周延申出224*224大小的图像。这就不能保证勾画的边界。

import os
import SimpleITK as sitk
import numpy as np

'''
这个脚本是根据ROI的中心坐标来映射到原图像上,裁剪出大小为224*224的图像,超出区域用0填充
如果需要保存上下共三个层面,中心点还是使用的最大层面ROI的中心坐标,因为往上往下一层可能没有勾画,就会报错
'''

label_path= r"C:\Users\Administrator\Desktop\Breast\benign_label\AN_YU_MEI-label.nii"
image_path = r"C:\Users\Administrator\Desktop\Breast\benign\DCE\AN_YU_MEI.nii"


# 找出勾画ROI数值最多的那一层
def max_index(label_array):
    # 遍历每张图片
    max_nonzero_pixels = 0
    max_nonzero_index = None

    for i in range(label_array.shape[0]):
        # 计算当前图片中非零像素的数量
        nonzero_pixels = np.count_nonzero(label_array[i])

        # 如果当前图片的非零像素数量比之前的最大值大,则更新最大值和对应的索引
        if nonzero_pixels > max_nonzero_pixels:
            max_nonzero_pixels = nonzero_pixels
            max_nonzero_index = i

    return max_nonzero_index

# 根据勾画的ROI,找到其中心坐标
def find_roi_center(max_label):
    # 找到所有 ROI 区域的索引
    indices = np.where(max_label == 1)
    # 计算中心点坐标
    center_x = int(np.round(np.mean(indices[0])))
    center_y = int(np.round(np.mean(indices[1])))
    return (center_x, center_y)

# 根据找到的中心点坐标,以此为中心,映射到原图上,向四周延申到224*224
def crop_roi(max_image, roi_center):
    # 计算裁剪区域的边界坐标
    x_min = max(0, roi_center[0] - 112)
    x_max = min(max_image.shape[0], roi_center[0] + 112)
    y_min = max(0, roi_center[1] - 112)
    y_max = min(max_image.shape[1], roi_center[1] + 112)

    # 创建一个空的224x224大小的数组,并用0填充
    cropped_image = np.zeros((224, 224))

    # 计算裁剪区域在目标数组中的位置
    cropped_x_min = max(0, 112 - (roi_center[0] - x_min))
    cropped_x_max = cropped_x_min + min(x_max - x_min, 224)
    cropped_y_min = max(0, 112 - (roi_center[1] - y_min))
    cropped_y_max = cropped_y_min + min(y_max - y_min, 224)

    # 将ROI区域复制到裁剪图像中
    cropped_image[cropped_x_min:cropped_x_max, cropped_y_min:cropped_y_max] = max_image[x_min:x_max, y_min:y_max]

    return cropped_image
# 读取标签和原始图像
image_label = sitk.ReadImage(label_path)
# 读取原始NII文件
image_origin = sitk.ReadImage(image_path)

# 转换为NumPy数组
origin_array = sitk.GetArrayFromImage(image_origin)
label_array = sitk.GetArrayFromImage(image_label)

# 提取像素值
origin_array = np.array([origin_array[i] for i in range(origin_array.shape[0])])
label_array = np.array([label_array[i] for i in range(label_array.shape[0])])
# 找到最大值的索引
max_index = max_index(label_array)
# 找出标签中勾画ROI最多的那张图像
max_image = origin_array[max_index]
max_label =label_array[max_index]
#找到ROI的中心点
roi_center = find_roi_center(max_label)
# 根据中心点坐标向四周延伸裁剪出224*224
cropped_image = crop_roi(max_image, roi_center)

print("裁剪后的图像:\n", cropped_image.shape)
print("ROI 中心点坐标:", roi_center)

如果需要保存三个层面则运行以下函数,这里使用了中间的那一层ROI的中心点作为三个层面的中心点坐标,因为有的ROI可能就勾画了一层两层,没有三层,这样代码就会报错

def three_image(max_index):
    max_label0 = label_array[max_index-1]
    max_label1 = label_array[max_index]
    max_label2 = label_array[max_index+1]

    max_image0 = origin_array[max_index-1]
    max_image1 = origin_array[max_index]
    max_image2 = origin_array[max_index+1]

    # 找到ROI的中心点
    #roi_center0 = find_roi_center(max_label0)
    roi_center1 = find_roi_center(max_label1)
    #roi_center2 = find_roi_center(max_label2)

    # 根据中心点坐标向四周延伸裁剪出224*224
    cropped_image0 = crop_roi(max_image0, roi_center1)
    cropped_image1 = crop_roi(max_image1, roi_center1)
    cropped_image2 = crop_roi(max_image2, roi_center1)

    # 将三个图像数组堆叠成一个新的数组
    stacked_images = np.stack((cropped_image0, cropped_image1, cropped_image2))

    return stacked_images

images = three_image(max_index)
print("保存了三个层面的图像:", images.shape )

全部代码

import os
import SimpleITK as sitk
import numpy as np

'''
这个脚本是根据ROI的中心坐标来映射到原图像上,裁剪出大小为224*224的图像,超出区域用0填充
如果需要保存上下共三个层面,中心点还是使用的最大层面ROI的中心坐标,因为往上往下一层可能没有勾画,就会报错
'''

label_path= r"C:\Users\Administrator\Desktop\Breast\benign_label\AN_YU_MEI-label.nii"
image_path = r"C:\Users\Administrator\Desktop\Breast\benign\DCE\AN_YU_MEI.nii"


# 找出勾画ROI数值最多的那一层
def max_index(label_array):
    # 遍历每张图片
    max_nonzero_pixels = 0
    max_nonzero_index = None

    for i in range(label_array.shape[0]):
        # 计算当前图片中非零像素的数量
        nonzero_pixels = np.count_nonzero(label_array[i])

        # 如果当前图片的非零像素数量比之前的最大值大,则更新最大值和对应的索引
        if nonzero_pixels > max_nonzero_pixels:
            max_nonzero_pixels = nonzero_pixels
            max_nonzero_index = i

    return max_nonzero_index

# 根据勾画的ROI,找到其中心坐标
def find_roi_center(max_label):
    # 找到所有 ROI 区域的索引
    indices = np.where(max_label == 1)
    # 计算中心点坐标
    center_x = int(np.round(np.mean(indices[0])))
    center_y = int(np.round(np.mean(indices[1])))
    return (center_x, center_y)

# 根据找到的中心点坐标,以此为中心,映射到原图上,向四周延申到224*224
def crop_roi(max_image, roi_center):
    # 计算裁剪区域的边界坐标
    x_min = max(0, roi_center[0] - 112)
    x_max = min(max_image.shape[0], roi_center[0] + 112)
    y_min = max(0, roi_center[1] - 112)
    y_max = min(max_image.shape[1], roi_center[1] + 112)

    # 创建一个空的224x224大小的数组,并用0填充
    cropped_image = np.zeros((224, 224))

    # 计算裁剪区域在目标数组中的位置
    cropped_x_min = max(0, 112 - (roi_center[0] - x_min))
    cropped_x_max = cropped_x_min + min(x_max - x_min, 224)
    cropped_y_min = max(0, 112 - (roi_center[1] - y_min))
    cropped_y_max = cropped_y_min + min(y_max - y_min, 224)

    # 将ROI区域复制到裁剪图像中
    cropped_image[cropped_x_min:cropped_x_max, cropped_y_min:cropped_y_max] = max_image[x_min:x_max, y_min:y_max]

    return cropped_image
# 读取标签和原始图像
image_label = sitk.ReadImage(label_path)
# 读取原始NII文件
image_origin = sitk.ReadImage(image_path)

# 转换为NumPy数组
origin_array = sitk.GetArrayFromImage(image_origin)
label_array = sitk.GetArrayFromImage(image_label)

# 提取像素值
origin_array = np.array([origin_array[i] for i in range(origin_array.shape[0])])
label_array = np.array([label_array[i] for i in range(label_array.shape[0])])
# 找到最大值的索引
max_index = max_index(label_array)
# 找出标签中勾画ROI最多的那张图像
max_image = origin_array[max_index]
max_label =label_array[max_index]
#找到ROI的中心点
roi_center = find_roi_center(max_label)
# 根据中心点坐标向四周延伸裁剪出224*224
cropped_image = crop_roi(max_image, roi_center)

print("裁剪后的图像:\n", cropped_image.shape)
print("ROI 中心点坐标:", roi_center)

def three_image(max_index):
    max_label0 = label_array[max_index-1]
    max_label1 = label_array[max_index]
    max_label2 = label_array[max_index+1]

    max_image0 = origin_array[max_index-1]
    max_image1 = origin_array[max_index]
    max_image2 = origin_array[max_index+1]

    # 找到ROI的中心点
    #roi_center0 = find_roi_center(max_label0)
    roi_center1 = find_roi_center(max_label1)
    #roi_center2 = find_roi_center(max_label2)

    # 根据中心点坐标向四周延伸裁剪出224*224
    cropped_image0 = crop_roi(max_image0, roi_center1)
    cropped_image1 = crop_roi(max_image1, roi_center1)
    cropped_image2 = crop_roi(max_image2, roi_center1)

    # 将三个图像数组堆叠成一个新的数组
    stacked_images = np.stack((cropped_image0, cropped_image1, cropped_image2))

    return stacked_images

images = three_image(max_index)
print("保存了三个层面的图像:", images.shape )

写成类的代码,添加了保存的文件

import os
import SimpleITK as sitk
import numpy as np

class ImageProcessor:
    def __init__(self, label_path, image_path):
        self.label_path = label_path
        self.image_path = image_path
        self.origin_array = None
        self.label_array = None
        self.max_index = None
        self.max_image = None
        self.max_label = None
        self.roi_center = None

    # 读取标签和原始图像
    def read_images(self):
        image_label = sitk.ReadImage(self.label_path)
        image_origin = sitk.ReadImage(self.image_path)

        # 转换为NumPy数组
        self.origin_array = sitk.GetArrayFromImage(image_origin)
        self.label_array = sitk.GetArrayFromImage(image_label)

        # 提取像素值
        self.origin_array = np.array([self.origin_array[i] for i in range(self.origin_array.shape[0])])
        self.label_array = np.array([self.label_array[i] for i in range(self.label_array.shape[0])])

    # 找出勾画ROI数值最多的那一层
    def find_max_index(self):
        # 遍历每张图片
        max_nonzero_pixels = 0
        max_nonzero_index = None

        for i in range(self.label_array.shape[0]):
            # 计算当前图片中非零像素的数量
            nonzero_pixels = np.count_nonzero(self.label_array[i])

            # 如果当前图片的非零像素数量比之前的最大值大,则更新最大值和对应的索引
            if nonzero_pixels > max_nonzero_pixels:
                max_nonzero_pixels = nonzero_pixels
                max_nonzero_index = i

        self.max_index = max_nonzero_index

    # 根据找到的中心点坐标,以此为中心,映射到原图上,向四周延伸到224*224
    def crop_roi(self):
        # 找出标签中勾画ROI最多的那张图像
        self.max_image = self.origin_array[self.max_index]
        self.max_label = self.label_array[self.max_index]

        #找到ROI的中心点
        self.roi_center = self.find_roi_center(self.max_label)

        # 根据中心点坐标向四周延伸裁剪出224*224
        cropped_image = self._crop_roi(self.max_image, self.roi_center)

        return cropped_image

    # 根据勾画的ROI,找到其中心坐标
    def find_roi_center(self, max_label):
        # 找到所有 ROI 区域的索引
        indices = np.where(max_label == 1)
        # 计算中心点坐标
        center_x = int(np.round(np.mean(indices[0])))
        center_y = int(np.round(np.mean(indices[1])))
        return (center_x, center_y)

    def _crop_roi(self, max_image, roi_center):
        # 计算裁剪区域的边界坐标
        x_min = max(0, roi_center[0] - 112)
        x_max = min(max_image.shape[0], roi_center[0] + 112)
        y_min = max(0, roi_center[1] - 112)
        y_max = min(max_image.shape[1], roi_center[1] + 112)

        # 创建一个空的224x224大小的数组,并用0填充
        cropped_image = np.zeros((224, 224))

        # 计算裁剪区域在目标数组中的位置
        cropped_x_min = max(0, 112 - (roi_center[0] - x_min))
        cropped_x_max = cropped_x_min + min(x_max - x_min, 224)
        cropped_y_min = max(0, 112 - (roi_center[1] - y_min))
        cropped_y_max = cropped_y_min + min(y_max - y_min, 224)

        # 将ROI区域复制到裁剪图像中
        cropped_image[cropped_x_min:cropped_x_max, cropped_y_min:cropped_y_max] = max_image[x_min:x_max, y_min:y_max]

        return cropped_image

    # 保存裁剪后的图像
    def save_cropped_image(self, output_path):
        cropped_image = self.crop_roi()
        # 保存裁剪后的图像
        sitk.WriteImage(sitk.GetImageFromArray(cropped_image), output_path)

    # 保存三个层面的图像
    def save_three_images(self, output_path):
        images = self._three_image()
        # 保存三个层面的图像
        sitk.WriteImage(sitk.GetImageFromArray(images), output_path)

    # 根据最大值索引裁剪出三个层面的图像
    def _three_image(self):
        max_label0 = self.label_array[self.max_index - 1]
        max_label1 = self.label_array[self.max_index]
        max_label2 = self.label_array[self.max_index + 1]

        max_image0 = self.origin_array[self.max_index - 1]
        max_image1 = self.origin_array[self.max_index]
        max_image2 = self.origin_array[self.max_index + 1]

        # 找到ROI的中心点
        roi_center1 = self.find_roi_center(max_label1)

        # 根据中心点坐标向四周延伸裁剪出224*224
        cropped_image0 = self._crop_roi(max_image0, roi_center1)
        cropped_image1 = self._crop_roi(max_image1, roi_center1)
        cropped_image2 = self._crop_roi(max_image2, roi_center1)

        # 将三个图像数组堆叠成一个新的数组
        stacked_images = np.stack((cropped_image0, cropped_image1, cropped_image2))

        return stacked_images

# 示例用法
label_path = r"C:\Users\Administrator\Desktop\Breast\benign_label\AN_YU_MEI-label.nii"
image_path = r"C:\Users\Administrator\Desktop\Breast\benign\DCE\AN_YU_MEI.nii"
output_path = r"C:\Users\Administrator\Desktop\output_image.nii"

processor = ImageProcessor(label_path, image_path)
processor.read_images()
processor.find_max_index()
cropped_image = processor.crop_roi()
processor.save_cropped_image(output_path)
processor.save_three_images(output_path)

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值