Exemple #1
0
    def setUp(self):
        # Create simple dataset for all tests
        ds = Dataset()
        ds.PatientName = "Name^Patient"

        # Set up a simple nested sequence
        # first, the innermost sequence
        subitem1 = Dataset()
        subitem1.ContourNumber = 1
        subitem1.ContourData = ['2', '4', '8', '16']
        subitem2 = Dataset()
        subitem2.ContourNumber = 2
        subitem2.ContourData = ['32', '64', '128', '196']

        sub_ds = Dataset()
        sub_ds.ContourSequence = Sequence(
            (subitem1,
             subitem2))  # XXX in 0.9.5 will need sub_ds.ContourSequence

        # Now the top-level sequence
        ds.ROIContourSequence = Sequence(
            (sub_ds, ))  # Comma necessary to make it a one-tuple

        # Store so each test can use it
        self.ds = ds
Exemple #2
0
    def create_dicom_contours(self):
        """ Creates and returns a list of Dicom CONTOUR objects from self.
        """

        # in order to get DICOM readable by Eclipse we need to connect each contour with CT slice
        # CT slices are identified by SOPInstanceUID
        # first we assume some default value if we cannot figure out CT slice info (i.e. CT cube is not loaded)
        ref_sop_instance_uid = '1.2.3'

        # then we check if CT cube is loaded
        if self.cube is not None:

            # if CT cube is loaded we extract DICOM representation of the cube (1 dicom per slice)
            # and select DICOM object for current slice based on slice position
            # it is time consuming as for each call of this method we generate full DICOM representation (improve!)
            candidates = [dcm for dcm in self.cube.create_dicom() if dcm.SliceLocation == self.get_position()]
            if len(candidates) > 0:
                # finally we extract CT slice SOP Instance UID
                ref_sop_instance_uid = candidates[0].SOPInstanceUID

        contour_list = []
        for item in self.contour:
            con = Dataset()
            contour = []
            for p in item.contour:
                contour.extend([p[0], p[1], p[2]])
            con.ContourData = contour
            con.ContourGeometricType = 'CLOSED_PLANAR'
            con.NumberofContourPoints = item.number_of_points()
            cont_image_item = Dataset()
            cont_image_item.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'  # CT Image Storage SOP Class
            cont_image_item.ReferencedSOPInstanceUID = ref_sop_instance_uid  # CT slice Instance UID
            con.ContourImageSequence = Sequence([cont_image_item])
            contour_list.append(con)
        return contour_list
    def setUp(self):
        # Create simple dataset for all tests
        ds = Dataset()
        ds.PatientsName = "Name^Patient"
        
        # Set up a simple nested sequence
        # first, the innermost sequence
        subitem1 = Dataset()
        subitem1.ContourNumber = 1
        subitem1.ContourData = [2,4,8,16]
        subitem2 = Dataset()
        subitem2.ContourNumber = 2
        subitem2.ContourData = [32,64,128,196]
        
        sub_ds = Dataset()
        sub_ds.Contours = Sequence((subitem1, subitem2)) # XXX in 0.9.5 will need sub_ds.ContourSequence

        # Now the top-level sequence
        ds.ROIContours = Sequence((sub_ds,)) # Comma necessary to make it a one-tuple
        
        # Store so each test can use it
        self.ds = ds
Exemple #4
0
    def setUp(self):
        # Create simple dataset for all tests
        ds = Dataset()
        ds.PatientName = "Name^Patient"

        # Set up a simple nested sequence
        # first, the innermost sequence
        subitem1 = Dataset()
        subitem1.ContourNumber = 1
        subitem1.ContourData = ['2', '4', '8', '16']
        subitem2 = Dataset()
        subitem2.ContourNumber = 2
        subitem2.ContourData = ['32', '64', '128', '196']

        sub_ds = Dataset()
        sub_ds.ContourSequence = Sequence((subitem1, subitem2))

        # Now the top-level sequence
        ds.ROIContourSequence = Sequence((sub_ds,))  # Comma to make one-tuple

        # Store so each test can use it
        self.ds = ds
Exemple #5
0
def create_rtstruct(RS_File, im_mask_ax, im_mask_sag, im_mask_cor):

    rmin, rmax, cmin, cmax, zmin, zmax = bbox2_3D(im_mask_sag, 0)
    if rmin < 0:
        rmin = 0
    if cmin < 0:
        cmin = 0
    if zmin < 0:
        zmin = 0

    im_mask_ax_adj = np.zeros(np.shape(im_mask_ax))
    im_mask_ax_adj[rmin:rmax, cmin:cmax,
                   zmin:zmax] = im_mask_ax[rmin:rmax, cmin:cmax, zmin:zmax]

    ss = dicom.read_file(RS_File)
    contour_name = FLAGS.structure
    data_path = FLAGS.data_dir

    ## Add Contour
    UID = ss.SOPInstanceUID.split('.')
    UID_NEW = UID[:-1]
    UID_NEW.append(datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")[0:19])
    ss.SOPInstanceUID = '.'.join(UID_NEW)
    ss.StructureSetName = FLAGS.structure_match + '_DLV3_' + datetime.datetime.now(
    ).strftime("%Y%m%d%H%M%S%f")[0:19]
    ss.StructureSetLabel = datetime.datetime.now().strftime(
        "%Y%m%d%H%M%S%f")[0:19]
    ss.InstanceCreationDate = datetime.datetime.now().strftime("%Y%m%d")
    ss.InstanceCreationTime = datetime.datetime.now().strftime("%H%M%S.%f")
    ROINumList = []
    for s in ss.ROIContourSequence:
        ROINumList.append(s.ReferencedROINumber)

    ## Add StructureSetROISequence
    ss_new = Dataset()
    ss_new.ROINumber = np.int(max(ROINumList)) + 1
    ss_new.ReferencedFrameOfReferenceUID = ss.StructureSetROISequence[
        len(ROINumList) - 1].ReferencedFrameOfReferenceUID
    ss_new.ROIName = FLAGS.structure_match + '_DLV3'
    ss_new.ROIDescription = ''
    ss_new.ROIGenerationAlgorithm = 'MANUAL'
    ss.StructureSetROISequence.append(ss_new)

    ## Add RTROIObservationsSequence
    ss_new = Dataset()
    ss_new.ObservationNumber = np.int(max(ROINumList)) + 1
    ss_new.ReferencedROINumber = np.int(max(ROINumList)) + 1
    ss_new.ROIObservationDescription = 'Type:Soft, Range:*/*, Fill:0, Opacity:0.0, Thickness:1, LineThickness:2'
    ss_new.RTROIInterpretedType = ''
    ss_new.ROIInterpreter = ''
    ss.RTROIObservationsSequence.append(ss_new)

    ## Add ROIContourSequence
    ss_new = Dataset()
    ss_new.ReferencedROINumber = np.int(max(ROINumList)) + 1
    ss_new.ROIDisplayColor = ['255', '0', '0']
    ss_new.ContourSequence = Sequence()

    k = 0
    ss_referenceclass = ss.ROIContours[0].Contours[0].ContourImageSequence[
        0].ReferencedSOPClassUID
    for item in ss.StructureSetROISequence[:]:
        ## Check if structure is equal to specified structure name
        if item.ROIName == FLAGS.structure_match:
            ## ss_maxslice: determines maximum number of image slices contour lives on
            ss_maxslice = len(ss.ROIContours[k].Contours)
            ## pattern collects referenced SOP for DICOM collection, searched dir for CT_files list
            pattern = ss.ROIContours[k].Contours[0].ContourImageSequence[
                0].ReferencedSOPInstanceUID
            pattern = '*' + '.'.join(pattern.split('.')[:-2])
            pattern = pattern[:-3] + '*'
            CT_files = find(pattern, data_path)
            try:
                CT_files.remove(RS_File)
            except:
                print('RS not found in CT list')

            if CT_files:

                ## Open first CT image, get size, total number of files and
                ## initialize Numpy Arrays for data collection
                ct_maxslice = len(CT_files)
                img = dicom.read_file(CT_files[0])
                img_size = np.shape(img.pixel_array)
                im_mask = np.zeros((img_size[0], img_size[1], ct_maxslice))
                im_data = np.zeros((img_size[0], img_size[1], ct_maxslice))
                z0 = img.ImagePositionPatient[2]

                ## Since DICOM files are not in spatial order, determine
                ## "z0" or starting z position
                for slice in range(0, ct_maxslice):
                    img = dicom.read_file(CT_files[slice])
                    if 'RS' in CT_files[slice]:
                        print('not structure')
                    else:
                        if z0 > img.ImagePositionPatient[2]:
                            z0 = img.ImagePositionPatient[2]

            for slice in range(0, ct_maxslice):
                if 'RS' in CT_files[slice]:
                    print('not structure')
                else:
                    contour_dicom = Dataset()
                    img = dicom.read_file(CT_files[slice])
                    x_y = np.array(img.ImagePositionPatient)
                    xsp_ysp = np.array(img.PixelSpacing)
                    z_prime = float(img.ImagePositionPatient[2])
                    zsp = float(img.SliceThickness)
                    z = int((z_prime - z0) / zsp)
                    if np.max(im_mask_ax_adj[:, :, z]) > 0 and (np.max(
                            im_mask_sag[:, :, z] > 0)):
                        r = im_mask_ax_adj[:, :, z]
                        contours = measure.find_contours(r, 0.5)
                        for n, contour in enumerate(contours):
                            pointList = []
                            contour_dicom = Dataset()
                            contour_dicom.ContourGeometricType = 'CLOSED_PLANAR'
                            for i in range(0, len(contour)):
                                y = contour[i][0]
                                x = contour[i][1]
                                x_prime = x * xsp_ysp[0] + x_y[0]
                                y_prime = y * xsp_ysp[1] + x_y[1]
                                pointList.append(x_prime)
                                pointList.append(y_prime)
                                pointList.append(z_prime)

                            if len(pointList) > 0:
                                contour_dicom.NumberOfContourPoints = len(
                                    contour)
                                contour_dicom.ContourData = pointList
                                contour_dicom.ContourImageSequence = Sequence()
                                img_seq = Dataset()
                                img_seq.ReferencedSOPClassUID = ss_referenceclass
                                img_seq.ReferencedSOPInstanceUID = CT_files[
                                    slice].split(os.sep)[-1].replace(
                                        '.dcm', '').replace('MR.', '')
                                contour_dicom.ContourImageSequence.append(
                                    img_seq)
                                ss_new.ContourSequence.append(contour_dicom)
            k = k + 1

    ss.ROIContourSequence.append(ss_new)
    filename = RS_File.split(os.sep)
    filename[-1] = contour_name + str(
        datetime.datetime.now().strftime("%Y%m%d")) + '.dcm'
    print(filename)
    ss.save_as(os.sep.join(filename))

    return