2015-01-21 5 views
0

dicom 이미지를 처리하기 위해 pydicom을 사용하고 싶었습니다. 내가 변수 format_str를 인쇄 할 때 불행하게도 나는 기능pydicom 함수의 버그

def _pixel_data_numpy(self): 
"""Return a NumPy array of the pixel data. 

NumPy is a numerical package for python. It is used if available. 

:raises TypeError: if no pixel data in this dataset. 
:raises ImportError: if cannot import numpy. 

""" 
if 'PixelData' not in self: 
    raise TypeError("No pixel data found in this dataset.") 

if not have_numpy: 
    msg = "The Numpy package is required to use pixel_array, and numpy could not be imported.\n" 
    raise ImportError(msg) 

# determine the type used for the array 
need_byteswap = (self.is_little_endian != sys_is_little_endian) 

# Make NumPy format code, e.g. "uint16", "int32" etc 
# from two pieces of info: 
# self.PixelRepresentation -- 0 for unsigned, 1 for signed; 
# self.BitsAllocated -- 8, 16, or 32 
format_str = '%sint%d' % (('u', '')[self.PixelRepresentation], 
          self.BitsAllocated) 
try: 
    numpy_format = numpy.dtype(format_str) 
print numpy_format 
except TypeError: 
print "Data type not understood by NumPy!" 
print format_str 
    msg = ("Data type not understood by NumPy: " 
      "format='%s', PixelRepresentation=%d, BitsAllocated=%d") 
    raise TypeError(msg % (numpy_format, self.PixelRepresentation, 
        self.BitsAllocated)) 

# Have correct Numpy format, so create the NumPy array 
arr = numpy.fromstring(self.PixelData, numpy_format) 

# XXX byte swap - may later handle this in read_file!!? 
if need_byteswap: 
    arr.byteswap(True) # True means swap in-place, don't make a new copy 
# Note the following reshape operations return a new *view* onto arr, but don't copy the data 
if 'NumberOfFrames' in self and self.NumberOfFrames > 1: 
    if self.SamplesPerPixel > 1: 
     arr = arr.reshape(self.SamplesPerPixel, self.NumberOfFrames, self.Rows, self.Columns) 
    else: 
     arr = arr.reshape(self.NumberOfFrames, self.Rows, self.Columns) 
else: 
    if self.SamplesPerPixel > 1: 
     if self.BitsAllocated == 8: 
      arr = arr.reshape(self.SamplesPerPixel, self.Rows, self.Columns) 
     else: 
      raise NotImplementedError("This code only handles SamplesPerPixel > 1 if Bits Allocated = 8") 
    else: 
     arr = arr.reshape(self.Rows, self.Columns) 
return arr 

에 오류

File "/usr/local/lib/python2.7/dist-packages/dicom/dataset.py", line 372, in _pixel_data_numpy 
    raise TypeError(msg % (numpy_format, self.PixelRepresentation, 
UnboundLocalError: local variable 'numpy_format' referenced before assignment 

을 얻을, 나는 uint12를 얻을. 불행히도이 버그를 해결할 수 없습니다. 그 문제를 해결하기 위해 내가 할 수있는 일이 있습니까?
print 명령 (모두 디버그 용으로 추가 한 명령)을 제거하더라도 동일한 오류가 발생합니다. 내가 코드를 있으리라 믿고있어

답변

0

이 같은 포맷을 의미한다 :

try: 
    numpy_format = numpy.dtype(format_str) 
    print numpy_format 
except TypeError: 
    print "Data type not understood by NumPy!" 
    print format_str 
    msg = ("Data type not understood by NumPy: " 
      "format='%s', PixelRepresentation=%d, BitsAllocated=%d") 
    raise TypeError(msg % (numpy_format, self.PixelRepresentation, 
        self.BitsAllocated)) 

try 블록에서 numpy_format에 값이 할당됩니다. numpy.dtype(format_str)TypeError 인 경우 numpy_format 값을 바인딩하지 않고 곧바로 except 블록으로 이동합니다. 이것은 이 TypeError을 일으킬 때 다시 참조 될 때, 처음에 바인딩되지 않았으므로 UnboundLocalError을 던집니다.

+0

문제는 모든 인쇄 명령을 제거해도 버그가 여전히 발생한다는 것입니다. –

2

여기에는 두 가지 문제가 있습니다. 첫째, pydicom의 버그 : 오류 발생시 정의되지 않은 numpy_format을 잘못 사용하고 있습니다. format_str을 사용해야합니다. 이 문제를 해결하기 위해 문제를 추가하겠습니다.

두 번째 문제는 파일의 BitsAllocated가 12인데 매우 드문 경우입니다. DICOM 파일은 일반적으로 12 비트 픽셀 값을 갖지만 파일에서 픽셀 당 16 비트를 사용합니다.

RowsColumns을 픽셀 데이터의 크기와 비교하여 실제로 할당 된 것을 확인할 수 있습니다. 단일 프레임 이미지의 경우 (예를 아래에 pydicom의 CT_small.dcm 샘플 파일을 사용) : 이미지가 여러 프레임이

>>> len(ds.PixelData) 
32768 
>>> ds.Rows * ds.Columns * 2 # 2 bytes for 16-bit allocation 
32768 

경우, 당신은뿐만 아니라 프레임의 수를 곱해야합니다. SamplesPerPixel에 대해서도 마찬가지입니다.

픽셀 당 2 바이트를 사용하여 픽셀 데이터의 크기가 위와 일치하면 pixel_array을 요청하기 전에 ds.BitsAllocated을 16으로 설정하여 문제를 해결할 수 있습니다.