写了一个Dicom图像自动按照病人和扫描序列分类代码matlab。
如果你拿到的是很多很多的dicom图像混在一起,并不知道每个dicom属于哪个序列,那么可以借助此代码,把dicom图像按照序列分类存储。
代码文件‘DicomClassifier_V1.m’是根据病人的名称和protocal的名称把Dicom图像分类存储。
代码文件‘DicomClassifier_V2.m’是考虑到MRI设备中扫描出来的原始数据中有的Dicom图像中没有protocal的名称,因此,我们可以获取前一个slice的protocal的名称来使用。
代码文件‘uniquecell.m’是从网址(http://cn.mathworks.com/matlabcentral/fileexchange/31718-unique-elements-in-cell-array)下载的,用于提取出cell中不重复的字符串。
使用方法:
(1)代码文件‘uniquecell.m’的放置。
该文件的路径是‘D:/MyMatlabFunctions‘,
可以根据自己放代码的文件夹,修改代码文件‘DicomClassifier_V1.m’或代码文件‘DicomClassifier_V2.m’中的 addpath(‘D:/MyMatlabFunctions‘);
(2)dicom文件的路径
根据自己存放dicom文件的文件夹修改代码文件‘DicomClassifier_V1.m’或代码文件‘DicomClassifier_V2.m’中的以下代码行:
InFolderName=‘H:/DATA_fMRI/‘;
(3)输出的文件的路径
按照自己想把输出的文件放在哪里,修改以下代码行:
OutFolderName=‘D:/TestDataClassifier‘;
该代码行也在代码文件‘DicomClassifier_V1.m’或代码文件‘DicomClassifier_V2.m’中。
(4)运行代码文件‘DicomClassifier_V1.m’或代码文件‘DicomClassifier_V2.m’
后面附上代码:
代码文件‘DicomClassifier_V1.m’
clc;clear;close all;
% 后面会用到的一个uniquecell函数所在位置
addpath(‘D:/MyMatlabFunctions‘);
%% [1]读取一个文件夹里面全部的dicom文件
InFolderName=‘H:/DATA_fMRI/‘;
OutFolderName=‘D:/TestDataClassifier‘;
files=dir(fullfile(InFolderName,‘*‘));%文件夹中的dcm文件没有后缀名时使用这句
% files=dir(fullfile(filename,‘*.dcm‘));%文件夹中的dcm文件有.dcm后缀时使用这句
%% [2]读取文件中的Header信息,主要是病人名字和序列名称
name=cell(length(files),1);
protocol=cell(length(files),1);
% name_protocol=cell(length(files),2);
cd(InFolderName);
for i=1:length(files)
if files(i).bytes~=0 % make sure it is not an empty file
info=dicominfo(files(i).name);
patientname=info.PatientName.GivenName;
protocolname=info.ProtocolName;
name(i)=cellstr(patientname);
protocol(i)=cellstr(protocolname);
% name_protocol(i,1)=(name(i));
% name_protocol(i,2)=(protocol(i));
end
end
%% [3]把文件中包含的所有人的名字和序列提取出来,重复的只提取一个出来
UniqueName=uniquecell(name);% 获取全部的病人的名字
UniqueProtocol=uniquecell(protocol);% 获取包含的全部的序列名称
%% [4] 产生准备把存数据的文件夹
for i=1:1:length(UniqueName)
if ~isequal(UniqueName(i),{[]})% 名字不是空的
OutNameFile=char(UniqueName(i));
mkdir(OutFolderName,OutNameFile);
for j=1:1:length(UniqueProtocol)
if ~isequal(UniqueProtocol(j),{[]}) % Protocol名字不是空的
OutProtocolFolder=strcat(OutFolderName,‘/‘,OutNameFile);
OutProtocolName=UniqueProtocol(j);
% OutProtocolName=char(UniqueProtocol(j));
mkdir(OutProtocolFolder,char(OutProtocolName));
end
end
end
end
%% [5] 把图片放到对应的文件夹里面去
cd(InFolderName);
for m=1:length(files)
if files(m).bytes~=0 % make sure it is not an empty file
info=dicominfo(files(m).name);
patientname=info.PatientName.GivenName;
protocolname=info.ProtocolName;
% copyfile(‘source‘,‘destination‘)
sourceFileName=sprintf(‘%s%s‘,InFolderName,files(m).name);
destinationFolder=sprintf(‘%s/%s/%s‘,OutFolderName,char(patientname),char(protocolname));
copyfile(sourceFileName,destinationFolder)
end
end
clc;clear;close all;% 后面会用到的一个uniquecell函数所在位置
addpath(‘D:/MyMatlabFunctions‘);%% [1]读取一个文件夹里面全部的dicom文件InFolderName=‘H:/DATA_fMRI/‘;OutFolderName=‘D:/TestDataClassifier‘;files=dir(fullfile(InFolderName,‘*‘));%文件夹中的dcm文件没有后缀名时使用这句% files=dir(fullfile(filename,‘*.dcm‘));%文件夹中的dcm文件有.dcm后缀时使用这句%% [2]读取文件中的Header信息,主要是病人名字和序列名称name=cell(length(files),1);protocol=cell(length(files),1);% name_protocol=cell(length(files),2);cd(InFolderName);for i=1:length(files) if files(i).bytes~=0 % make sure it is not an empty file info=dicominfo(files(i).name); patientname=info.PatientName.GivenName; protocolname=info.ProtocolName; name(i)=cellstr(patientname); protocol(i)=cellstr(protocolname);% name_protocol(i,1)=(name(i));% name_protocol(i,2)=(protocol(i)); endend%% [3]把文件中包含的所有人的名字和序列提取出来,重复的只提取一个出来UniqueName=uniquecell(name);% 获取全部的病人的名字UniqueProtocol=uniquecell(protocol);% 获取包含的全部的序列名称%% [4] 产生准备把存数据的文件夹for i=1:1:length(UniqueName) if ~isequal(UniqueName(i),{[]})% 名字不是空的 OutNameFile=char(UniqueName(i)); mkdir(OutFolderName,OutNameFile); for j=1:1:length(UniqueProtocol) if ~isequal(UniqueProtocol(j),{[]}) % Protocol名字不是空的 OutProtocolFolder=strcat(OutFolderName,‘/‘,OutNameFile); OutProtocolName=UniqueProtocol(j); % OutProtocolName=char(UniqueProtocol(j)); mkdir(OutProtocolFolder,char(OutProtocolName)); end end endend%% [5] 把图片放到对应的文件夹里面去cd(InFolderName);for m=1:length(files) if files(m).bytes~=0 % make sure it is not an empty file info=dicominfo(files(m).name); patientname=info.PatientName.GivenName; protocolname=info.ProtocolName; % 如果有的图片的protocolname是空的,那么延续使用它前面的那个图的protocolname。 if isequal(protocolname,‘‘) protocolname=TMP_protocolname; end % 把dicom图像复制到要分类保存的文件夹下面 % copyfile(‘source‘,‘destination‘) sourceFileName=sprintf(‘%s%s‘,InFolderName,files(m).name); destinationFolder=sprintf(‘%s/%s/%s‘,OutFolderName,char(patientname),char(protocolname)); copyfile(sourceFileName,destinationFolder) %保存一个备选的protocolname,以防止下一个图片的protocolname是空的。 if ~isequal(protocolname,‘‘) TMP_protocolname=protocolname; end end end 代码文件uniquecell.mfunction [Au, idx ,idx2] = uniquecell(A) %function [Au, idx, idx2] = uniquecell(A) %For A a cell array of matrices (or vectors), returns %Au, which contains the unique matrices in A, idx, which contains %the indices of the last appearance of each such unique matrix, and %idx2, which contains th indices such that Au(idx2) == A % %Example usage: % %A = {[1,2,3],[0],[2,3,4],[2,3,1],[1,2,3],[0]}; %[Au,idx,idx2] = uniquecell(A); % %Results in: %idx = [6,5,4,3] %Au = {[0],[1,2,3],[2,3,1],[2,3,4]} %idx2 = [2,1,4,3,2,1] % %Algorithm: uses cellfun to translate numeric matrices into strings % then calls unique on cell array of strings and reconstructs % the initial matrices % %See also: unique B = cellfun(@(x) num2str(x(:)‘),A,‘UniformOutput‘,false); if nargout > 2 [~,idx,idx2] = unique(B); Au = A(idx); else [~,idx] = unique(B); Au = A(idx); end end
Dicom图像自动按照病人和扫描序列分类储存的matlab代码
原文:http://blog.csdn.net/quxiaoxia1986/article/details/69675704