最近在做单b值DW图像的去噪算法研究,为了实现对比效果,所以这几天对noise2noise在DWI上的运用进行实现,而且今天收获很大,所以我又来记录了(嘿嘿,积少成多嘛)
一、单b值数据: 文件后缀 .nii ,使用库dipy(或者nibabel)读取
from dipy.io.image import load_nifti
nii_path = "file path"
data_array, affine, _ = load_nifti(nii_path, return_img=True)
我得到的data_array是四维的(deepth,height,width,n),第4维就是根据b值的采集个数而产生的。
二、如何获取noise2noise图像对(input,target)
由于单b值dwi数据本身的特性:b值<=5,近似看作干净图像(clean),剩余的都是同b值的含噪图像,只是采集的梯度方向不一样。
就以b1000为例,要想找出适用于noise2noise的噪声图像对,其实不用像原论文那样(使用clean,加噪得noise1,再加噪得noise2,用noise1-noise2做图像对),对于单b值dwi,我们可以在同一b值下,使用某种相似度计算方法,找出梯度方向最近似的两个b1000噪声图像对,输入降噪模型)
def find_target(gradients, indices):
"""
找出每个梯度向量最相似的邻居并返回索引配对。
参数:
gradients: 梯度向量列表。
indices: 梯度向量在原始数据中的索引列表。
返回:
pairs: 索引配对列表,每个元素是一个包含两个索引的元组。
"""
# 计算余弦相似度矩阵
similarity_matrix = np.zeros((len(gradients), len(gradients)))
for i, vec_i in enumerate(gradients):
for j, vec_j in enumerate(gradients):
similarity_matrix[i, j] = np.dot(vec_i, vec_j) / (np.linalg.norm(vec_i) * np.linalg.norm(vec_j))
nearest_match = []
for i in range(len(gradients)):
max_sim_index = np.argmax(similarity_matrix[i]) # 先找到最大相似度的索引
if max_sim_index == i: # 如果是自己,则找第二大的
similarity_matrix[i, i] = -1
max_sim_index = np.argmax(similarity_matrix[i])
nearest_match.append((indices[i], indices[max_sim_index]))
return nearest_match
得到的nearest_match是一个list,每个元素就是(noise1_index,noise2_index)
三、总结
根据nearest_match就可以从data_array的最后一维取出对应的三维图像
def find_pair(data_array,index_match):
noise1_index = [ps[0] for ps in index_match]
noise2_index= [ps[1] for ps in index_match]
noise1 = data_array[:, :, :, noise1_index]
noise2 = data_array[:, :, :, noise2_index]
return noise1,noise2