在nema.org中解码无损jpeg DICOM文件

时间:2017-05-13 01:54:14

标签: jpeg dicom

几年前我写了一个jpeg压缩器/解压缩器,可以处理无损和有损的jpeg文件。它运行良好,但并不总是正确解码DICOM文件中的jpeg流。

我很了解jpeg,但我对DICOM知之甚少。 DICOM中的无损jpeg不可能符合jpeg ISO标准。必须进行一些修改,硬编码或由jpeg文件流之外的DICOM文件中的某个参数修改。

我的代码在大多数示例DICOM文件(compsamples_jpeg.tar)处失败: ftp://medical.nema.org/MEDICAL/Dicom/DataSets/WG04/

这是我解码此套装中的第一个无损jpeg(IMAGES \ JPLL \ CT1_JPLL)时会发生什么:

dicom decoded image

左图像是从我的代码渲染的,右边是由在线DICOM阅读器呈现的: www(点)ofoct(点)com(斜杠)查看器(斜杠)dicom-viewer-online(点)html

(x)MedCon是一个开源的DICOM读取器,它与我的代码完全相同,所以我不是唯一一个有这个问题的人。 xmedcon dot sourceforge dot net

我已逐字节读取了这个jpeg流,绘制了霍夫曼树并用铅笔和纸计算了霍夫曼代码,我的代码完全按照它应该做的去做。以下是霍夫曼代码:

  • 0 00
  • 4 01
  • 3 100
  • 5 101
  • 1 1100
  • 2 1101
  • 6 1110
  • 7 11110
  • 8 111110
  • 9 1111110
  • 12 11111110
  • 11 111111110
  • 10 1111111110
  • 15 11111111110

以下是SOS标记后的压缩数据:

  • ff 00 de 0c 00(ff为填充字节后的00)
  • 11111111 11011110 00001100 00000000
  • 11111111110 si = 15
  • 111100000110000 diff = 30768

在线观看者说第一个像素值是-3024。如果这是正确的,那么第一个diff值应该是-3024,但它不是。

在此之后,我的代码正确地解码了大约2/5的图像,但随后解码了一个非常不准确的diff值:

  • d2 a1 fe ff 00 e0(ff为填充字节后的00)
  • 1010111 10100001 11111110 11111111 11100000

  • 101 si = 5

  • 01111 diff = -16
  • 01 si = 4
  • 0000 diff = -15
  • 111111110 si = 11 ????
  • 11111111111 diff = 2047

如果您查看在线查看器解码的图像,此位置的像素强度没有根本变化,因此si = 11值不正确。

我确信我对jpeg有很好的理解,但DICOM中的jpeg流似乎不遵循jpeg标准。当jpeg流嵌入DICOM文件时,对它们进行了哪些扩展/更改?

2 个答案:

答案 0 :(得分:5)

DICOM指定使用ISO 10918,因此在DICOM图像中使用无损JPEG没有任何魔力,除了将已解码比特流的始终无符号输出重新解释为有符号(取决于像素表示)并将重新缩放斜率和截距应用于解码的"存储的像素值"进入任何"价值观"如Paolo所描述的,观众可以报告(例如,作为Hounsfield单位)。换句话说,不要依赖"像素值"观察者报告与解码比特流的直接输出相同。

作为参考,以下是DICOM中通常用于解决10918使用的部分:

http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_8.2.html#sect_8.2.1 http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_A.4.html#sect_A.4.1

DICOM编码器可能会将单个压缩帧拆分为单独的片段,就像此示例中故意使用碎片来测试解码能力的情况一样。我希望你知道这一点,并且已经注意重新组装压缩比特流跨越片段边界(即,删除片段之间固定长度的Item标签):

http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_A.4.html

虽然有些编码器可能有问题,但我不认为NEMA样本数据集中的IMAGES \ JPLL \ CT1_JPLL就是这种情况,这是我多年前使用Stanford PVRG编解码器创建的。

http://www.dclunie.com/pixelmed/software/codec/我自己的解码器(最小)与它没有任何问题。源是可用的,所以如果你想重新编译它,打开一些调试消息来跟踪每个解码值,预测器输入值,每行开头重启等,与你自己的逻辑进行比较,随意

最后,由于JPEG无损在DICOM之外很少使用,您可能会发现很难获得其他要测试的样本。我想到的一个问题是USF数字化乳房X线照相术集(医学,但不是DICOM),http://marathon.csee.usf.edu/Mammography/Database.html

大卫

PS。我确实检查了XMedCon在https://sourceforge.net/projects/xmedcon/使用的编解码器,它似乎使用了Cornell无损代码的一些副本;所以它可能容易受到BitBank所引用的帖子(https://groups.google.com/forum/#!topic/comp.protocols.dicom/Yl5GkZ8ggOE)中描述的相同错误或其他一些错误的影响。我没有尝试破译源代码来查看。

答案 1 :(得分:1)

第一个像素的值确实是-3024,因为在线dicom查看器说:

您正确地将第一个幅度解码为30768,但第一个像素的预测值设置为零,因此其实际值为32768 + 30768 = 63536。这是一个无符号值。

现在,像素表示标签表示文件值是b2补码(有符号),因此当我们使用最高有效位作为符号时,该值变为-2000。

当我们在rescale斜率截取标记(-1024)中应用该值时,第一个像素的值变为-3024。

但是,我的编解码器在第179行附近找不到任何幅度2047,所以也许你的编解码器会以某种方式失去同步:在后续行中也会看到同步丢失(它们都向右移动)