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

embedded/2024/10/21 10:04:24/

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

有两个文件,一个是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 = 0max_nonzero_index = Nonefor 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_pixelsmax_nonzero_index = ireturn 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*224cropped_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_imagesimages = 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 = 0max_nonzero_index = Nonefor 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_pixelsmax_nonzero_index = ireturn 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*224cropped_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_imagesimages = three_image(max_index)
print("保存了三个层面的图像:", images.shape )

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

import os
import SimpleITK as sitk
import numpy as npclass ImageProcessor:def __init__(self, label_path, image_path):self.label_path = label_pathself.image_path = image_pathself.origin_array = Noneself.label_array = Noneself.max_index = Noneself.max_image = Noneself.max_label = Noneself.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 = 0max_nonzero_index = Nonefor 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_pixelsmax_nonzero_index = iself.max_index = max_nonzero_index# 根据找到的中心点坐标,以此为中心,映射到原图上,向四周延伸到224*224def 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*224cropped_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*224cropped_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)


http://www.ppmy.cn/embedded/41925.html

相关文章

css中用来设置表格的一些样式属性

在CSS中我们用来给表格设置样式的有以下属性: 1. 基本表格样式 边框:使用border属性可以为表格添加边框。内边距:padding属性用于增加单元格内的空间。外边距:margin属性用于控制表格与其他元素之间的距离。 2. 表格结构样式 …

Nginx-04-Docker Nginx

Docker Nginx 实战 HTTP 服务 Nginx 的最大作用,就是搭建一个 Web Server。 有了容器,只要一行命令,服务器就架设好了,完全不用配置。 运行官方 image $ docker container run \-d \-p 8080:80 \--rm \--name mynginx \nginx…

UVM寄存器模型——手写Ralf问题debug

寄存器模型是UVM中至关重要的一部分,如果没有寄存器模型,那么验证平台对于DUT内寄存器的访问方式将十分有限,对DUT运行状态的把控也会变得更为复杂。 在验证过程中,scoreboard或者其他验证组件经常需要了解当前时间某个寄存器的值…

【Leetcode每日一题】 动态规划 - 简单多状态 dp 问题 - 删除并获得点数(难度⭐⭐)(76)

1. 题目解析 题目链接:LCR 091. 粉刷房子 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 1. 状态定义 在解决这类问题时,我们首先需要根据题目的具体要求来定义状态。针对房屋粉刷问题&#…

【个人成长】Fitten Code 测试案例分析

JS,Fitten Code 当插件,然后在代码分析的时候,有些小感悟,大模型写代码的思路,正常我理解的代码思路。 输入代码 (item.score* 100).toFixed(0)Prompt 得出的结果 5分,如果超过100按100算输出结果 con…

代码审计-php篇之某CRM系统多处sql注入

🌟 ❤️ 作者:yueji0j1anke 首发于公号:剑客古月的安全屋 字数:3516 阅读时间: 35min 声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果…

Lora训练Windows[笔记]

一. 使用kohya_ss的GUI版本(https://github.com/bmaltais/kohya_ss.git) 这个版本跟stable-diffusion-webui的界面很像,只不过是训练模型专用而已,打开的端口同样是7860。 1.双击setup.bat,选择1安装好xformers,pytorch等和cuda…

docker容器技术篇:rancher管理平台部署kubernetes集群

rancher管理平台部署kubernetes集群 Rancher 是一个 Kubernetes 管理工具,让你能在任何地方和任何提供商上部署和运行集群。 Rancher 可以创建来自 Kubernetes 托管服务提供商的集群,创建节点并安装 Kubernetes,或者导入在任何地方运行的现…