def get_pixeldata(ds: "Dataset") -> "numpy.ndarray": """Return the *Pixel Data* as a :class:`numpy.ndarray`. Returns ------- numpy.ndarray A correctly sized (but not shaped) numpy array of the *Pixel Data*. Raises ------ ImportError If the required packages are not available. NotImplementedError If the transfer syntax is not supported. TypeError If the pixel data type is unsupported. """ tsyntax = ds.file_meta.TransferSyntaxUID if tsyntax not in SUPPORTED_TRANSFER_SYNTAXES: raise NotImplementedError( f"The jpeg_ls does not support this transfer syntax {tsyntax.name}" ) if not HAVE_JPEGLS: raise ImportError( "The jpeg_ls package is required to use pixel_array for this " f"transfer syntax {tsyntax.name}, and jpeg_ls could not be " "imported") pixel_bytes = bytearray() nr_frames = getattr(ds, "NumberOfFrames", 1) or 1 if nr_frames > 1: for src in decode_data_sequence(ds.PixelData): frame = jpeg_ls.decode(numpy.frombuffer(src, dtype='u1')) pixel_bytes.extend(frame.tobytes()) else: src = defragment_data(ds.PixelData) frame = jpeg_ls.decode(numpy.frombuffer(src, dtype='u1')) pixel_bytes.extend(frame.tobytes()) arr = numpy.frombuffer(pixel_bytes, pixel_dtype(ds)) if should_change_PhotometricInterpretation_to_RGB(ds): ds.PhotometricInterpretation = "RGB" return cast("numpy.ndarray", arr)
def test_encode_decode_compare_uint8(self): data, meta = data_io.read(self.fname) # Compress, decompress. data_comp = jls.encode(data) data_image = jls.decode(data_comp) diff = np.sum( (data.squeeze().astype(np.int) - data_image.astype(np.int))**2) self.assertTrue(diff == 0)
def _get_jpeg_ls_supported_compressed_pixeldata(self): if not have_jpeg_ls: msg = "The jpeg_ls package is required to use pixel_array for this transfer syntax {0}, and jpeg_ls could not be imported.".format(self.file_meta.TransferSyntaxUID) raise ImportError(msg) # decompress here UncompressedPixelData = '' if 'NumberOfFrames' in self and self.NumberOfFrames > 1: # multiple compressed frames CompressedPixelDataSeq = pydicom.encaps.decode_data_sequence(self.PixelData) # print len(CompressedPixelDataSeq) for frame in CompressedPixelDataSeq: decompressed_image = jpeg_ls.decode(numpy.fromstring(frame, dtype=numpy.uint8)) UncompressedPixelData += decompressed_image.tobytes() else: # single compressed frame CompressedPixelData = pydicom.encaps.defragment_data(self.PixelData) decompressed_image = jpeg_ls.decode(numpy.fromstring(CompressedPixelData, dtype=numpy.uint8)) UncompressedPixelData = decompressed_image.tobytes() return UncompressedPixelData
def open_files(path): dicom = pydicom.read_file(path) # print(type(dicom.PixelData)) # with open('/tmp/output.jp2', 'wb') as f: f.write(np.frombuffer( # dicom.PixelData, dtype=np.uint8, offset=0x10)) try: img = dicom.pixel_array except: import jpeg_ls img = jpeg_ls.decode( np.frombuffer(dicom.PixelData, dtype=np.uint8, offset=0x10)) # img = Image.frombuffer(np.frombuffer( # dicom.PixelData, dtype=np.uint8, offset=0x10), 'jpeg2000') return img.astype(np.float32)
def _retrieve_instance_frames(args): '''Retrieves frames for an individual instances and either writes them to standard output or files on disk or displays them in a GUI (depending on the requested content type). Frames can only be saved and shown if they are retrieved using image media types. ''' client = DICOMwebClient(args.url, username=args.username, password=args.password, ca_bundle=args.ca_bundle, cert=args.cert) pixel_data = client.retrieve_instance_frames( args.study_instance_uid, args.series_instance_uid, args.sop_instance_uid, args.frame_numbers, media_types=args.media_types, ) for i, data in enumerate(pixel_data): if args.save or args.show: try: image = Image.open(BytesIO(data)) except Exception: try: import jpeg_ls image = jpeg_ls.decode(np.fromstring(data, dtype=np.uint8)) except Exception: raise IOError('Cannot load retrieved frame as an image.') if args.save: filename = ( '{sop_instance_uid}_{frame_number}.{extension}'.format( sop_instance_uid=args.sop_instance_uid, frame_number=args.frame_numbers[i], extension=image.format.lower())) filepath = os.path.join(args.output_dir, filename) _save_image(image, filepath) elif args.show: _show_image(image) else: _print_pixel_data(data)
def get_pixeldata(dicom_dataset): """ Use the jpeg_ls package to decode the PixelData attribute Returns ------- numpy.ndarray A correctly sized (but not shaped) numpy array of the entire data volume Raises ------ ImportError if the required packages are not available NotImplementedError if the transfer syntax is not supported TypeError if the pixel data type is unsupported """ if (dicom_dataset.file_meta.TransferSyntaxUID not in JPEGLSSupportedTransferSyntaxes): msg = ("The jpeg_ls does not support " "this transfer syntax {0}.".format( dicom_dataset.file_meta.TransferSyntaxUID)) raise NotImplementedError(msg) if not have_jpeg_ls: msg = ("The jpeg_ls package is required to use pixel_array " "for this transfer syntax {0}, and jpeg_ls could not " "be imported.".format( dicom_dataset.file_meta.TransferSyntaxUID)) raise ImportError(msg) # Make NumPy format code, e.g. "uint16", "int32" etc # from two pieces of info: # dicom_dataset.PixelRepresentation -- 0 for unsigned, 1 for signed; # dicom_dataset.BitsAllocated -- 8, 16, or 32 if dicom_dataset.PixelRepresentation == 0: format_str = 'uint{}'.format(dicom_dataset.BitsAllocated) elif dicom_dataset.PixelRepresentation == 1: format_str = 'int{}'.format(dicom_dataset.BitsAllocated) else: format_str = 'bad_pixel_representation' try: numpy_format = numpy.dtype(format_str) except TypeError: msg = ("Data type not understood by NumPy: " "format='{}', PixelRepresentation={}, " "BitsAllocated={}".format( format_str, dicom_dataset.PixelRepresentation, dicom_dataset.BitsAllocated)) raise TypeError(msg) if (dicom_dataset.is_little_endian != sys_is_little_endian): numpy_format = numpy_format.newbyteorder('S') # decompress here UncompressedPixelData = b'' if ('NumberOfFrames' in dicom_dataset and dicom_dataset.NumberOfFrames > 1): # multiple compressed frames CompressedPixelDataSeq = pydicom.encaps.decode_data_sequence( dicom_dataset.PixelData) # print len(CompressedPixelDataSeq) for frame in CompressedPixelDataSeq: decompressed_image = jpeg_ls.decode( numpy.fromstring(frame, dtype=numpy.uint8)) UncompressedPixelData += decompressed_image.tobytes() else: # single compressed frame CompressedPixelData = pydicom.encaps.defragment_data( dicom_dataset.PixelData) decompressed_image = jpeg_ls.decode( numpy.fromstring(CompressedPixelData, dtype=numpy.uint8)) UncompressedPixelData = decompressed_image.tobytes() pixel_array = numpy.fromstring(UncompressedPixelData, numpy_format) if should_change_PhotometricInterpretation_to_RGB(dicom_dataset): dicom_dataset.PhotometricInterpretation = "RGB" return pixel_array
import os import data_io import jpeg_ls # Read in an image from an existing PNG file. fname_img = 'test/gray_raw.png' data_image = data_io.read_PIL(fname_img) # This input image should be a numpy array. print('\nData properties:') print('Type: {:s}'.format(data_image.dtype)) print('Shape: {:s}'.format(data_image.shape)) # Compress image data to a sequence of bytes. data_buffer = jpeg_ls.encode(data_image) # Sizes. size_png = os.path.getsize(fname_img) print('\nSize of uncompressed image data: {:n}'.format(len(data_image.tostring()))) print('Size of PNG encoded data file: {:n}'.format(size_png)) print('Size of JPEG-LS encoded data: {:n}'.format(len(data_buffer))) # Decompress. data_image_b = jpeg_ls.decode(data_buffer) # Compare image data, before and after. is_same = (data_image == data_image_b).all() print('\nRestored data is identical to original? {:s}\n'.format(str(is_same)))
def get_pixeldata(dicom_dataset): """Return the *Pixel Data* as a :class:`numpy.ndarray`. Returns ------- numpy.ndarray A correctly sized (but not shaped) numpy array of the *Pixel Data*. Raises ------ ImportError If the required packages are not available. NotImplementedError If the transfer syntax is not supported. TypeError If the pixel data type is unsupported. """ if (dicom_dataset.file_meta.TransferSyntaxUID not in SUPPORTED_TRANSFER_SYNTAXES): msg = ("The jpeg_ls does not support " "this transfer syntax {0}.".format( dicom_dataset.file_meta.TransferSyntaxUID.name)) raise NotImplementedError(msg) if not HAVE_JPEGLS: msg = ("The jpeg_ls package is required to use pixel_array " "for this transfer syntax {0}, and jpeg_ls could not " "be imported.".format( dicom_dataset.file_meta.TransferSyntaxUID.name)) raise ImportError(msg) # Make NumPy format code, e.g. "uint16", "int32" etc # from two pieces of info: # dicom_dataset.PixelRepresentation -- 0 for unsigned, 1 for signed; # dicom_dataset.BitsAllocated -- 8, 16, or 32 if dicom_dataset.PixelRepresentation == 0: format_str = 'uint{}'.format(dicom_dataset.BitsAllocated) elif dicom_dataset.PixelRepresentation == 1: format_str = 'int{}'.format(dicom_dataset.BitsAllocated) else: format_str = 'bad_pixel_representation' try: numpy_format = numpy.dtype(format_str) except TypeError: msg = ("Data type not understood by NumPy: " "format='{}', PixelRepresentation={}, " "BitsAllocated={}".format( format_str, dicom_dataset.PixelRepresentation, dicom_dataset.BitsAllocated)) raise TypeError(msg) numpy_format = dtype_corrected_for_endianness( dicom_dataset.is_little_endian, numpy_format) # decompress here UncompressedPixelData = bytearray() if ('NumberOfFrames' in dicom_dataset and dicom_dataset.NumberOfFrames > 1): # multiple compressed frames CompressedPixelDataSeq = pydicom.encaps.decode_data_sequence( dicom_dataset.PixelData) # print len(CompressedPixelDataSeq) for frame in CompressedPixelDataSeq: decompressed_image = jpeg_ls.decode( numpy.frombuffer(frame, dtype=numpy.uint8)) UncompressedPixelData.extend(decompressed_image.tobytes()) else: # single compressed frame CompressedPixelData = pydicom.encaps.defragment_data( dicom_dataset.PixelData) decompressed_image = jpeg_ls.decode( numpy.frombuffer(CompressedPixelData, dtype=numpy.uint8)) UncompressedPixelData.extend(decompressed_image.tobytes()) pixel_array = numpy.frombuffer(UncompressedPixelData, numpy_format) if should_change_PhotometricInterpretation_to_RGB(dicom_dataset): dicom_dataset.PhotometricInterpretation = "RGB" return pixel_array
from . import data_io import jpeg_ls # Read in an image from an existing PNG file. fname_img = 'test/gray_raw.png' data_image = data_io.read_PIL(fname_img) # This input image should be a numpy array. print('\nData properties:') print('Type: {:s}'.format(data_image.dtype)) print('Shape: {:s}'.format(data_image.shape)) # Compress image data to a sequence of bytes. data_buffer = jpeg_ls.encode(data_image) # Sizes. size_png = os.path.getsize(fname_img) print('\nSize of uncompressed image data: {:n}'.format( len(data_image.tostring()))) print('Size of PNG encoded data file: {:n}'.format(size_png)) print('Size of JPEG-LS encoded data: {:n}'.format(len(data_buffer))) # Decompress. data_image_b = jpeg_ls.decode(data_buffer) # Compare image data, before and after. is_same = (data_image == data_image_b).all() print('\nRestored data is identical to original? {:s}\n'.format(str(is_same)))