Мне нужно использовать GDCM для преобразования изображений DICOM в формат PNG. В то время как этот пример работает, кажется, не берет LUT во внимание, и, таким образом, я получаю смесь инвертированных / неинвертированных изображений. Хотя я знаком и с 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)
но безуспешно
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)
...
К сожалению, я получил «Не удалось применить LUT», и изображения все еще инвертированы. Смотрите изображение ниже, ImageJ предполагает, что у него есть инвертирующая LUT.
В качестве простого решения я бы сначала применил LUT. В этом случае вам нужно использовать ImageApplyLookupTable. Внутренне вызывает gdcm :: LookupTable API. Смотрите для пример.
Конечно, правильным решением было бы передать DICOM LUT и преобразовать его в PNG LUT.
Обновление: теперь, когда вы опубликовали скриншот. Я понимаю, что происходит на вашей стороне. Вы не пытаетесь применить таблицу поиска DICOM, вы пытаетесь изменить рендеринг двух разных наборов данных фотометрической интерпретации DICOM, а именно MONOCHROME1 против MONOCHROME2.
В этом случае вы можете изменить это с помощью программной реализации с помощью: gdcm.ImageChangePhotometricInterpretation. Технически этот тип рендеринга лучше всего делать с помощью вашей графической карты (но это другая история).