Dicom图像自动按照病人和扫描序列分类储存的matlab代码


写了一个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

代码文件‘DicomClassifier_V2.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)); 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.m

function [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



评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值