【问题标题】:dicom header personal information conversion to a .txt filedicom header 个人信息转换为.txt文件
【发布时间】:2017-06-07 04:35:30
【问题描述】:

我有一系列想要匿名的 DICOM 图像,我发现很少有 Matlab 代码和一些可以完成这项工作的程序,但它们都没有导出已删除个人信息的 .txt 文件。我想知道是否有一个功能可以将已删除的 DICOM 图像的个人信息保存为 .txt 格式以供功能使用。另外,我正在尝试创建一个表格,显示与其真实姓名相对应的新图像 ID。(主题真实姓名 = 删除个人信息的图像 ID)

有什么想法吗?

感谢您考虑我的要求!

【问题讨论】:

    标签: matlab dicom


    【解决方案1】:

    我猜您只想将由anonymization(修改、删除或添加)更改的字段输出到您的文本文件。首先,您可能需要修改一些 dicomanon 选项以减少更改次数,尤其是传递参数 'WritePrivate', true 以确保保留私有扩展。

    首先,您可以使用dicominfo 执行匿名化,保存匿名化前后元数据的结构:

    preAnonData = dicominfo('input_file.dcm');
    dicomanon('input_file.dcm', 'output_file.dcm', 'WritePrivate', true);
    postAnonData = dicominfo('output_file.dcm');
    

    然后可以使用fieldnamessetdiff查找被匿名化删除或添加的字段,分别添加到匿名化后或匿名化前的数据中,以nan值作为位置持有人:

    preFields = fieldnames(preAnonData);
    postFields = fieldnames(postAnonData);
    
    removedFields = setdiff(preFields, postFields);
    for iField = 1:numel(removedFields)
      postAnonData.(removedFields{iField}) = nan;
    end
    
    addedFields = setdiff(postFields, preFields);
    for iField = 1:numel(addedFields)
      preAnonData.(addedFields{iField}) = nan;
    end
    

    使用orderfields 也很有帮助,这样两个数据结构的字段名称顺序相同:

    postAnonData = orderfields(postAnonData, preAnonData);
    

    最后,现在每个结构都具有相同顺序的相同字段,我们可以使用struct2cell 将其字段数据转换为元胞数组,并使用cellfunisequal 查找已被修改的任何字段匿名化:

    allFields = fieldnames(preAnonData);
    preAnonCell = struct2cell(preAnonData);
    postAnonCell = struct2cell(postAnonData);
    index = ~cellfun(@isequal, preAnonCell, postAnonCell);
    modFields = allFields(index);
    

    现在您可以创建一个 table 的更改,如下所示:

    T = table(modFields, preAnonCell(index), postAnonCell(index), ...
              'VariableNames', {'Field', 'PreAnon', 'PostAnon'});
    

    您可以使用writetable 轻松将表格数据输出到文本文件:

    writetable(T, 'anonymized_data.txt');
    

    但是请注意,如果表中的任何字段包含数据的向量或结构,则输出文件的格式可能看起来有点古怪(即很多列,其中大部分是空的,除了那几个字段)。

    【讨论】:

    • 非常感谢您详细说明这些要求。我运行了您的代码,但出现此错误:“使用 cellfun 时出错所有输入参数必须具有相同的大小和形状。以前的输入在维度 1 中的大小为 155。输入 #3 的大小为 106”这似乎是合乎逻辑的,因为某些部分向量已被删除,知道吗?
    • @mohammadreza:我在回答中添加了注释来解释问题以及如何解决它。
    • 感谢您的回复,我将 'WritePrivate' 形式 'false' 更改为 'true',但我得到了相同的错误,只需稍作改动:使用 cellfun 时出错所有输入参数必须相同尺寸和形状。以前的输入在维度 1 中的大小为 155。输入 #3 的大小为 147。Untitled22 中的错误(第 10 行)索引 = ~cellfun(@isequal, preAnonCell, postAnonCell);
    • 我添加了您的“注释脚本”,但出现此错误:动态结构引用的参数必须评估为有效的字段名称。 Untitled22 中的错误(第 8 行) postAnonData.(missingFields(iField)) = nan; % 或其他占位符
    • @mohammadreza:有一个错字(我们需要大括号)。它现在应该可以工作了。
    【解决方案2】:

    做到这一点的一种方法是在匿名化之前和之后存储标签,并使用它们来编写您的文本文件。在 Matlab 中,dicominfo() 会将标签读入结构中:

    % Get tags before anonymization
    tags_before = dicominfo(file_in);
    
    % Anoymize
    dicomanon(file_in, file_out); % Need to set tags values where required
    
    % Get tags after anonymization
    tags_after = dicominfo(file_out);
    
    % Do something with the two structures
    disp(['Patient ID:', tags_before.PatientID ' -> ' tags_after.PatientID]);
    disp(['Date of Birth:', tags_before.PatientBirthDate ' -> ' tags_after.PatientBirthDate]);
    disp(['Family Name:', tags_before.PatientName.FamilyName ' -> ' tags_after.PatientName.FamilyName]);
    

    然后您可以将之前/之后的字段写入文本文件。您需要修改 dicomanon() 为已删除字段选择您自己的值,因为默认情况下它们设置为空。

    【讨论】:

    • 感谢您的回复,但我收到此错误:使用存在时出错 存在的第一个输入必须是字符串。 dicom_get_msg 中的错误(第 18 行) if (exist(file.Filename) ~= 2) dicominfo>getFileDetails 中的错误(第 387 行)file = dicom_get_msg(file); dicominfo 中的错误(第 36 行)fileDetails = getFileDetails(filename); Untitled2 中的错误(第 2 行) tags_before = dicominfo(660);
    • file_indicominfo(file_in) 的参数需要是字符串,即 DICOM 文件的路径和文件名。该错误表明您正在传递数字、文件句柄或其他内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2016-02-13
    • 2020-03-20
    • 2015-05-08
    相关资源
    最近更新 更多