【问题标题】:Why should I subtract my pixel values of dicom image from 2^15 when I'm using dcmtk?使用 dcmtk 时,为什么要从 2^15 中减去 dicom 图像的像素值?
【发布时间】:2013-05-28 23:46:13
【问题描述】:

我正在使用 dcmtk 读取 dicom 图像,并且新样本具有以下属性:

(0028,0004) Photometric Interpretation: MONOCHROME2
(0028,0010) Rows: 512
(0028,0011) Columns: 512
(0028,0030) Pixel Spacing: 0.4688\0.4688
(0028,0100) Bits Allocated: 16
(0028,0101) Bits Stored: 16
(0028,0102) High Bit: 15
(0028,0103) Pixel Representation: 1
(0028,0106) Smallest Image Pixel Value: 0
(0028,0107) Largest Image Pixel Value: 2732
(0028,1050) Window Center: 1366
(0028,1051) Window Width: 2732

我使用 getOutputData(16) 来读取 int16_t 数据。这让我感到惊讶,因为这些值在 -1*(2^16) 附近是负数,当我将这些值减去 2^15 时,一切似乎都正常,我可以看到图像! :-(

现在我有两个问题:

  1. 为什么我要减去 2^15 的值才可以?图片上没有padding value
  2. getOutputData 的文档中,它谈到了渲染的像素数据总是无符号的。。由于 (0028,0103) 属性对我说,当我的图像数据被签名时,这意味着什么?如果这种方法不合适,我可以通过 dcmtk 获取真实数据吗?

【问题讨论】:

  • getOutputData 返回一个void *,并且(正如你自己提到的)根据documentation,输出数据始终是无符号的。那么你不应该将输出数据转换为uint16 吗?
  • 能否请您提供 Rescale Slope (0028,1053) 和 Rescale Intercept (0028, 1052),正如保罗建议的那样?

标签: c++ dicom imaging


【解决方案1】:

关键是像素表示 (0028,0106) 数据元素。

PixelRepresentation = 0 -> unsigned
PixelRepresentation = 1 -> signed

在您的情况下,您的值为“1”,因此您必须将这些值读取并解释为有符号整数。

您可以找到更多信息here

【讨论】:

  • 我知道。但这不是我问题的答案!我在那里阅读了附加信息。没有什么关于为什么我应该用 2^15 减去。
  • 这是计算 16 位数字的 two's complement 的操作。我的意思是,这是将解释为无符号整数的数字转换为解释为有符号整数的相同数字的操作。查看 2N 减法 部分
【解决方案2】:

从未使用过 dcmtk,但看起来您必须应用模态 VOI 的斜率/截距参数才能获得正确的数字。

请参阅 rescale slope and rescale interceptWindow width and center calculation of DICOM image

【讨论】:

  • 我在这里分享了整个标题:docs.google.com/document/d/…
  • 所以,没有重新调整数据元素。您是否尝试将像素数据读取为有符号整数,就像我在之前的回答中建议的那样?
【解决方案3】:

根据文档 getOutputData 在渲染之前应用演示文稿 VOI,因此您始终会获得未签名的数据。 因此,如果您要求 16 位数据,您将获得 0 到 65535 之间的像素,而不管数据集中指定的最小值和最大值是多少;这是因为返回的数据是要显示的,而不是存储在图像中的原始数据。 我认为您应该将值右移 8 位,或者只要求 8 位数据(即使图像是 16 位):我认为您的显卡无论如何都不能处理 16 位灰度。

【讨论】:

    【解决方案4】:

    DICOM 标头表示数据作为带符号值存储在 DICOM 文件中,但看起来文档说 getOutputData 将其转换为无符号值。因此,请尝试将 getOutputData 的输出读取为 uint16_t 而不是 int16_t。

    【讨论】:

    • 也许原因是原始值是负值。
    • uint_16 的范围是 0 到 65,535。 int_16 的范围为 –32,768 到 32,767。如果存储的值大于 32767,则设置第 16 位。这就是为什么如果你 int_16,它会显示为负数。
    【解决方案5】:

    我找到了答案。它已经由优秀的官方开发人员解释了here。见第2页。与DCMTK工具包完全相关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 2015-06-26
      • 2013-08-03
      • 2017-12-12
      相关资源
      最近更新 更多