如何在 Python 中将 DICOM LUT 解码器与 gdcm 一起使用 - 传递缓冲区
How to use the DICOM LUT decoder with gdcm in Python - passing buffers
我需要考虑使用 GDCM for converting DICOM images to PNG-format. While this example works, it does not seem to take the LUT,因此我得到了 inverted/non-inverted 图像的混合。虽然我熟悉 C++ 和 Python,但我不能完全理解包装器中的黑魔法。该文档完全是用 C++ 编写的,我需要一些帮助来连接这些点。
主线任务
转换示例中的以下部分:
def gdcm_to_numpy(image):
....
gdcm_array = image.GetBuffer()
result = numpy.frombuffer(gdcm_array, dtype=dtype)
....
像这样:
def gdcm_to_numpy(image):
....
gdcm_array = image.GetBuffer()
lut = image.GetLUT()
gdcm_decoded = lut.Decode(gdcm_array)
result = numpy.frombuffer(gdcm_decoded, dtype=dtype)
....
现在出现错误:
NotImplementedError: Wrong number or type of arguments for overloaded function 'LookupTable_Decode'.
Possible C/C++ prototypes are:
gdcm::LookupTable::Decode(std::istream &,std::ostream &) const
gdcm::LookupTable::Decode(char *,size_t,char const *,size_t) const
通过查看 GetBuffer 定义,我猜第一个参数是分配的变量 bool GetBuffer(char *buffer) const;
。我想后一个 4 参数版本是我应该瞄准的版本。不幸的是,我不知道 size_t
参数应该是什么。我试过
gdcm_in_size = sys.getsizeof(gdcm_array)
gdcm_out_size = sys.getsizeof(gdcm_array)*3
gdcm_decoded = lut.Decode(gdcm_out_size, gdcm_array, gdcm_in_size)
还有
gdcm_in_size = ctypes.sizeof(gdcm_array)
gdcm_out_size = ctypes.sizeof(gdcm_array)*3
gdcm_decoded = lut.Decode(gdcm_out_size, gdcm_array, gdcm_in_size)
但没有成功。
更新 - 根据@malat 的建议
使用 ImageApplyLookupTable
进行测试
...
lutfilt = gdcm.ImageApplyLookupTable();
lutfilt.SetInput( image );
if (not lutfilt.Apply()):
print("Failed to apply LUT")
gdcm_decoded = lutfilt.GetOutputAsPixmap()\
.GetBuffer()
dtype = get_numpy_array_type(pf)
result = numpy.frombuffer(gdcm_decoded, dtype=dtype)
...
不幸的是,我打印了 "Failed to apply LUT" 图像,但图像仍然是倒置的。看下图,ImageJ表示它有一个反相LUT。
作为一个简单的解决方案,我会先应用 LUT。在这种情况下,您需要使用 ImageApplyLookupTable. It internally calls the gdcm::LookupTable API. See for example.
当然,正确的解决方案是传递 DICOM LUT 并将其转换为 PNG LUT。
更新:现在您已经发布了屏幕截图。我明白你这边的情况。您不是在尝试应用 DICOM 查找 Table,而是在尝试更改两个不同光度学解释 DICOM 数据集的渲染,即 MONOCHROME1 与 MONOCHROME2。
在这种情况下,您可以通过使用以下软件实现来更改它:gdcm.ImageChangePhotometricInterpretation。从技术上讲,这种类型的渲染最好使用您的图形卡来完成(但那是另一回事)。
我需要考虑使用 GDCM for converting DICOM images to PNG-format. While this example works, it does not seem to take the LUT,因此我得到了 inverted/non-inverted 图像的混合。虽然我熟悉 C++ 和 Python,但我不能完全理解包装器中的黑魔法。该文档完全是用 C++ 编写的,我需要一些帮助来连接这些点。
主线任务
转换示例中的以下部分:
def gdcm_to_numpy(image):
....
gdcm_array = image.GetBuffer()
result = numpy.frombuffer(gdcm_array, dtype=dtype)
....
像这样:
def gdcm_to_numpy(image):
....
gdcm_array = image.GetBuffer()
lut = image.GetLUT()
gdcm_decoded = lut.Decode(gdcm_array)
result = numpy.frombuffer(gdcm_decoded, dtype=dtype)
....
现在出现错误:
NotImplementedError: Wrong number or type of arguments for overloaded function 'LookupTable_Decode'.
Possible C/C++ prototypes are:
gdcm::LookupTable::Decode(std::istream &,std::ostream &) const
gdcm::LookupTable::Decode(char *,size_t,char const *,size_t) const
通过查看 GetBuffer 定义,我猜第一个参数是分配的变量 bool GetBuffer(char *buffer) const;
。我想后一个 4 参数版本是我应该瞄准的版本。不幸的是,我不知道 size_t
参数应该是什么。我试过
gdcm_in_size = sys.getsizeof(gdcm_array)
gdcm_out_size = sys.getsizeof(gdcm_array)*3
gdcm_decoded = lut.Decode(gdcm_out_size, gdcm_array, gdcm_in_size)
还有
gdcm_in_size = ctypes.sizeof(gdcm_array)
gdcm_out_size = ctypes.sizeof(gdcm_array)*3
gdcm_decoded = lut.Decode(gdcm_out_size, gdcm_array, gdcm_in_size)
但没有成功。
更新 - 根据@malat 的建议
使用ImageApplyLookupTable
进行测试
...
lutfilt = gdcm.ImageApplyLookupTable();
lutfilt.SetInput( image );
if (not lutfilt.Apply()):
print("Failed to apply LUT")
gdcm_decoded = lutfilt.GetOutputAsPixmap()\
.GetBuffer()
dtype = get_numpy_array_type(pf)
result = numpy.frombuffer(gdcm_decoded, dtype=dtype)
...
不幸的是,我打印了 "Failed to apply LUT" 图像,但图像仍然是倒置的。看下图,ImageJ表示它有一个反相LUT。
作为一个简单的解决方案,我会先应用 LUT。在这种情况下,您需要使用 ImageApplyLookupTable. It internally calls the gdcm::LookupTable API. See for example.
当然,正确的解决方案是传递 DICOM LUT 并将其转换为 PNG LUT。
更新:现在您已经发布了屏幕截图。我明白你这边的情况。您不是在尝试应用 DICOM 查找 Table,而是在尝试更改两个不同光度学解释 DICOM 数据集的渲染,即 MONOCHROME1 与 MONOCHROME2。
在这种情况下,您可以通过使用以下软件实现来更改它:gdcm.ImageChangePhotometricInterpretation。从技术上讲,这种类型的渲染最好使用您的图形卡来完成(但那是另一回事)。