def test_Intensity_1(self):
     """Test a case of distributed intensity values."""
     # Create label image with only one region
     label_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Create original image with two equally distibuted intensity value
     original_image = scipy.zeros(2*2*2, dtype=scipy.int8)
     original_image[:4] = -1
     original_image[4:] = 1
     original_image = original_image.reshape(2,2,2)
     
     # Initialize object
     statistics = LabelImageStatistics(label_image, original_image)
     
     # Computed expected result
     i = scipy.array([-1,-1,-1,-1,1,1,1,1])
     h = scipy.histogram(i, statistics._intensity_distribution_local_histogram_width)
     hr = scipy.array(h[0]) / float(h[0].sum())
     g = stats.norm(*stats.norm.fit(i))
     r = abs(hr - g.pdf(h[1][:-1]))
     r *= h[1][-2] - h[1][0]
     r = r.sum()
     
     # Check created intensity distribution
     intensity_distributions = statistics.get_intensity_distributions()
     self.assertEqual(len(intensity_distributions), 1)
     self.assertEqual(intensity_distributions[0], i.std())
     
     intensity_distribution_histogram = statistics.get_intensity_distribution_histogram()
     self.assertEqual(intensity_distribution_histogram[0][statistics.get_intensity_distribution_histogram_width()/2], 1)
     self.assertEqual(intensity_distribution_histogram[0].max(), 1)
     self.assertEqual(intensity_distribution_histogram[0].min(), 0)
     self.assertEqual(intensity_distribution_histogram[1].mean(), i.std())
示例#2
0
    def test_Homogeneous(self):
        """Checks the return value for a homogeneous region."""
        # Create label image with only one region
        label_image = scipy.zeros(2 * 2 * 2, dtype=scipy.int8).reshape(2, 2, 2)

        # Create original image with only one intensity value
        original_image = scipy.zeros(2 * 2 * 2,
                                     dtype=scipy.int8).reshape(2, 2, 2)

        # Initialize object
        statistics = LabelImageStatistics(label_image, original_image)

        # Check created intensity distribution
        intensity_distributions = statistics.get_intensity_distributions()
        self.assertEqual(len(intensity_distributions), 1)
        self.assertEqual(intensity_distributions[0], 0)

        intensity_distribution_histogram = statistics.get_intensity_distribution_histogram(
        )
        self.assertEqual(
            len(intensity_distribution_histogram[0]),
            statistics.get_intensity_distribution_histogram_width())
        self.assertEqual(
            len(intensity_distribution_histogram[1]),
            statistics.get_intensity_distribution_histogram_width() + 1)
        self.assertEqual(
            intensity_distribution_histogram[0]
            [statistics.get_intensity_distribution_histogram_width() / 2], 1)
        self.assertEqual(intensity_distribution_histogram[0].max(), 1)
        self.assertEqual(intensity_distribution_histogram[0].min(), 0)
示例#3
0
    def test_Equality(self):
        """Checks whether equally formed histograms in different intensity regions produce the same result."""
        # Create random value for testing
        x = scipy.random.randint(10, 10000)

        # Create label image with only one region
        label_image = scipy.zeros(2 * 2 * 2, dtype=scipy.int8).reshape(2, 2, 2)

        # Create original images with two equally distributed intensity values
        original_image1 = scipy.zeros(2 * 2 * 2).reshape(2, 2, 2)
        original_image2 = scipy.zeros(2 * 2 * 2).reshape(2, 2, 2)
        original_image1[2:, :, :] = -x
        original_image1[:2, :, :] = 0
        original_image2[2:, :, :] = 0
        original_image2[:2, :, :] = x

        # Initialize objects
        statistics1 = LabelImageStatistics(label_image, original_image1)
        statistics2 = LabelImageStatistics(label_image, original_image2)

        # Check created intensity distribution to be different
        intensity_distributions1 = statistics1.get_intensity_distributions()
        intensity_distributions2 = statistics2.get_intensity_distributions()
        self.assertEqual(intensity_distributions1[0],
                         intensity_distributions2[0])
 def test_Homogeneous(self):
     """Checks the return value for a homogeneous region."""
     # Create label image with only one region
     label_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Create original image with only one intensity value
     original_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Initialize object
     statistics = LabelImageStatistics(label_image, original_image)
     
     # Check created intensity distribution
     intensity_distributions = statistics.get_intensity_distributions()
     self.assertEqual(len(intensity_distributions), 1)
     self.assertEqual(intensity_distributions[0], 0)
     
     intensity_distribution_histogram = statistics.get_intensity_distribution_histogram()
     self.assertEqual(len(intensity_distribution_histogram[0]), statistics.get_intensity_distribution_histogram_width())
     self.assertEqual(len(intensity_distribution_histogram[1]), statistics.get_intensity_distribution_histogram_width() + 1)
     self.assertEqual(intensity_distribution_histogram[0][statistics.get_intensity_distribution_histogram_width()/2], 1)
     self.assertEqual(intensity_distribution_histogram[0].max(), 1)
     self.assertEqual(intensity_distribution_histogram[0].min(), 0)
 def test_Continuity(self):
     """Checks if the returned values are continuous for more spaced intensity values."""
     # Create random value for testing
     x = scipy.random.randint(10, 10000) 
     
     # Create label image with only one region
     label_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Create original images with two equally distributed intensity values
     original_image1 = scipy.zeros(2*2*2).reshape(2,2,2)
     original_image2 = scipy.zeros(2*2*2).reshape(2,2,2)
     original_image1[1:,:,:] = x
     original_image2[1:,:,:] = 2*x
     
     # Initialize objects
     statistics1 = LabelImageStatistics(label_image, original_image1)
     statistics2 = LabelImageStatistics(label_image, original_image2)
     
     # Check created intensity distribution to be different
     intensity_distributions1 = statistics1.get_intensity_distributions()
     intensity_distributions2 = statistics2.get_intensity_distributions()
     self.assertGreater(intensity_distributions2[0], intensity_distributions1[0])        
示例#6
0
    def test_Intensity_1(self):
        """Test a case of distributed intensity values."""
        # Create label image with only one region
        label_image = scipy.zeros(2 * 2 * 2, dtype=scipy.int8).reshape(2, 2, 2)

        # Create original image with two equally distibuted intensity value
        original_image = scipy.zeros(2 * 2 * 2, dtype=scipy.int8)
        original_image[:4] = -1
        original_image[4:] = 1
        original_image = original_image.reshape(2, 2, 2)

        # Initialize object
        statistics = LabelImageStatistics(label_image, original_image)

        # Computed expected result
        i = scipy.array([-1, -1, -1, -1, 1, 1, 1, 1])
        h = scipy.histogram(
            i, statistics._intensity_distribution_local_histogram_width)
        hr = scipy.array(h[0]) / float(h[0].sum())
        g = stats.norm(*stats.norm.fit(i))
        r = abs(hr - g.pdf(h[1][:-1]))
        r *= h[1][-2] - h[1][0]
        r = r.sum()

        # Check created intensity distribution
        intensity_distributions = statistics.get_intensity_distributions()
        self.assertEqual(len(intensity_distributions), 1)
        self.assertEqual(intensity_distributions[0], i.std())

        intensity_distribution_histogram = statistics.get_intensity_distribution_histogram(
        )
        self.assertEqual(
            intensity_distribution_histogram[0]
            [statistics.get_intensity_distribution_histogram_width() / 2], 1)
        self.assertEqual(intensity_distribution_histogram[0].max(), 1)
        self.assertEqual(intensity_distribution_histogram[0].min(), 0)
        self.assertEqual(intensity_distribution_histogram[1].mean(), i.std())
 def test_Equality(self):
     """Checks whether equally formed histograms in different intensity regions produce the same result."""
     # Create random value for testing
     x = scipy.random.randint(10, 10000) 
     
     # Create label image with only one region
     label_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Create original images with two equally distributed intensity values
     original_image1 = scipy.zeros(2*2*2).reshape(2,2,2)
     original_image2 = scipy.zeros(2*2*2).reshape(2,2,2)
     original_image1[2:,:,:] = -x
     original_image1[:2,:,:] = 0
     original_image2[2:,:,:] = 0
     original_image2[:2,:,:] = x
     
     # Initialize objects
     statistics1 = LabelImageStatistics(label_image, original_image1)
     statistics2 = LabelImageStatistics(label_image, original_image2)
     
     # Check created intensity distribution to be different
     intensity_distributions1 = statistics1.get_intensity_distributions()
     intensity_distributions2 = statistics2.get_intensity_distributions()
     self.assertEqual(intensity_distributions1[0], intensity_distributions2[0])      
示例#8
0
    def test_Continuity(self):
        """Checks if the returned values are continuous for more spaced intensity values."""
        # Create random value for testing
        x = scipy.random.randint(10, 10000)

        # Create label image with only one region
        label_image = scipy.zeros(2 * 2 * 2, dtype=scipy.int8).reshape(2, 2, 2)

        # Create original images with two equally distributed intensity values
        original_image1 = scipy.zeros(2 * 2 * 2).reshape(2, 2, 2)
        original_image2 = scipy.zeros(2 * 2 * 2).reshape(2, 2, 2)
        original_image1[1:, :, :] = x
        original_image2[1:, :, :] = 2 * x

        # Initialize objects
        statistics1 = LabelImageStatistics(label_image, original_image1)
        statistics2 = LabelImageStatistics(label_image, original_image2)

        # Check created intensity distribution to be different
        intensity_distributions1 = statistics1.get_intensity_distributions()
        intensity_distributions2 = statistics2.get_intensity_distributions()
        self.assertGreater(intensity_distributions2[0],
                           intensity_distributions1[0])
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)
    
    # iterate over input images
    for image in args.images:
        
        # load image as float using ITK
        logger.info('Loading image {} as float using ITK...'.format(image))
        image_type = itk.Image[itk.F, 3]  # causes PyDev to complain -> ignore error warning
        reader = itk.ImageFileReader[image_type].New()
        reader.SetFileName(image)
        reader.Update()
            
        
        logger.debug(itku.getInformation(reader.GetOutput()))
        
        # build output image name
        image_watershed_name = args.folder + '/' + image.split('/')[-1][:-4] + '_watershed' + image.split('/')[-1][-4:]
        
        # check if output image exists
        if not args.force:
            if os.path.exists(image_watershed_name):
                logger.warning('The output image {} already exists. Skipping this input image.'.format(image_watershed_name))
                continue
                
        # prepare watershed
        # assign to watershed_source the image to be passed to the watershed
        watershed_source = reader.GetOutput()
        # extract data from original image to scipy
        itk_py_converter_orig = itk.PyBuffer[image_type]  # causes PyDev to complain -> ignore error warning
        original_image_array = itk_py_converter_orig.GetArrayFromImage(reader.GetOutput())        
        # recover input image dimensions
        rs = original_image_array.shape
        # create empty final label image array
        image_label_final_array = scipy.zeros(rs[0] * rs[1] * rs[2], dtype=scipy.int32).reshape(rs) #!TODO: Is 32bit enough?
        # create an empty watershed result array
        watershed_result_array = scipy.zeros_like(image_label_final_array)
        # create initial label mask covering the whole image space
        label_mask = scipy.zeros(rs[0] * rs[1] * rs[2], dtype=scipy.bool_).reshape(rs)
        label_mask.fill(True)
        # set threhold to use
        threshold = __INITIAL_THRESHOLD
        # set the point to the largest region to process
        region_pointer = -1

        
        # apply the watershed
        logger.info('Applying watershed...')
        
        while True:
            # initialize the watershed filter object
            logger.info('Watershedding with settings: thr={} / level={}...'.format(threshold, 0.0))
            image_watershed = itk.WatershedImageFilter[image_type].New()
            image_watershed.SetInput(watershed_source)
            image_watershed.SetThreshold(threshold)
            image_watershed.SetLevel(0.0)
            
            try:
                image_watershed.Update()
                
                logger.debug(itku.getInformation(image_watershed.GetOutput()))
            
                logger.info('Adding resulting labels to final result image...')
                # converting to scipy
                itk_py_converter_ws = itk.PyBuffer[itku.getImageType(image_watershed.GetOutput())]  # causes PyDev to complain -> ignore error warning
                watershed_result_array = itk_py_converter_ws.GetArrayFromImage(image_watershed.GetOutput())
                # recovering current offset for the new label ids
                min_label_id = image_label_final_array.max()
                # updating final label image
                image_label_final_array[label_mask] = watershed_result_array[label_mask] + min_label_id
                
                logger.info('Last watershed led to {} new labels, {} in total now...'.format(len(scipy.unique(watershed_result_array)) - 1, len(scipy.unique(image_label_final_array))))
                
    #            # lower the threshold if no new labels were created, or skip label if a threshold of 0 did not help
                if 100 >= len(scipy.unique(watershed_result_array)) - 1:
                    if 0 == threshold:
                        region_pointer -= 1
                        logger.info('Skipping this region as threshold lowering did not lead to the production of more than 100 labels...')
                    else:
                        threshold = threshold / 2.
                        if threshold < 0.001: threshold = 0.0
                        logger.info('Lowering threshold for next region to {} ...'.format(threshold))
                else:
                    threshold = __INITIAL_THRESHOLD
                    logger.info('Resetting threshold to original value of {} ...'.format(__INITIAL_THRESHOLD))
                    
            except RuntimeError as error:
                if 0 == threshold:
                    region_pointer -= 1
                    logger.warning('Watershed processing terminated with error {}. Skipping this region as threshold lowering did not succeed.'.format(error))
                else:
                    threshold = threshold / 2
                    if threshold < 0.001: threshold = 0.0
                    logger.warning('Watershed processing terminated with error {}. Lowering threshold to {}.'.format(error, threshold))
            
                        
            logger.info('Computing statistics / checking stop condition...')
            statistics = LabelImageStatistics(image_label_final_array, original_image_array)
            
            # check medium region size and if stop condition reached, break
            sizes = sorted(statistics.get_sizes().iteritems(), key=lambda x: x[1]) # get sizes sorted (biggest region last)
            if __IDEAL_REGION_SIZE >= sizes[region_pointer][1]:
                logger.info('Stopping condition {} with a maximum region size of {} reached: Stopping processing...'.format(__IDEAL_REGION_SIZE, sizes[region_pointer][1]))
                break
#            if __IDEAL_REGION_SIZE >= sum(map(lambda x: x[1], sizes)) / float(len(sizes)):
#                logger.info('Stopping condition {} with a medium region size of {} reached: Stopping processing...'.format(__IDEAL_REGION_SIZE, sum(map(lambda x: x[1], sizes)) / float(len(sizes))))
#                break
                
            logger.info('Stopping condition {} with a maximum region size of {} not reached: Preparing next run...'.format(__IDEAL_REGION_SIZE, sizes[region_pointer][1]))
#            logger.info('Stopping condition {} with a medium region size of {} not reached: Preparing next run...'.format(__IDEAL_REGION_SIZE, sum(map(lambda x: x[1], sizes)) / float(len(sizes))))
            
            logger.info('Biggest region scheduled for breaking up: {} with {} voxels and intensity distribution score of {}...'.format(sizes[region_pointer][0], sizes[region_pointer][1], statistics.get_intensity_distributions()[sizes[region_pointer][0]]))
            # update label mask to cover the biggest label
            label_mask = (sizes[region_pointer][0] == image_label_final_array)
                
            # create the new input for the watershed algorithm
            watershed_source_array = scipy.zeros_like(original_image_array)
            watershed_source_array[label_mask] = original_image_array[label_mask]
            #watershed_source_array[scipy.invert(label_mask)] = watershed_source_array[label_mask].max() + 1 #!TODO: Not sure if this works, as I have the gradient image! High value = high gradient!?
            
            # cast to ITK image to apply watershed in the next step            
            watershed_source = itk_py_converter_orig.GetImageFromArray(watershed_source_array.tolist())

            logger.debug(itku.getInformation(watershed_source))
            
        # cast to ITK image to save (uses the watershed converter)
        image_label_final = itk_py_converter_ws.GetImageFromArray(image_label_final_array.tolist())

        logger.debug(itku.getInformation(image_label_final))

        logger.info('Overall skipped regions: {}...'.format(-1 * region_pointer - 1))

        # save file
        logger.info('Saving watershed image as {}...'.format(image_watershed_name))
        watershed_image_type = itku.getImageType(image_watershed.GetOutput())
        writer = itk.ImageFileWriter[watershed_image_type].New()
        writer.SetFileName(image_watershed_name)
        writer.SetInput(image_label_final)
        writer.Update()
    
    logger.info('Successfully terminated.')
 def test_Basic(self):
     """Test the case of a region with only one intensity value and some basic return values."""
     # Create label image with only one region
     label_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Create original image with only one intensity value
     original_image = scipy.zeros(2*2*2, dtype=scipy.int8).reshape(2,2,2)
     
     # Initialize object
     statistics = LabelImageStatistics(label_image, original_image)
     
     # Check created intensity distribution
     intensity_distributions = statistics.get_intensity_distributions()
     self.assertEqual(len(intensity_distributions), 1)
     self.assertEqual(intensity_distributions[0], 0)
     
     intensity_distribution_histogram = statistics.get_intensity_distribution_histogram()
     self.assertEqual(len(intensity_distribution_histogram[0]), statistics.get_intensity_distribution_histogram_width())
     self.assertEqual(len(intensity_distribution_histogram[1]), statistics.get_intensity_distribution_histogram_width() + 1)
     self.assertEqual(intensity_distribution_histogram[0][statistics.get_intensity_distribution_histogram_width()/2], 1)
     self.assertEqual(intensity_distribution_histogram[0].max(), 1)
     self.assertEqual(intensity_distribution_histogram[0].min(), 0)
     
     # Check created size distribution
     sizes = statistics.get_sizes()
     self.assertEqual(len(sizes), 1)
     self.assertEqual(sizes[0], 2*2*2)
     
     sizes_histogram = statistics.get_size_histogram()
     self.assertEqual(len(sizes_histogram[0]), statistics.get_size_histogram_width())
     self.assertEqual(len(sizes_histogram[1]), statistics.get_size_histogram_width() + 1)
     self.assertEqual(sizes_histogram[0][statistics.get_size_histogram_width()/2], 1)
     self.assertEqual(sizes_histogram[0].max(), 1)
     self.assertEqual(sizes_histogram[0].min(), 0)
     
     # Check other statistics values
     self.assertTrue(statistics.labels_are_consecutive())
     self.assertEqual(statistics.get_min_intensity(), 0)
     self.assertEqual(statistics.get_max_intensity(), 0)
     self.assertEqual(statistics.get_min_label(), 0)
     self.assertEqual(statistics.get_max_label(), 0)
     self.assertEqual(statistics.get_label_count(), 1)
示例#11
0
    def test_Basic(self):
        """Test the case of a region with only one intensity value and some basic return values."""
        # Create label image with only one region
        label_image = scipy.zeros(2 * 2 * 2, dtype=scipy.int8).reshape(2, 2, 2)

        # Create original image with only one intensity value
        original_image = scipy.zeros(2 * 2 * 2,
                                     dtype=scipy.int8).reshape(2, 2, 2)

        # Initialize object
        statistics = LabelImageStatistics(label_image, original_image)

        # Check created intensity distribution
        intensity_distributions = statistics.get_intensity_distributions()
        self.assertEqual(len(intensity_distributions), 1)
        self.assertEqual(intensity_distributions[0], 0)

        intensity_distribution_histogram = statistics.get_intensity_distribution_histogram(
        )
        self.assertEqual(
            len(intensity_distribution_histogram[0]),
            statistics.get_intensity_distribution_histogram_width())
        self.assertEqual(
            len(intensity_distribution_histogram[1]),
            statistics.get_intensity_distribution_histogram_width() + 1)
        self.assertEqual(
            intensity_distribution_histogram[0]
            [statistics.get_intensity_distribution_histogram_width() / 2], 1)
        self.assertEqual(intensity_distribution_histogram[0].max(), 1)
        self.assertEqual(intensity_distribution_histogram[0].min(), 0)

        # Check created size distribution
        sizes = statistics.get_sizes()
        self.assertEqual(len(sizes), 1)
        self.assertEqual(sizes[0], 2 * 2 * 2)

        sizes_histogram = statistics.get_size_histogram()
        self.assertEqual(len(sizes_histogram[0]),
                         statistics.get_size_histogram_width())
        self.assertEqual(len(sizes_histogram[1]),
                         statistics.get_size_histogram_width() + 1)
        self.assertEqual(
            sizes_histogram[0][statistics.get_size_histogram_width() / 2], 1)
        self.assertEqual(sizes_histogram[0].max(), 1)
        self.assertEqual(sizes_histogram[0].min(), 0)

        # Check other statistics values
        self.assertTrue(statistics.labels_are_consecutive())
        self.assertEqual(statistics.get_min_intensity(), 0)
        self.assertEqual(statistics.get_max_intensity(), 0)
        self.assertEqual(statistics.get_min_label(), 0)
        self.assertEqual(statistics.get_max_label(), 0)
        self.assertEqual(statistics.get_label_count(), 1)