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

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

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

python 复制代码
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可能就勾画了一层两层,没有三层,这样代码就会报错

python 复制代码
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 )

全部代码

python 复制代码
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)
相关推荐
CV学术叫叫兽7 分钟前
快速图像识别:落叶植物叶片分类
人工智能·分类·数据挖掘
xrgs_shz21 分钟前
MATLAB读入不同类型图像并显示图像和相关信息
图像处理·计算机视觉·matlab
WeeJot嵌入式33 分钟前
卷积神经网络:深度学习中的图像识别利器
人工智能
脆皮泡泡42 分钟前
Ultiverse 和web3新玩法?AI和GameFi的结合是怎样
人工智能·web3
机器人虎哥1 小时前
【8210A-TX2】Ubuntu18.04 + ROS_ Melodic + TM-16多线激光 雷达评测
人工智能·机器学习
码银1 小时前
冲破AI 浪潮冲击下的 迷茫与焦虑
人工智能
用户37791362947551 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
何大春1 小时前
【弱监督语义分割】Self-supervised Image-specific Prototype Exploration for WSSS 论文阅读
论文阅读·人工智能·python·深度学习·论文笔记·原型模式
uncle_ll1 小时前
PyTorch图像预处理:计算均值和方差以实现标准化
图像处理·人工智能·pytorch·均值算法·标准化
宋138102797201 小时前
Manus Xsens Metagloves虚拟现实手套
人工智能·机器人·vr·动作捕捉