如何读取带反斜杠的 DICOM 字符串值 (VR=LO, Value="0.4323[=10=].2325")?

How to read DICOM string value with backslash (VR=LO, Value="0.4323\0.2325")?

我们的C++软件使用ITK编写DICOM文件。在其中,我们有一个私人标签 LO(长字符串)作为 VR 和 2 个十进制值作为 0.3234[=16=].34223.

的值

LO 选择是 ITK 固有的。

在其他 java 应用程序中,我使用 dcm4che3 来 read/write 它们。由于它尊重 DICOM 协议,因此禁止反斜杠,并且 dcm4che 将该值解释为 "0.3234" 并且永远不会达到第二个值。

我使用的所有 DICOM 查看器应用程序都可以显示此值。

所以我的问题是:dcm4che 中是否有技巧可以将此完整值作为字符串 "0.3234[=19=].34223" 读取,尽管存在反斜杠?

下面,我使用的代码:

     public DicomInfo uploadFile(MultipartFile file) throws IOException, ParseException {

       DicomInfo infos = new DicomInfo();

       Attributes attrs = readDicomAttributes(file);
       infos.setTags(toAttributesObject(attrs).toString());
    }

    private static JsonObject toAttributesObject(Attributes targetSeriesAttrs) 
    {
       StringWriter strWriter = new StringWriter();
       JsonGenerator gen = Json.createGenerator(strWriter);
       JSONWriter writer = new JSONWriter(gen);
       writer.write(targetSeriesAttrs);
       gen.flush();
       gen.close();
       return Json.createReader(new 
          StringReader(strWriter.toString())).readObject();
  }
  
  public Attributes readDicomAttributes(MultipartFile file) throws IOException 
  {
    DicomInputStream dis = new DicomInputStream(file.getInputStream());
    Attributes dataSet = dis.readDataset(-1, Tag.PixelData);
    Attributes fmi = dis.readFileMetaInformation();
    dis.close();

    fmi.addAll(dataSet);

    return fmi;
  }

在 JSON 我得到这个标签:

\"00110013\":{\"vr\":\"LO\",\"Value\":[\"0.4323\"]},

正如你所见,它是LO,第二部分已经丢失了。

我使用的获取具体属性的方法:

attr.getStrings(0x00110013)

发回一个只有一个值 0.4323 的 table。

问题发生在 readDataSet 函数中。

当我用free dicom viewer之类的软件打开标签时,我有完整的数据,所以数据就在这里。


好的,我找到了问题的根源...它是 addAll fmi.addAll(dataSet);

在数据集中,getStrings 工作得很好。在fmi之后addAll,属性失去了第二个值。

所以我的问题是现在解决这个 addAll 问题:dcm4che3 java lib: Attributes.addAll method seems to lost multiple LO values

LO 可以有多个值,用反斜杠分隔。

DICOM 标准规定在 VR“LO”中不能在值中使用反斜杠,因为它用于分隔不同的元素。

在不允许多个元素的 VR 中,可以在值中使用反斜杠。

所以dcm4che这里是错误的

看到Paolo的回答,请相信我们,反斜杠没有违反VR。正如他所说,该属性是 2 维,即它具有 两个由反斜杠分隔的 VR LO 值

我对 dcm4che 项目及其背后的人了解一些,我几乎无法想象它通常无法处理这个问题。

我强烈怀疑您的问题与您的属性 private 有关。也就是说,如果没有标签及其值的任何附加信息,dcm4che(和任何其他产品)永远无法知道该属性的值被编码为 VR LO(长字符串)。

DICOM 中的默认传输语法是 Implicit Little Endian。这意味着,数据集不传达有关数据集中属性 VR 的 显式 信息。该信息由属性的Tag隐式编码,必须使用数据字典(DICOM Part 6)查找标签并获得对应的VR。显然,这仅适用于标准中定义的众所周知的 DICOM 标签,对私有标签无效。

因此,一种选择是尝试以显式小字节序对数据集进行编码,这意味着 VR 是数据集中属性编码的一部分。我希望这就足够了。

成熟的工具包(如 dcm4che)允许通过配置扩展数据字典,也就是说,您可以使用您的自定义标签扩展 takeit 使用的“官方”数据字典定义 - 包括 VR。所以在数据集本身没有明确给出VR的情况下,可以查找标签。

同样,我不是 dcm4che 的专家,但在 google 快速搜索“dcm4che private dictionary”会得到 this promising link.

我非常有信心您可以在 dcm4che 中解决问题,并且您不必迁移到其他工具包。

这个问题的解决方法是写

dataSet.addAll(fmi);
return dataSet;

而不是

fmi.AddAll(dataSet);
return fmi;

因为 addAll 方法丢失了私有 LO 的多个值