图像分割中根据mask的ROI,去除mask和image中没有勾画ROI层数以外的图像

news2025/2/4 6:17:03

在分割任务中,一个患者有很多层图像,但是勾画的ROI仅有那么几层。我想去除ROI以外层数的那些没用的图像。这里以一个36张图像的nii格式数据为例

 

查看一下mask文件中有多少个非0图像

import nibabel as nib
import numpy as np

# 加载 .nii 文件
file_path = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI\zhangsan-label.nii"#
image = nib.load(file_path)

# 获取数据数组
data = image.get_fdata()

# 打印数据的形状
print("数据的形状:", data.shape)

# 初始化一个列表来存储非全零图像的序号
non_zero_indices = []

# 遍历每张图像
for i in range(data.shape[2]):  # 遍历第三维,即36张图像
    image_slice = data[:, :, i]  # 提取第i张图像
    if np.any(image_slice):  # 检查图像是否包含非零像素
        non_zero_indices.append(i)  # 将序号加入列表

# 打印筛选结果
print(f"包含非零像素的图像序号: {non_zero_indices}")
print(f"筛选出的非全零图像数量: {len(non_zero_indices)}")

 

数据的形状: (480, 480, 36)
包含非零像素的图像序号: [13, 14, 15, 16]
筛选出的非全零图像数量: 4

 对mask中勾画的ROI进行查看

import nibabel as nib
import matplotlib.pyplot as plt

# 加载处理后的NIfTI文件
processed_path = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI\CAO_ZHAN_GUO-label.nii"
processed_img = nib.load(processed_path)
processed_data = processed_img.get_fdata()  # 获取处理后的数据,形状为(480, 480, 36)

# 可视化36张图像
def visualize_slices(data, num_slices):
    """
    可视化3D数据中的多张切片
    :param data: 3D数据,形状为(height, width, depth)
    :param num_slices: 需要可视化的切片数量
    """
    depth = data.shape[2]  # 获取切片的数量
    slice_indices = np.linspace(0, depth - 1, num_slices, dtype=int)  # 均匀选择切片索引

    # 创建子图
    fig, axes = plt.subplots(6, 6, figsize=(15, 15))  # 6x6的子图布局
    fig.suptitle("Processed Image Slices", fontsize=16)

    for i, idx in enumerate(slice_indices):
        ax = axes[i // 6, i % 6]  # 获取当前子图
        ax.imshow(data[:, :, idx], cmap="gray")  # 显示切片
        ax.set_title(f"Slice {idx}")
        ax.axis("off")  # 关闭坐标轴

    plt.tight_layout()
    plt.show()

# 可视化36张切片
visualize_slices(processed_data, 36)

 

 对image图像进行查看

 我们要删除mask中没有勾画ROI的图像,最后是这样的mask文件

 

 并保存对应的image图像

 

 最后就是保存了两个删除后的文件。

完整的代码,批量操作image和mask文件夹下的文件,并保存到两个新的文件夹中

import nibabel as nib
import numpy as np
import os

# 设置image和mask文件夹路径
image_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\image"
mask_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI"
new_image_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\image_filtered"
new_mask_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI_filtered"

# 创建新文件夹(如果不存在)
os.makedirs(new_image_folder, exist_ok=True)
os.makedirs(new_mask_folder, exist_ok=True)

# 遍历image文件夹中的所有nii文件
for image_filename in os.listdir(image_folder):
    if image_filename.endswith('.nii'):
        # 构建对应的mask文件名
        mask_filename = image_filename.replace('.nii', '-label.nii')
        
        # 构建完整路径
        image_path = os.path.join(image_folder, image_filename)
        mask_path = os.path.join(mask_folder, mask_filename)
        
        # 检查mask文件是否存在
        if not os.path.exists(mask_path):
            print(f"警告: 未找到对应的mask文件 {mask_filename},跳过此文件。")
            continue
        
        # 读取image和mask文件
        image_nii = nib.load(image_path)
        mask_nii = nib.load(mask_path)

        # 获取图像数据
        image_data = image_nii.get_fdata()
        mask_data = mask_nii.get_fdata()

        # 创建一个空列表,用于保存所有非零图像
        filtered_image_data = []
        filtered_mask_data = []

        # 遍历每张图像(这里假设每张图像的大小是480x480)
        for i in range(image_data.shape[2]):  # 假设第三个维度是图像的数量,这里是36
            # 选择当前图像的mask(二维数据)
            mask_slice = mask_data[:, :, i]
            
            # 如果mask图像有任何非零像素,则保存对应的image和mask
            if np.any(mask_slice != 0):
                # 获取该图像的数据
                image_slice = image_data[:, :, i]
                
                # 将符合条件的图像和mask存入列表
                filtered_image_data.append(image_slice)
                filtered_mask_data.append(mask_slice)

        # 将筛选出的图像合并成一个新的数组
        if filtered_image_data and filtered_mask_data:  # 确保有有效的图像
            filtered_image_data = np.stack(filtered_image_data, axis=2)
            filtered_mask_data = np.stack(filtered_mask_data, axis=2)
            
            # 打印处理的文件名
            print(f"处理文件: {image_filename} 和 {mask_filename}")
            
            # 保存新的合并后的nii文件
            new_image_filename = os.path.join(new_image_folder, image_filename)
            new_mask_filename = os.path.join(new_mask_folder, mask_filename)
            
            # 保存为新的nii文件
            new_image_nii = nib.Nifti1Image(filtered_image_data, image_nii.affine)
            new_mask_nii = nib.Nifti1Image(filtered_mask_data, mask_nii.affine)
            
            # 保存为新的nii文件
            nib.save(new_image_nii, new_image_filename)
            nib.save(new_mask_nii, new_mask_filename)

print("批量处理完成!")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2291644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全栈开发:使用.NET Core WebAPI构建前后端分离的核心技巧(一)

目录 cors解决跨域 依赖注入使用 分层服务注册 缓存方法使用 内存缓存使用 缓存过期清理 缓存存在问题 分布式的缓存 cors解决跨域 前后端分离已经成为一种越来越流行的架构模式,由于跨域资源共享(cors)是浏览器的一种安全机制,它会阻止前端应用…

springboot使用rabbitmq

使用springboot创建rabbitMQ的链接。 整个项目结构如下&#xff1a; 1.maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>3.4.1</version> </dependency>application.y…

Linux——ext2文件系统(二)

Linux——ext2文件系统 ext2文件系统宏观认识一、磁盘分区与格式化二、块组&#xff08;Block Group&#xff09;结构三、文件系统特性 文件名与目录名与inode一、inode的作用原理二、文件与目录名与inode的关系 路径一&#xff0c;路径解析二&#xff0c;路径缓存三&#xff0…

如何让DeepSeek恢复联网功能?解决(由于技术原因,联网搜索暂不可用)

DeekSeek提示&#xff1a;&#xff08;由于技术原因&#xff0c;联网搜索暂不可用&#xff09; 众所周知&#xff0c;因为海外黑客的ddos攻击、僵尸网络攻击&#xff0c;deepseek的联网功能一直处于宕机阶段&#xff0c;但是很多问题不联网出来的结果都还是2023年的&#xff0c…

python的ruff简单使用

Ruff 是一个用 Rust 编写的高性能 Python 静态分析工具和代码格式化工具。它旨在提供快速的代码检查和格式化功能&#xff0c;同时支持丰富的配置选项和与现有工具的兼容性。ruff是用rust实现的python Linter&Formatter。 安装&#xff1a; conda install -c conda-forge…

【漫话机器学习系列】077.范数惩罚是如何起作用的(How Norm Penalties Work)

范数惩罚的作用与原理 范数惩罚&#xff08;Norm Penalty&#xff09; 是一种常用于机器学习模型中的正则化技术&#xff0c;它的主要目的是控制模型复杂度&#xff0c;防止过拟合。通过对模型的参数进行惩罚&#xff08;即在损失函数中加入惩罚项&#xff09;&#xff0c;使得…

LLMs之OpenAI o系列:OpenAI o3-mini的简介、安装和使用方法、案例应用之详细攻略

LLMs之OpenAI o系列&#xff1a;OpenAI o3-mini的简介、安装和使用方法、案例应用之详细攻略 目录 相关文章 LLMs之o3&#xff1a;《Deliberative Alignment: Reasoning Enables Safer Language Models》翻译与解读 LLMs之OpenAI o系列&#xff1a;OpenAI o3-mini的简介、安…

Notepad++消除生成bak文件

设置(T) ⇒ 首选项... ⇒ 备份 ⇒ 勾选 "禁用" 勾选禁用 就不会再生成bak文件了 notepad怎么修改字符集编码格式为gbk 如图所示

后台管理系统通用页面抽离=>高阶组件+配置文件+hooks

目录结构 配置文件和通用页面组件 content.config.ts const contentConfig {pageName: "role",header: {title: "角色列表",btnText: "新建角色"},propsList: [{ type: "selection", label: "选择", width: "80px&q…

Spring Boot项目如何使用MyBatis实现分页查询

写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油&#xff0c;冲鸭&#x…

Intellij 插件开发-快速开始

目录 一、开发环境搭建以及创建action1. 安装 Plugin DevKit 插件2. 新建idea插件项目3. 创建 Action4. 向新的 Action 表单注册 Action5. Enabling Internal Mode 二、插件实战开发[不推荐]UI Designer 基础JBPanel类&#xff08;JPanel面板&#xff09;需求&#xff1a;插件设…

语言月赛 202412【题目名没活了】题解(AC)

》》》点我查看「视频」详解》》》 [语言月赛 202412] 题目名没活了 题目描述 在 XCPC 竞赛里&#xff0c;会有若干道题目&#xff0c;一支队伍可以对每道题目提交若干次。我们称一支队伍对一道题目的一次提交是有效的&#xff0c;当且仅当&#xff1a; 在本次提交以前&…

MySQL锁类型(详解)

锁的分类图&#xff0c;如下&#xff1a; 锁操作类型划分 读锁 : 也称为共享锁 、英文用S表示。针对同一份数据&#xff0c;多个事务的读操作可以同时进行而不会互相影响&#xff0c;相互不阻塞的。 写锁 : 也称为排他锁 、英文用X表示。当前写操作没有完成前&#xff0c;它会…

OSCP - Proving Grounds - Roquefort

主要知识点 githook 注入Linux path覆盖 具体步骤 依旧是nmap扫描开始&#xff0c;3000端口不是很熟悉&#xff0c;先看一下 Nmap scan report for 192.168.54.67 Host is up (0.00083s latency). Not shown: 65530 filtered tcp ports (no-response) PORT STATE SERV…

集合通讯概览

&#xff08;1&#xff09;通信的算法 是根据通讯的链路组成的 &#xff08;2&#xff09;因为通信链路 跟硬件强相关&#xff0c;所以每个CCL的库都不一样 芯片与芯片、不同U之间是怎么通信的&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很重要…

【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(二)

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;贪心算法篇–CSDN博客 文章目录 前言例题1.买卖股票的最佳时机2.买卖股票的最佳时机23.k次取…

oracle: 表分区>>范围分区,列表分区,散列分区/哈希分区,间隔分区,参考分区,组合分区,子分区/复合分区/组合分区

分区表 是将一个逻辑上的大表按照特定的规则划分为多个物理上的子表&#xff0c;这些子表称为分区。 分区可以基于不同的维度&#xff0c;如时间、数值范围、字符串值等&#xff0c;将数据分散存储在不同的分区 中&#xff0c;以提高数据管理的效率和查询性能&#xff0c;同时…

基于SpringBoot 前端接收中文显示解决方案

一. 问题 返回给前端的的中文值会变成“???” 二. 解决方案 1. 在application.yml修改字符编码 &#xff08;无效&#xff09; 在网上看到说修改servlet字符集编码&#xff0c;尝试了不行 server:port: 8083servlet:encoding:charset: UTF-8enabled: trueforce: true2. …

java练习(5)

ps:题目来自力扣 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这…

python算法和数据结构刷题[3]:哈希表、滑动窗口、双指针、回溯算法、贪心算法

回溯算法 「所有可能的结果」&#xff0c;而不是「结果的个数」&#xff0c;一般情况下&#xff0c;我们就知道需要暴力搜索所有的可行解了&#xff0c;可以用「回溯法」。 回溯算法关键在于:不合适就退回上一步。在回溯算法中&#xff0c;递归用于深入到所有可能的分支&…