예제 #1
0
    def test_append_file(self):
        # Create test data
        data = OrderedDict()
        data['FileName'] = 'filename.txt'
        data['A'] = 2
        data['B'] = 'b'

        # First write
        write_csv(data, self.csv_file_name)

        self.assertTrue(os.path.exists(self.csv_file_name),
          'Could not create file')

        # Second write
        write_csv(data, self.csv_file_name)

        # Create the expected file
        correct_file_name = os.path.join(self.test_dir, 'test_correct.csv')
        with open(correct_file_name, 'w') as f:
            f.write('FileName,A,B' + os.linesep)
            f.write('filename.txt,2,b' + os.linesep)
            f.write('filename.txt,2,b' + os.linesep)

        # Test
        self.assertTrue(filecmp.cmp(correct_file_name, self.csv_file_name),
          'Files are not the same')
예제 #2
0
    def test_special_characters(self):
        # Create test data
        data = OrderedDict()
        data['Spacing.X [mm]'] = 3
        data['C^asdf'] = 'Hello'

        # Create the expected file
        correct_file_name = os.path.join(self.test_dir, 'test_correct.csv')
        with open(correct_file_name, 'w') as f:
            f.write('Spacing.X [mm],C^asdf' + os.linesep)
            f.write('3,Hello' + os.linesep)

        # Print result
        write_csv(data, self.csv_file_name)

        # Test
        self.assertTrue(os.path.exists(self.csv_file_name),
          'Could not create file')
        self.assertTrue(filecmp.cmp(correct_file_name, self.csv_file_name),
          'Files are not the same')
예제 #3
0
    def test_delimiter(self):
        # Create test data
        data = OrderedDict()
        data['FileName'] = 'filename.txt'
        data['A'] = 2
        data['B'] = 'b'

        # Create the expected file
        correct_file_name = os.path.join(self.test_dir, 'test_correct.csv')
        with open(correct_file_name, 'w') as f:
            f.write('FileName;A;B' + os.linesep)
            f.write('filename.txt;2;b' + os.linesep)

        # Print result
        write_csv(data, self.csv_file_name, delimiter=';')

        # Test
        self.assertTrue(os.path.exists(self.csv_file_name),
          'Could not create file')
        self.assertTrue(filecmp.cmp(correct_file_name, self.csv_file_name),
          'Files are not the same')
예제 #4
0
def Muscle(input_filename, converted_filename, segmentation_filename, bone_threshold, smoothing_iterations, segmentation_iterations, segmentation_multiplier, initial_neighborhood_radius, closing_radius, csv_filename='', tiff_filename='', histogram_filename=''):
    # Python 2/3 compatible input
    from six.moves import input

    # Input must be an AIM
    if not input_filename.lower().endswith('.aim'):
        os.sys.exit('[ERROR] Input \"{}\" must be an AIM'.format(input_filename))

    # Read input
    if not os.path.isfile(input_filename):
        os.sys.exit('[ERROR] Cannot find file \"{}\"'.format(input_filename))

    # Internal constants
    bone_label = 1
    muscle_label = 2

    # Compute calibration constants
    print('Computing calibration constants')
    reader = vtkbone.vtkboneAIMReader()
    reader.SetFileName(input_filename)
    reader.DataOnCellsOff()
    reader.Update()
    m,b = get_aim_density_equation(reader.GetProcessingLog())
    del reader
    print('  m: {}'.format(m))
    print('  b: {}'.format(b))
    print('')

    # Converting image
    print('Converting {} to {}'.format(input_filename, converted_filename))
    ImageConverter(input_filename, converted_filename, overwrite=True)
    print('')

    print('Reading in converted image')
    image = sitk.ReadImage(converted_filename)

    # Segment bone
    print('Segmenting bone')
    seg_bone = segment_bone(image, (bone_threshold - b)/m)
    seg_bone = (seg_bone>0)*bone_label
    print('')

    # Find centroid
    print('Finding centroid of the two largest bones')
    stat_filter = sitk.LabelShapeStatisticsImageFilter()
    stat_filter.Execute(sitk.RelabelComponent(sitk.ConnectedComponent(seg_bone)))
    centroids = [
        stat_filter.GetCentroid(1),
        stat_filter.GetCentroid(2)
    ]
    seed = [0 for i in range(len(centroids[0]))]
    for i in range(len(seed)):
        seed[i] = 0.5*(centroids[0][i] + centroids[1][i])
    seed_index = image.TransformPhysicalPointToIndex(seed)
    print('  Centroid1:       {}'.format(centroids[0]))
    print('  Centroid2:       {}'.format(centroids[1]))
    print('  Seed (physical): {}'.format(seed))
    print('  Seed (index):    {}'.format(seed_index))
    print('')

    # Smooth image
    print('Performing anisotropic smoothing')
    timeStep = image.GetSpacing()[0] / 2.0**4
    smooth_image = sitk.GradientAnisotropicDiffusion(
        sitk.Cast(image, sitk.sitkFloat32),
        timeStep=timeStep,
        numberOfIterations=smoothing_iterations
    )
    print('')

    # Segment muscle
    print('Segmenting muscle')
    radius = int(max(1, initial_neighborhood_radius/image.GetSpacing()[0]))
    print('  initialNeighborhoodRadius [vox]: {}'.format(radius))
    seg_muscle = sitk.ConfidenceConnected(
        smooth_image,
        seedList=[seed_index],
        numberOfIterations=segmentation_iterations,
        multiplier=segmentation_multiplier,
        initialNeighborhoodRadius=radius,
        replaceValue=1
    )

    # Take largest component
    seg_muscle = (sitk.RelabelComponent(sitk.ConnectedComponent(seg_muscle>0))==1)*muscle_label
    print('')

    # One, solid peice of background
    print('Cleaning up segmentation')
    vector_radius = [int(max(1, closing_radius//s)) for s in image.GetSpacing()]
    print('  Closing radius [mm]:    {}'.format(closing_radius))
    print('  Vector radius [voxels]: {}'.format(vector_radius))
    seg = (seg_bone+seg_muscle)>0
    seg = sitk.BinaryDilate(seg, vector_radius)
    background = sitk.RelabelComponent(sitk.ConnectedComponent(seg<1))==1
    seg_muscle = sitk.BinaryErode(background<1, vector_radius)*muscle_label
    print('')

    # Join segmentation
    seg_muscle = sitk.Mask(seg_muscle, 1-(seg_bone>0))
    seg = seg_bone + seg_muscle
    seg = sitk.Cast(seg, sitk.sitkInt8)

    # Write segmentation
    print('Writing segmentation to ' + segmentation_filename)
    sitk.WriteImage(seg, segmentation_filename)
    print('')

    print('Performing quantification')
    # Quantify Density
    intensity_filter = sitk.LabelIntensityStatisticsImageFilter()
    intensity_filter.Execute(seg, image)
    muscle_density = intensity_filter.GetMean(muscle_label)

    # Quantify cross sectional area
    # Note that since
    stat_filter = sitk.LabelShapeStatisticsImageFilter()
    stat_filter.Execute(seg)
    ave_cross_area = float(stat_filter.GetNumberOfPixels(muscle_label)) / seg.GetSize()[2]

    print('  density:       {}'.format(muscle_density))
    print('  cross section: {}'.format(ave_cross_area))
    print('')

    # Write results
    entry = OrderedDict()
    entry['Filename'] = input_filename
    entry['Spacing.X [mm]'] = image.GetSpacing()[0]
    entry['Spacing.Y [mm]'] = image.GetSpacing()[1]
    entry['Spacing.Z [mm]'] = image.GetSpacing()[2]
    entry['density_slope'] = m
    entry['density_intercept'] = b
    entry['muscle density [native]'] = muscle_density
    entry['A.Cross [vox^2]'] = ave_cross_area
    print(echo_arguments('Muscle Outcomes:', entry))

    # Write CSV
    if len(csv_filename)>0:
        print('  Writing to csv file ' + csv_filename)
        write_csv(entry, csv_filename)

    # Write TIFF
    if len(tiff_filename)>0:
        overlay = sitk.LabelOverlay(
            sitk.Cast(sitk.IntensityWindowing(
                sitk.Cast(image, sitk.sitkFloat32),
                windowMinimum = 0,
                windowMaximum = (bone_threshold - b)/m,
                outputMinimum = 0.0,
                outputMaximum = 255.0
            ), sitk.sitkUInt8),
            seg,
            opacity=0.3
        )

        size = list(overlay.GetSize())
        index = [0, 0, int(size[2]//2)]
        size[2]=0

        #Step 5: Extract that specific slice using the Extract Image Filter
        tiff_image = sitk.Extract(
            overlay,
            size=size,
            index=index
        )

        print('  Save single slice to ' + tiff_filename)
        sitk.WriteImage(tiff_image, tiff_filename)

    # Create histogram
    if len(histogram_filename)>0:
        import matplotlib.pyplot as plt
        print('Saving histogram to ' + histogram_filename)

        data = m*sitk.GetArrayFromImage(image)+b
        mask = sitk.GetArrayFromImage(seg)
        data = data.ravel()
        mask = mask.ravel()

        plt.figure(figsize=(8, 6))
        plt.hist(data[mask==muscle_label], bins=1000, density=True)
        plt.xlabel('Density [mg HA/ccm]')
        plt.ylabel('Normalized Count')
        plt.pause(0.1)
        plt.savefig(histogram_filename)