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')
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')
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')
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)