将图像特征和CSV中的特征保存到h5文件中

 这个脚本的任务是:从mask中提取最大的ROI,然后映射到DCE原图中,获取原图最大ROI的上一层及下一层,共三层。然后去除掉周围的0像素,再利用双线性插值到224*224大小的图像。再映射到T2序列的原图中,得到224*224大小的图像(mask和T2图像的大小不一样,利用最邻近插值将mask调整到T2大小)。还要获取CSV中这个患者的特征。将图像信息及CSV中的特征一块保存到h5文件中。以便在网络中进行融合。

import glob
from random import randomimport pandas as pd
from skimage import exposure
import h5py
import SimpleITK as sitk
from PIL import Image
import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt
import os
import numpy as np
import pydicom
import nibabel as nib
import random"""
这个脚本只能处理良性文件夹或恶性文件夹,需要运行两次,良性一次,恶性一次,另外需要修改label为0或1可以将良性或恶性文件夹下的DCE和T2的数据,CSV的数据还有label数据保存到h5文件中image_DCE_path文件夹存储着所有DCE序列原始图像的nii文件
image_T2_path文件夹存储着所有T2序列原始图像的nii文件
label_path文件夹存储着所有掩膜图像的nii文件
save_dir文件夹存储着所有处理后的图像h5文件
csv_file 为pyradiomics特征提取后的csv文件路径,注意要删除里面没意义的列
name_labbel = 0 为良性或恶性的标签
"""# # 设置文件夹路径
image_DCE_path = r'C:\Users\Administrator\Desktop\Breast\benign\DCE'
image_T2_path = r'C:\Users\Administrator\Desktop\Breast\benign\T2'label_path = r'C:\Users\Administrator\Desktop\Breast\benign_label'save_dir = r'C:\Users\Administrator\Desktop\Breast\data'
csv_file = "C:\\Users\\Administrator\\Desktop\\Breast\\result.csv"  # CSV文件地址
label = 0# 定义一个函数来修剪图像,去除空白部分
def trim_image(image):# 转换为numpy数组image_array = np.array(image)# 找到非零像素的边界non_zero_indices = np.nonzero(image_array)min_row = np.min(non_zero_indices[0])max_row = np.max(non_zero_indices[0])min_col = np.min(non_zero_indices[1])max_col = np.max(non_zero_indices[1])min_depth = np.min(non_zero_indices[2])max_depth = np.max(non_zero_indices[2])# 裁剪图像cropped_image_array = image_array[min_row:max_row + 1, min_col:max_col + 1, min_depth:max_depth + 1]return cropped_image_array# 数据预处理
def preprocess_data(image_array, window_width=1000, window_center=500):"""对图像进行预处理,包括窗宽窗位变换。Args:image_array: 原始图像nii文件读取后的数据window_width:窗宽window_center: 窗位Returns:对图像进行了窗宽窗位变换和均质化后的图像"""# 提取每张图像的像素值#img: 需要增强的图片#window_width:窗宽#window_center:中心minWindow = float(window_center)-0.5*float(window_width)new_img = (image_array -minWindow)/float(window_width)new_img[new_img<0] = 0new_img[new_img>1] = 1img = (new_img*255).astype('uint8')img_ = []for i in range(img.shape[0]):# Perform histogram equalizationimg_res = exposure.equalize_hist(img[i])img_.append(img_res)return np.array(img_)def concat_image(label_path,image_path , label = False):# 读取标签NII文件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])])if label == True:label_array = F.interpolate(torch.tensor(label_array, dtype=torch.float32).unsqueeze(0), size=(672, 672), mode='nearest').squeeze().numpy().astype(np.uint8)#对数据进行均质化和窗宽窗位的调整#origin_array = preprocess_data(origin_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 = iroi_array = np.array([label_array[max_nonzero_index] * origin_array[max_nonzero_index - 1],label_array[max_nonzero_index] * origin_array[max_nonzero_index],label_array[max_nonzero_index] * origin_array[max_nonzero_index + 1]])finish_array = trim_image(roi_array).astype(np.float64)image_tensor = torch.tensor(finish_array, dtype=torch.float32).unsqueeze(0)# 目标图像大小target_height, target_width = 224, 224# 使用双线性插值角对齐对图像进行缩放output_bilinear_corners_True = F.interpolate(image_tensor, size=(target_height, target_width), mode='bilinear',align_corners=True)# 将张量转换回 numpy 数组output_bilinear_corners_True_array = output_bilinear_corners_True.squeeze().numpy().astype(np.uint8)return output_bilinear_corners_True_arraydef get_features_by_name(name, csv_file):"""根据姓名获取到csv文件中的同名那一行数据,保存这行第二列之后的数据Args:name: 为出入的姓名csv_file: 为pyradiomics特征提取后的csv文件路径,注意要删除里面没意义的列Returns:"""# 读取CSV文件df = pd.read_csv(csv_file)# 查找姓名是否在第一列中if name in df['Name'].values:# 获取姓名所在行的索引index = df.index[df['Name'] == name].tolist()[0]# 获取特征(姓名后的列)features = df.iloc[index, 1:].tolist()return pd.DataFrame(features)else:print(f"Name '{name}' not found in CSV file.")return Nonedef save_data(image_DCE_path,image_T2_path,label_path,label):r_num = 0image_DCE_files = glob.glob(f'{image_DCE_path}/*.nii')image_T2_files = glob.glob(f'{image_T2_path}/*.nii')label_files = glob.glob(f'{label_path}/*.nii')for i in range(len (label_files)):name_labbel = label_files[i].split('\\')[-1].split('-')[0]name_image_DCE = image_DCE_files[i].split('\\')[-1].split('.')[0]name_image_T2 = image_T2_files[i].split('\\')[-1].split('.')[0]if name_labbel == name_image_DCE :# 读取原始图像image_DCE = concat_image(label_files[i], image_DCE_files[i])image_T2 = concat_image(label_files[i], image_T2_files[i] , label = True)csv_data =  get_features_by_name(name_labbel, csv_file)R = random.randint(1, 100)if R >= 0 and R <= 70:os.makedirs(save_dir+"/train", exist_ok=True)f = h5py.File(save_dir+"/train" + '/{}_{}.h5'.format(name_labbel, r_num), 'w')elif R > 70 and R <= 90:os.makedirs(save_dir + "/valid", exist_ok=True)f = h5py.File(save_dir+"/valid" + '/{}_{}.h5'.format(name_labbel, r_num), 'w')else:os.makedirs(save_dir + "/test", exist_ok=True)f = h5py.File(save_dir+"/test" + '/{}_{}.h5'.format(name_labbel, r_num), 'w')f.create_dataset('data_DCE', data=image_DCE, compression="gzip")f.create_dataset('data_T2', data=image_T2, compression="gzip")f.create_dataset('csv', data=csv_data)f.create_dataset('label', data=label)f.close()r_num += 1print("process {} uid = {} label={}".format(r_num, name_labbel,label))# plt.imshow(image_DCE[2], cmap='gray')## plt.show()  # 显示图像save_data(image_DCE_path,image_T2_path,label_path,label)

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

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

相关文章

二叉树的前序、中序、后序遍历的C++实现

二叉树的前序、中序、后序 遍历属于深度优先搜索方式&#xff0c;本文使用递归法实现前序、中序、后序的遍历方法&#xff0c;代码如下&#xff1a; #include <iostream> #include <vector>struct TreeNode{int val;TreeNode* left;TreeNode* right;TreeNode(int …

初识C++ · 模板初阶

目录 1 泛型编程 2 函数模板 3 类模板 1 泛型编程 模板是泛型编程的基础&#xff0c;泛型我们碰到过多次了&#xff0c;比如malloc函数返回的就是泛型指针&#xff0c;需要我们强转。 既然是泛型编程&#xff0c;也就是说我们可以通过一个样例来解决类似的问题&#xff0c…

leetcode1290-Convert Binary Number in a Linked List to Integer

题目 给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1&#xff1a; 输入&#xff1a;head [1,0,1] 输出&#xff1a;5 解释&#xff1a;二进制数 (101) 转化为…

Java基础之《mybatis-plus多数据源配置》

1、pom文件引入依赖 引入MyBatis-Plus之后请不要再次引入MyBatis以及mybatis-spring-boot-starter和MyBatis-Spring&#xff0c;以避免因版本差异导致的问题 <!--引入 MyBatis-Plus 之后请不要再次引入 MyBatis 以及 mybatis-spring-boot-starter和MyBatis-Spring&#xff0…

【C++】STL_ string的使用 + 模拟实现

前言 目录 1. STL简介&#xff08;1&#xff09;什么是STL&#xff08;2&#xff09;STL的版本&#xff08;3&#xff09;STL的六大组件 2. string的使用2.1 npos2.2 遍历字符串string的每一个字符2.3 迭代器&#xff1a;2.4 string的内存管理2.5 string模拟实现2.5.1 深拷贝&a…

Redis(主从复制搭建)

文章目录 1.主从复制示意图2.搭建一主多从1.搭建规划三台机器&#xff08;一主二从&#xff09;2.将两台从Redis服务都按照同样的方式配置&#xff08;可以理解为Redis初始化&#xff09;1.安装Redis1.yum安装gcc2.查看gcc版本3.将redis6.2.6上传到/opt目录下4.进入/opt目录下然…

iptables---防火墙

防火墙介绍 防火墙的作用可以理解为是一堵墙&#xff0c;是一个门&#xff0c;用于保护服务器安全的。 防火墙可以保护服务器的安全&#xff0c;还可以定义各种流量匹配的规则。 防火墙的作用 防火墙具有对服务器很好的保护作用&#xff0c;入侵者必须穿透防火墙的安全防护…

第V章-Ⅰ Vue3路由vue-router初识

第V章-Ⅰ Vue3路由vue-router初识 安装Vue路由基础router-link 组件导航router-view 路由出口单独导入关于路由的库文件定义路由组件定义路由规则对象创建router实例将路由对象挂载Vue实例上redirect 路由重定向嵌套路由 路由传参params形式传参query形式传参params方式与query…

Leetcode—1991. 找到数组的中间位置【简单】

2024每日刷题&#xff08;129&#xff09; Leetcode—1991. 找到数组的中间位置 实现代码 class Solution { public:int findMiddleIndex(vector<int>& nums) {int sum accumulate(nums.begin(), nums.end(), 0);int prefix 0;for(int i 0; i < nums.size();…

考情分析 | 2025年西北工业大学计算机考研考情分析!

西北工业简称西工大&#xff08;英文缩写NPU&#xff09;&#xff0c;大学坐落于古都西安&#xff0c;是我国唯一一所以同时发展航空、航天、航海工程教育和科学研究为特色&#xff0c;以工理为主&#xff0c;管、文、经、法协调发展的研究型、多科性和开放式的科学技术大学。十…

代码随想录-算法训练营day33【贪心算法03:K次取反后最大化的数组和、加油站、分发糖果】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第八章 贪心算法 part03● 1005.K次取反后最大化的数组和 ● 134. 加油站 ● 135. 分发糖果 详细布置 1005.K次取反后最大化的数组和 本题简单一些&#xff0c;估计大家不用想着贪心 &#xff0c;用自己直觉也会有…

怎么制作好玩的gif?试试这个工具轻松制作

视频之所以受大众的喜爱是因为有声音、画面的搭配&#xff0c;让观者深入其中体验感会更强。但是视频的体积较大、时长也比较长&#xff0c;给我们的传播和保存造成了一定的影响。那么&#xff0c;我们可以将视频制作成gif图片来使用&#xff0c;不需要下载软件&#xff0c;使用…

最大数字——蓝桥杯十三届2022国赛大学B组真题

问题分析 这道题属于贪心加回溯。所有操作如果能使得高位的数字变大必定优先用在高位&#xff0c;因为对高位的影响永远大于对低位的影响。然后我们再来分析一下&#xff0c;如何使用这两种操作&#xff1f;对于加操作&#xff0c;如果能使这一位的数字加到9则变成9&#xff0…

LeetCode-hot100题解—Day6

原题链接&#xff1a;力扣热题-HOT100 我把刷题的顺序调整了一下&#xff0c;所以可以根据题号进行参考&#xff0c;题号和力扣上时对应的&#xff0c;那么接下来就开始刷题之旅吧~ 1-8题见LeetCode-hot100题解—Day1 9-16题见LeetCode-hot100题解—Day2 17-24题见LeetCode-hot…

UE5自动生成地形一:地形制作

UE5自动生成地形一&#xff1a;地形制作 常规地形制作地形编辑器地形管理添加植被手动修改部分地形的植被 置换贴图全局一致纹理制作地貌裸露岩石地形实例 常规地形制作 地形制作入门 地形导入部分 选择模式&#xff1a;地形模式。选择地形子菜单&#xff1a;管理->导入 …

STC8增强型单片机开发——C51版本Keil环境搭建

一、目标 了解C51版本Keil开发环境的概念和用途掌握C51版本Keil环境的安装和配置方法熟悉C51版本Keil开发环境的使用 二、准备工作 Windows 操作系统Keil C51 安装包&#xff08;可以从Keil官网下载&#xff09;一款8051单片机开发板 三、搭建流程 环境搭建的基本流程&#xf…

思维导图网页版哪个好?2024年值得推荐的8个在线思维导图软件!

思维导图如今已成为一种常用的工具&#xff0c;帮助我们清晰地组织和整理信息。随着科技的发展&#xff0c;思维导图的产品形态也经过多轮迭代&#xff0c;从最初的本地客户端过渡到基于云的 Web 端&#xff0c;各类网页版思维导图软件应运而生&#xff0c;它们方便快捷&#x…

【Linux】gcc/g++的使用

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; Linux &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好&#xff0c;本片文章将会讲解Linux中gcc/g使用的相关内容。 如果看到最后您觉得这篇文章写得不错…

【Linux】CAN根据时钟频率、波特率计算采样点详解

1、采样点知识回顾 参考博客:【CAN】知识点:帧类型、数据帧结构、传输速率、位时间、采样点 CAN 采样点是指在一个数据位的传输周期内,接收器实际采样数据的时间点。这个时间点是以百分比来表示的,它决定了在数据位的传输周期中,何时读取数据位的值。 正确设置采样点对…

js api part3

环境对象 环境对象&#xff1a; 指的是函数内部特殊的 变量 this &#xff0c; 它代表着当前函数运行时所处的环境 作用&#xff1a; 弄清楚this的指向&#xff0c;可以让我们代码更简洁 函数的调用方式不同&#xff0c;this 指代的对象也不同 【谁调用&#xff0c; this 就是…