Example #1
0
 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)        
Example #2
0
 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)
Example #3
0
    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)
Example #4
0
    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.')