Пример #1
0
 def setup(self):
     """Setup the tests."""
     # Create a dataset skeleton for use in the cycle tests
     ds = Dataset()
     ds.file_meta = FileMetaDataset()
     ds.file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
     ds.Rows = 2
     ds.Columns = 4
     ds.SamplesPerPixel = 3
     ds.PlanarConfiguration = 1
     self.ds = ds
Пример #2
0
def nii2dicom(ni, ds):
    if len(ni.shape) == 3:
        I, J, K = ni.shape
        T = 1
    elif len(ni.shape) == 4:
        I, J, K, T = ni.shape
    else:
        raise (Exception(f"tried to convert nifti with shape {ni.shape}"))

    orientation = ni.affine
    orientation33 = orientation[:3, :3]
    image_position0 = orientation[:3, 3]

    pixel_spacing = list(
        map(np.linalg.norm, [orientation[:3, 0], orientation[:3, 1]]))
    slice_spacing = np.linalg.norm(orientation[:3, 2])
    slice_thickness = ni.header["pixdim"][3]
    orientation_rescaled = orientation33 @ np.diag(
        [1 / pixel_spacing[0], 1 / pixel_spacing[1], 1 / slice_spacing])
    orientation_dcm = np.reshape(orientation_rescaled[:2, :], 6)
    slice_vector = np.cross(orientation_rescaled[0, :],
                            orientation_rescaled[1, :])
    scl_slope = 1 if np.isnan(
        ni.header["scl_slope"]) else ni.header["scl_slope"]
    scl_inter = 0 if np.isnan(
        ni.header["scl_inter"]) else ni.header["scl_inter"]
    raw = ni.get_fdata()
    minvol = np.min(raw)
    maxvol = np.max(raw)
    raw -= minvol
    scl_inter += minvol * scl_slope
    raw *= 65536 / (maxvol - minvol)
    scl_slope *= (maxvol - minvol) / 65536
    minval = scl_slope * np.min(raw) + scl_inter
    maxval = scl_slope * np.max(raw) + scl_inter
    uintVOL = np.uint16(np.round(raw))

    out_dcms = []
    for k in range(K):
        for t in range(T):
            d = Dataset()
            for elem in ds:
                if elem.tag.group in [0x8, 0x10, 0x18, 0x20, 0x28, 0x32, 0x40]:
                    d[elem.tag] = deepcopy(elem)
            fix_meta_info(d)
            d.SOPInstanceUID = generate_uid(entropy_srcs=[
                d.SeriesInstanceUID, d.SeriesDescription,
                str(k),
                str(t),
                str(uintVOL[:2, :2, k])
            ])
            d.SeriesInstanceUID = generate_uid(
                entropy_srcs=[d.SeriesInstanceUID, d.SeriesDescription])
            d.PixelSpacing = pixel_spacing
            d.SeriesNumber += 1000
            d.SpacingBetweenSlices = slice_spacing
            d.SliceThickness = slice_thickness
            d.ImageOrientationPatient = list(orientation_dcm)
            d.ImagePositionPatient = list(image_position0 + (k - 1) *
                                          slice_vector * slice_spacing)
            d.SliceLocation = np.dot(d.ImagePositionPatient, slice_vector)
            d.Rows = J
            d.Columns = I
            d.InstanceNumber = k
            d.AcquisitionNumber = t
            if len(ni.shape) == 3:
                d.PixelData = np.flip(uintVOL[:, :,
                                              k]).T.copy(order='C').tobytes()
            else:
                d.PixelData = np.flip(uintVOL[:, :, k,
                                              t]).T.copy(order='C').tobytes()
            #d.Pixel Data = transpose(uintVOL[end:-1:1,end:-1:1,k,t])        # flip from RAS to LPS
            d.BitsAllocated = 16
            d.BitsStored = 16
            d.HighBit = 15
            d.PixelRepresentation = 0
            d.WindowCenter = (maxval + minval) / 2
            d.WindowWidth = (maxval - minval)
            d.WindowCenterWidthExplanation = "LINEAR"
            d.RescaleIntercept = scl_inter
            d.RescaleSlope = scl_slope
            fix_meta_info(d)
            out_dcms.append(d)
    return out_dcms