def test_get_relative_volume_difference(self): i1, i2, i3, i4, i5 = self._createTestImages() # same image v = Volume(i1, i1) self.assertEqual(v.get_relative_volume_difference(), 0) # same image with both offsets the same v = Volume(i1, i1, [1,2,3], [1,2,3]) self.assertEqual(v.get_relative_volume_difference(), 0) # same image with different offsets v = Volume(i1, i1, [0,0,0], [1,1,1]) self.assertEqual(v.get_relative_volume_difference(), 0) # overlapping image with objects of same volume v = Volume(i1, i2) self.assertEqual(v.get_relative_volume_difference(), 0) # not overlapping image with objects of same volume v = Volume(i1, i3) self.assertEqual(v.get_relative_volume_difference(), 0) # included object with different volume v = Volume(i1, i4) self.assertEqual(v.get_relative_volume_difference(), 700) # included object with different volume in image of different size v = Volume(i1, i5) self.assertEqual(v.get_relative_volume_difference(), 700) # included object with different volume / reversed v = Volume(i4, i1) self.assertEqual(v.get_relative_volume_difference(), -87.5) # included object with different volume in image of different size / reversed v = Volume(i5, i1) self.assertEqual(v.get_relative_volume_difference(), -87.5)
def test_get_volumetric_overlap_error(self): i1, i2, i3, i4, i5 = self._createTestImages() # same image v = Volume(i1, i1) self.assertEqual(v.get_volumetric_overlap_error(), 0) # same image with both offsets the same v = Volume(i1, i1, [1,2,3], [1,2,3]) self.assertEqual(v.get_volumetric_overlap_error(), 0) # same image with different offsets v = Volume(i1, i1, [0,0,0], [1,1,1]) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 37.364705882) # overlapping image with objects of same volume v = Volume(i1, i2) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 93.333333333) # not overlapping image with objects of same volume v = Volume(i1, i3) self.assertEqual(v.get_volumetric_overlap_error(), 100) # included object with different volume v = Volume(i1, i4) self.assertEqual(v.get_volumetric_overlap_error(), 87.5) # included object with different volume in image of different size v = Volume(i1, i5) self.assertEqual(v.get_volumetric_overlap_error(), 87.5) # reversed versions where sensible # # same image with different offsets v = Volume(i1, i1, [1,1,1], [0,0,0]) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 37.364705882) # overlapping image with objects of same volume v = Volume(i2, i1) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 93.333333333) # not overlapping image with objects of same volume v = Volume(i3, i1) self.assertEqual(v.get_volumetric_overlap_error(), 100) # included object with different volume v = Volume(i4, i1) self.assertEqual(v.get_volumetric_overlap_error(), 87.5) # included object with different volume in image of different size v = Volume(i5, i1) self.assertEqual(v.get_volumetric_overlap_error(), 87.5)
def test_get_volumetric_overlap_error(self): i1, i2, i3, i4, i5 = self._createTestImages() # same image v = Volume(i1, i1) self.assertEqual(v.get_volumetric_overlap_error(), 0) # same image with both offsets the same v = Volume(i1, i1, [1, 2, 3], [1, 2, 3]) self.assertEqual(v.get_volumetric_overlap_error(), 0) # same image with different offsets v = Volume(i1, i1, [0, 0, 0], [1, 1, 1]) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 37.364705882) # overlapping image with objects of same volume v = Volume(i1, i2) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 93.333333333) # not overlapping image with objects of same volume v = Volume(i1, i3) self.assertEqual(v.get_volumetric_overlap_error(), 100) # included object with different volume v = Volume(i1, i4) self.assertEqual(v.get_volumetric_overlap_error(), 87.5) # included object with different volume in image of different size v = Volume(i1, i5) self.assertEqual(v.get_volumetric_overlap_error(), 87.5) # reversed versions where sensible # # same image with different offsets v = Volume(i1, i1, [1, 1, 1], [0, 0, 0]) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 37.364705882) # overlapping image with objects of same volume v = Volume(i2, i1) self.assertAlmostEqual(v.get_volumetric_overlap_error(), 93.333333333) # not overlapping image with objects of same volume v = Volume(i3, i1) self.assertEqual(v.get_volumetric_overlap_error(), 100) # included object with different volume v = Volume(i4, i1) self.assertEqual(v.get_volumetric_overlap_error(), 87.5) # included object with different volume in image of different size v = Volume(i5, i1) self.assertEqual(v.get_volumetric_overlap_error(), 87.5)
def test_get_relative_volume_difference(self): i1, i2, i3, i4, i5 = self._createTestImages() # same image v = Volume(i1, i1) self.assertEqual(v.get_relative_volume_difference(), 0) # same image with both offsets the same v = Volume(i1, i1, [1, 2, 3], [1, 2, 3]) self.assertEqual(v.get_relative_volume_difference(), 0) # same image with different offsets v = Volume(i1, i1, [0, 0, 0], [1, 1, 1]) self.assertEqual(v.get_relative_volume_difference(), 0) # overlapping image with objects of same volume v = Volume(i1, i2) self.assertEqual(v.get_relative_volume_difference(), 0) # not overlapping image with objects of same volume v = Volume(i1, i3) self.assertEqual(v.get_relative_volume_difference(), 0) # included object with different volume v = Volume(i1, i4) self.assertEqual(v.get_relative_volume_difference(), 700) # included object with different volume in image of different size v = Volume(i1, i5) self.assertEqual(v.get_relative_volume_difference(), 700) # included object with different volume / reversed v = Volume(i4, i1) self.assertEqual(v.get_relative_volume_difference(), -87.5) # included object with different volume in image of different size / reversed v = Volume(i5, i1) self.assertEqual(v.get_relative_volume_difference(), -87.5)
def main(): # parse cmd arguments parser = getParser() parser.parse_args() args = getArguments(parser) # prepare logger logger = Logger.getInstance() if args.debug: logger.setLevel(logging.DEBUG) elif args.verbose: logger.setLevel(logging.INFO) # load reference image image_reference_data, image_reference_header = load(args.reference) # prepare reference image data image_reference_data = (0 != image_reference_data) # ensures that the reference mask is of type bool image_reference_size = len(image_reference_data.nonzero()[0]) # raise exception when the input mask is zero if 0 >= image_reference_size: raise Exception('The reference mask if of size <= 0.') # extract pyhsical pixel spacing spacing = numpy.array(get_pixel_spacing(image_reference_header)) # print header if requested if args.header: print '{}/{};'.format(args.reference.split('/')[-1], image_reference_size) , print 'mask-size;VolumetricOverlapError;RelativeVolumeDifference;AverageSymmetricSurfaceDistance;MaximumSymmetricSurfaceDistance;RootMeanSquareSymmetricSurfaceDistance' # load mask using nibabel image_mask_data, image_mask_header = load(args.input) # check if physical pixel spacing is coherent mask_spacing = numpy.array(get_pixel_spacing(image_mask_header)) if not (spacing == mask_spacing).all(): if not args.ignore: print 'Stopped. Incoherent pixel spacing (reference={}/mask={})\n'.format(spacing, mask_spacing) logger.warning('The physical pixel spacings of reference ({}) and mask ({}) do not comply. Breaking evaluation.'.format(spacing, mask_spacing)) sys.exit(-1) else: logger.warning('The physical pixel spacings of reference ({}) and mask ({}) do not comply. Evaluation continued nevertheless, as ignore flag is set.'.format(spacing, mask_spacing)) # prepare mask data image_mask_data = (0 != image_mask_data) # ensures that the mask is of type bool image_mask_size = len(image_mask_data.nonzero()[0]) # write mask name and size into file print '{};{}'.format(args.input.split('/')[-1], image_mask_size) , # warn when the mask is of size 0 or less if 0 >= image_mask_size: print ';Skipped: mask size is 0' logger.warning('The mask is of size <= 0. Breaking evaluation.') sys.exit(-1) # skip if reference mask ratio hints to bad results if 0.75 > 1. * image_reference_size / image_mask_size or 1.25 < 1. * image_reference_size / image_mask_size: print ';Skipped: reference/mask <0.075 or >1.25' logger.warning('The reference/mask ration of the mask is <0.075 or >1.25. Breaking evaluation.') sys.exit(-1) # volume metrics logger.info('Calculating volume metrics...') v = Volume(image_mask_data, image_reference_data) print ';{};{}'.format(v.get_volumetric_overlap_error(), v.get_relative_volume_difference()) , logger.info('Calculating surface metrics...') s = Surface(image_mask_data, image_reference_data, spacing) print ';{};{};{}'.format(s.get_average_symmetric_surface_distance(), s.get_maximum_symmetric_surface_distance(), s.get_root_mean_square_symmetric_surface_distance()) logger.info('Successfully terminated.')