def test_ComputeContour(self): reference = self._imagec.copy() reference[1, 1, 1] = False voxels = Surface.compute_contour(self._imagec) self.assertTrue((voxels == reference).all())
def test_get_maximum_symmetric_surface_distance(self): # same image s = Surface(self._imaged1, self._imaged1) self.assertEqual(s.get_maximum_symmetric_surface_distance(), 0.) # similar image s = Surface(self._imaged1, self._imaged2) self.assertAlmostEqual(s.get_maximum_symmetric_surface_distance(), 1.732050808) # shifted image s = Surface(self._imaged1, self._imaged1, (1, 1, 1), (0, 0, 0), (1, 1, 1)) self.assertAlmostEqual(s.get_maximum_symmetric_surface_distance(), 1.732050808) # shifte image \w non-one physical pixel spacing s = Surface(self._imaged1, self._imaged1, (2, 2, 2), (0, 0, 0), (1, 1, 1)) self.assertAlmostEqual(s.get_maximum_symmetric_surface_distance(), 3.464101615) # different image s = Surface(self._imaged1, self._imaged4) self.assertAlmostEqual(s.get_maximum_symmetric_surface_distance(), 5.196152423) # cube images A->B s = Surface(self._imagedA, self._imagedB) self.assertAlmostEqual(s.get_maximum_symmetric_surface_distance(), 1.73205080757) # cube images B->A s = Surface(self._imagedB, self._imagedA) self.assertAlmostEqual(s.get_maximum_symmetric_surface_distance(), 1.73205080757)
def test_get_root_mean_square_symmetric_surface_distance(self): # same image s = Surface(self._imaged1, self._imaged1) self.assertEqual(s.get_root_mean_square_symmetric_surface_distance(), 0.) # similar image s = Surface(self._imaged1, self._imaged2) self.assertAlmostEqual( s.get_root_mean_square_symmetric_surface_distance(), 1.732050808) # shifted image s = Surface(self._imaged1, self._imaged1, (1, 1, 1), (0, 0, 0), (1, 1, 1)) self.assertAlmostEqual( s.get_root_mean_square_symmetric_surface_distance(), 1.732050808) # shifte image \w non-one physical pixel spacing s = Surface(self._imaged1, self._imaged1, (2, 2, 2), (0, 0, 0), (1, 1, 1)) self.assertAlmostEqual( s.get_root_mean_square_symmetric_surface_distance(), 3.464101615) # different image s = Surface(self._imaged1, self._imaged4) self.assertAlmostEqual( s.get_root_mean_square_symmetric_surface_distance(), 2.898275349) # cube images A->B s = Surface(self._imagedA, self._imagedB) self.assertAlmostEqual( s.get_root_mean_square_symmetric_surface_distance(), 1.4272480643) # cube images B->A s = Surface(self._imagedB, self._imagedA) self.assertAlmostEqual( s.get_root_mean_square_symmetric_surface_distance(), 1.4272480643)
def test_get_average_symmetric_surface_distance(self): # same image s = Surface(self._imaged1, self._imaged1) self.assertEqual(s.get_average_symmetric_surface_distance(), 0.) # similar image s = Surface(self._imaged1, self._imaged2) self.assertAlmostEqual(s.get_average_symmetric_surface_distance(), 1.732050808) # shifted image s = Surface(self._imaged1, self._imaged1, (1,1,1), (0,0,0), (1,1,1)) self.assertAlmostEqual(s.get_average_symmetric_surface_distance(), 1.732050808) # shifte image \w non-one physical pixel spacing s = Surface(self._imaged1, self._imaged1, (2,2,2), (0,0,0), (1,1,1)) self.assertAlmostEqual(s.get_average_symmetric_surface_distance(), 3.464101615) # different image s = Surface(self._imaged1, self._imaged4) self.assertAlmostEqual(s.get_average_symmetric_surface_distance(), 2.078460969) # cube images A->B s = Surface(self._imagedA, self._imagedB) self.assertAlmostEqual(s.get_average_symmetric_surface_distance(), 1.40099885959) # cube images B->A s = Surface(self._imagedB, self._imagedA) self.assertAlmostEqual(s.get_average_symmetric_surface_distance(), 1.40099885959)
def test_ComputeContour(self): reference = self._imagec.copy() reference[1,1,1] = False voxels = Surface.compute_contour(self._imagec) self.assertTrue((voxels == reference).all())
def test_get_root_mean_square_symmetric_surface_distance(self): # same image s = Surface(self._imaged1, self._imaged1) self.assertEqual(s.get_root_mean_square_symmetric_surface_distance(), 0.) # similar image s = Surface(self._imaged1, self._imaged2) self.assertAlmostEqual(s.get_root_mean_square_symmetric_surface_distance(), 1.732050808) # shifted image s = Surface(self._imaged1, self._imaged1, (1,1,1), (0,0,0), (1,1,1)) self.assertAlmostEqual(s.get_root_mean_square_symmetric_surface_distance(), 1.732050808) # shifte image \w non-one physical pixel spacing s = Surface(self._imaged1, self._imaged1, (2,2,2), (0,0,0), (1,1,1)) self.assertAlmostEqual(s.get_root_mean_square_symmetric_surface_distance(), 3.464101615) # different image s = Surface(self._imaged1, self._imaged4) self.assertAlmostEqual(s.get_root_mean_square_symmetric_surface_distance(), 2.898275349) # cube images A->B s = Surface(self._imagedA, self._imagedB) self.assertAlmostEqual(s.get_root_mean_square_symmetric_surface_distance(), 1.4272480643) # cube images B->A s = Surface(self._imagedB, self._imagedA) self.assertAlmostEqual(s.get_root_mean_square_symmetric_surface_distance(), 1.4272480643)
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.')