如何读取带反斜杠的DICOM字符串值(VR=LO,值="0.4323\0.2325")?

huangapple go评论57阅读模式
英文:

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

问题

我们的C++软件使用ITK来编写DICOM文件。在其中,我们有一个私有标签,VRLO(长字符串),值为2个小数值,例如0.3234\0.34223

LO的选择是ITK固有的。

在其他Java应用程序中,我使用dcm4che3来读取/写入它们。由于它遵循DICOM协议,反斜杠是禁止的,dcm4che会将该值解释为"0.3234",并永远不会到达第二个值。

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

所以我的问题是:在dcm4che中是否有一种方法可以读取这个完整的值作为字符串"0.3234\0.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的表格。

问题发生在readDataSet函数中。

当我使用类似于免费的DICOM查看器等软件打开标签时,我可以看到完整的数据,所以数据是存在的。


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

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

所以我的问题现在是解决这个addAll问题:https://stackoverflow.com/q/63269682/5704707

英文:

Our C++ software use ITK to write DICOM files. In it we have a Private Tag with LO (Long String) as VR and 2 decimal values as value like 0.3234\0.34223.

The LO choice is inherent to ITK.

In other java application, I use dcm4che3 to read/write them. Since it respects the DICOM protocol, backslash are forbidden, and dcm4che interpret the value as "0.3234" and never reach the second value.

All DICOM viewer applications I use can display this value.

So my question is: Is there a trick in dcm4che to read this complete value as a string "0.3234\0.34223" despite the presence of a backslash?

Below, the code I use:

     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;
  }

In the JSON I get for this tag:

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

As you can see it is LO and the second part is already lost.

The method I use to get the specific attribute:

attr.getStrings(0x00110013)

send back a table with only one value, 0.4323.

The problem happens during the readDataSet function.

When I open tags with software like free dicom viewer, I have the complete data, so data is here.


Ok I found the source of the problem... It is the addAll fmi.addAll(dataSet);

In dataSet, getStrings works perfectly. In fmi after addAll, the attributes lost the second value.

So my problem is to solve this addAll issue now: https://stackoverflow.com/q/63269682/5704707

答案1

得分: 1

请参考Paolo的答案,并请相信我们,反斜杠不违反VR规定。就像他所说,该属性是二维的,即它有两个由反斜杠分隔的VR LO值

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

我强烈怀疑您的问题与您的属性是私有的这一事实有关。也就是说,在没有任何有关标签及其值的附加信息的情况下,dcm4che(以及任何其他产品)永远不会知道该属性的值编码为VR LO(长字符串)。

DICOM中的默认传输语法是隐式小尾数。这意味着数据集不提供关于数据集中属性的VR的显式信息。该信息通过属性的标签进行隐式编码,并且必须使用数据字典(DICOM Part 6)来查找标签并获取相应的VR。显然,这仅适用于标准中定义的众所周知的DICOM标签,对于私有标签则会失败。

因此,一种选择是尝试以显式小尾数编码数据集,这意味着VR是数据集中属性编码的一部分。我期望这足以解决问题。

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

再次强调,我不是dcm4che的专家,但是在Google上快速搜索“dcm4che私有字典”会出现这个有希望的链接

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

英文:

See answer from Paolo, and please believe us that the backslash is not a violation of the VR. Like he said, the attribute is 2-dimensional, i.e. it has two values of VR LO which are separated by the backslash.

I know a bit about the dcm4che project and the people behind it, and it is nearly unthinkable to me that it is generally incapable of handling this.

I strongly suspect that your problem is related to the fact that your attribute is private. That is, without any additional information to the tag and its value, dcm4che (and any other product) can never know that the attribute's value is encoded as VR LO (Long String).

The default transfer syntax in DICOM is Implicit Little Endian. This means, that the dataset does not convey an explicit information about the VR of the attributes in the dataset. This information is implicitly encoded by the Tag of the attribute, and the data dictionary (DICOM Part 6) must be used to look up the tag and obtain the corresponding VR. Obvioulsy this only works for well-known DICOM tags defined in the standard and fails for private ones.

So one option is to try encoding the dataset in Explicit Little Endian, which means that the VR is part of the attribute's encoding in the dataset. I would expect this to be sufficient.

Mature toolkits (like dcm4che) allow for extending the data dictionary by configuration, that is, you can extend the "official" data dictionary used by the tookit with your custom tag definitions - including the VR. So the tag can be looked up in the case that the VR is not explicitly given in the dataset itself.

Again, I am not an expert for dcm4che, but a quick search at google for "dcm4che private dictionary" yields this promising link.

I am more than confident that you can solve the problem in dcm4che and that you do not have to migrate to a different toolkit.

答案2

得分: 1

问题的解决方案是编写:

dataSet.addAll(fmi);
return dataSet;

而不是:

fmi.AddAll(dataSet);
return fmi;

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

英文:

The solution of this problem is to write

dataSet.addAll(fmi);
return dataSet;

instead of

fmi.AddAll(dataSet);
return fmi;

since the addAll methods lost multiple values of private LO

答案3

得分: 0

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

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

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

所以dcm4che在这里是错误的。

英文:

LO can have multiple values separated by a backslash.

The DICOM standard says that in the VR "LO" the backslash cannot be used in values because it is used to separate the different elements.

In VRs that don't allow multiple elements then the backslash can be used in values.

So dcm4che is wrong here.

huangapple
  • 本文由 发表于 2020年7月30日 21:59:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63174818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定