def testBasic(self): graph = Graph() op = OpFilterLabels(graph=graph) op.Input.setValue( self.inputData ) op.MinLabelSize.setValue(6) filtered = op.Output[...].wait() assert filtered.shape == self.inputData.shape expectedData = numpy.array(self.inputData) expectedData[0,1, 50:52, 50:52, 0] = 0 # 4 voxels, should be gone assert (filtered == expectedData).all() op.MaxLabelSize.setValue(8) expectedData[0, 0, 50:53, 50:53, 0] = 0 filtered2 = op.Output[:].wait() assert (filtered2 == expectedData).all()
def __init__(self, *args, **kwargs): super(_OpThresholdOneLevel, self).__init__(*args, **kwargs) self._opThresholder = OpPixelOperator(parent=self) self._opThresholder.Input.connect(self.InputImage) self._opLabeler = OpLabelVolume(parent=self) self._opLabeler.Method.setValue(_labeling_impl) self._opLabeler.Input.connect(self._opThresholder.Output) self.BeforeSizeFilter.connect(self._opLabeler.Output) self._opFilter = OpFilterLabels(parent=self) self._opFilter.Input.connect(self._opLabeler.Output) self._opFilter.MinLabelSize.connect(self.MinSize) self._opFilter.MaxLabelSize.connect(self.MaxSize) self._opFilter.BinaryOut.setValue(False) self.Output.connect(self._opFilter.Output)
def __init__(self, *args, **kwargs): super(OpThresholdTwoLevels, self).__init__(*args, **kwargs) self.opReorderInput = OpReorderAxes(parent=self) self.opReorderInput.AxisOrder.setValue('tzyxc') self.opReorderInput.Input.connect(self.InputImage) # PROBABILITIES: Convert to float32 self.opConvertProbabilities = OpConvertDtype( parent=self ) self.opConvertProbabilities.ConversionDtype.setValue( np.float32 ) self.opConvertProbabilities.Input.connect( self.opReorderInput.Output ) # PROBABILITIES: Normalize drange to [0.0, 1.0] self.opNormalizeProbabilities = OpPixelOperator( parent=self ) def normalize_inplace(a): drange = self.opNormalizeProbabilities.Input.meta.drange if drange is None or (drange[0] == 0.0 and drange[1] == 1.0): return a a[:] -= drange[0] a[:] = a[:]/float(( drange[1] - drange[0] )) return a self.opNormalizeProbabilities.Input.connect( self.opConvertProbabilities.Output ) self.opNormalizeProbabilities.Function.setValue( normalize_inplace ) self.opSmoother = OpAnisotropicGaussianSmoothing5d(parent=self) self.opSmoother.Sigmas.connect( self.SmootherSigma ) self.opSmoother.Input.connect( self.opNormalizeProbabilities.Output ) self.opSmootherCache = OpBlockedArrayCache(parent=self) self.opSmootherCache.BlockShape.setValue((1, None, None, None, 1)) self.opSmootherCache.Input.connect( self.opSmoother.Output ) self.opCoreChannelSelector = OpSingleChannelSelector(parent=self) self.opCoreChannelSelector.Index.connect( self.CoreChannel ) self.opCoreChannelSelector.Input.connect( self.opSmootherCache.Output ) self.opCoreThreshold = OpLabeledThreshold(parent=self) self.opCoreThreshold.Method.setValue( ThresholdMethod.SIMPLE ) self.opCoreThreshold.FinalThreshold.connect( self.HighThreshold ) self.opCoreThreshold.Input.connect( self.opCoreChannelSelector.Output ) self.opCoreFilter = OpFilterLabels(parent=self) self.opCoreFilter.BinaryOut.setValue(False) self.opCoreFilter.MinLabelSize.connect( self.MinSize ) self.opCoreFilter.MaxLabelSize.connect( self.MaxSize ) self.opCoreFilter.Input.connect( self.opCoreThreshold.Output ) self.opFinalChannelSelector = OpSingleChannelSelector(parent=self) self.opFinalChannelSelector.Index.connect( self.Channel ) self.opFinalChannelSelector.Input.connect( self.opSmootherCache.Output ) self.opSumInputs = OpMultiArrayMerger(parent=self) # see setupOutputs (below) for input connections self.opSumInputs.MergingFunction.setValue( sum ) self.opFinalThreshold = OpLabeledThreshold(parent=self) self.opFinalThreshold.Method.connect( self.CurOperator ) self.opFinalThreshold.FinalThreshold.connect( self.LowThreshold ) self.opFinalThreshold.GraphcutBeta.connect( self.Beta ) self.opFinalThreshold.CoreLabels.connect( self.opCoreFilter.Output ) self.opFinalThreshold.Input.connect( self.opSumInputs.Output ) self.opFinalFilter = OpFilterLabels(parent=self) self.opFinalFilter.BinaryOut.setValue(False) self.opFinalFilter.MinLabelSize.connect( self.MinSize ) self.opFinalFilter.MaxLabelSize.connect( self.MaxSize ) self.opFinalFilter.Input.connect( self.opFinalThreshold.Output ) self.opReorderOutput = OpReorderAxes(parent=self) #self.opReorderOutput.AxisOrder.setValue('tzyxc') # See setupOutputs() self.opReorderOutput.Input.connect(self.opFinalFilter.Output) self.Output.connect( self.opReorderOutput.Output ) self.opCache = OpBlockedArrayCache(parent=self) self.opCache.CompressionEnabled.setValue(True) self.opCache.Input.connect( self.opReorderOutput.Output ) self.CachedOutput.connect( self.opCache.Output ) self.CleanBlocks.connect( self.opCache.CleanBlocks ) ## Debug outputs self.Smoothed.connect( self.opSmootherCache.Output ) self.InputChannel.connect( self.opFinalChannelSelector.Output ) self.SmallRegions.connect( self.opCoreThreshold.Output ) self.FilteredSmallLabels.connect( self.opCoreFilter.Output ) self.BeforeSizeFilter.connect( self.opFinalThreshold.Output ) # Since hysteresis thresholding creates the big regions and immediately discards the bad ones, # we have to recreate it here if the user wants to view it as a debug layer self.opBigRegionsThreshold = OpLabeledThreshold(parent=self) self.opBigRegionsThreshold.Method.setValue( ThresholdMethod.SIMPLE ) self.opBigRegionsThreshold.FinalThreshold.connect( self.LowThreshold ) self.opBigRegionsThreshold.Input.connect( self.opFinalChannelSelector.Output ) self.BigRegions.connect( self.opBigRegionsThreshold.Output )
def __init__(self, *args, **kwargs): super(_OpThresholdTwoLevels, self).__init__(*args, **kwargs) self._opLowThresholder = OpPixelOperator(parent=self) self._opLowThresholder.Input.connect(self.InputImage) self._opHighThresholder = OpPixelOperator(parent=self) self._opHighThresholder.Input.connect(self.InputImage) self._opLowLabeler = OpLabelVolume(parent=self) self._opLowLabeler.Method.setValue(_labeling_impl) self._opLowLabeler.Input.connect(self._opLowThresholder.Output) self._opHighLabeler = OpLabelVolume(parent=self) self._opHighLabeler.Method.setValue(_labeling_impl) self._opHighLabeler.Input.connect(self._opHighThresholder.Output) self._opHighLabelSizeFilter = OpFilterLabels(parent=self) self._opHighLabelSizeFilter.Input.connect(self._opHighLabeler.Output) self._opHighLabelSizeFilter.MinLabelSize.connect(self.MinSize) self._opHighLabelSizeFilter.MaxLabelSize.connect(self.MaxSize) self._opHighLabelSizeFilter.BinaryOut.setValue( False) # we do the binarization in opSelectLabels # this way, we get to display pretty colors self._opSelectLabels = OpSelectLabels(parent=self) self._opSelectLabels.BigLabels.connect(self._opLowLabeler.Output) self._opSelectLabels.SmallLabels.connect( self._opHighLabelSizeFilter.Output) # remove the remaining very large objects - # they might still be present in case a big object # was split into many small ones for the higher threshold # and they got reconnected again at lower threshold self._opFinalLabelSizeFilter = OpFilterLabels(parent=self) self._opFinalLabelSizeFilter.Input.connect(self._opSelectLabels.Output) self._opFinalLabelSizeFilter.MinLabelSize.connect(self.MinSize) self._opFinalLabelSizeFilter.MaxLabelSize.connect(self.MaxSize) self._opFinalLabelSizeFilter.BinaryOut.setValue(False) self._opCache = OpCompressedCache(parent=self) self._opCache.name = "_OpThresholdTwoLevels._opCache" self._opCache.InputHdf5.connect(self.InputHdf5) self._opCache.Input.connect(self._opFinalLabelSizeFilter.Output) # Connect our own outputs self.Output.connect(self._opFinalLabelSizeFilter.Output) self.CachedOutput.connect(self._opCache.Output) # Serialization outputs self.CleanBlocks.connect(self._opCache.CleanBlocks) self.OutputHdf5.connect(self._opCache.OutputHdf5) #self.InputChannel.connect( self._opChannelSelector.Output ) # More debug outputs. These all go through their own caches self._opBigRegionCache = OpCompressedCache(parent=self) self._opBigRegionCache.name = "_OpThresholdTwoLevels._opBigRegionCache" self._opBigRegionCache.Input.connect(self._opLowThresholder.Output) self.BigRegions.connect(self._opBigRegionCache.Output) self._opSmallRegionCache = OpCompressedCache(parent=self) self._opSmallRegionCache.name = "_OpThresholdTwoLevels._opSmallRegionCache" self._opSmallRegionCache.Input.connect(self._opHighThresholder.Output) self.SmallRegions.connect(self._opSmallRegionCache.Output) self._opFilteredSmallLabelsCache = OpCompressedCache(parent=self) self._opFilteredSmallLabelsCache.name = "_OpThresholdTwoLevels._opFilteredSmallLabelsCache" self._opFilteredSmallLabelsCache.Input.connect( self._opHighLabelSizeFilter.Output) self._opColorizeSmallLabels = OpColorizeLabels(parent=self) self._opColorizeSmallLabels.Input.connect( self._opFilteredSmallLabelsCache.Output) self.FilteredSmallLabels.connect(self._opColorizeSmallLabels.Output)
def __init__(self, *args, **kwargs): super(OpVigraWatershedViewer, self).__init__(*args, **kwargs) self._seedThreshold = None # Overview Schematic # Example here uses input channels 0,2,5 # InputChannelIndexes=[0,2,5] ---- # \ # InputImage --> opChannelSlicer .Slices[0] ---\ # .Slices[1] ----> opAverage -------------------------------------------------> opWatershed --> opWatershedCache --> opColorizer --> GUI # .Slices[2] ---/ \ / # \ MinSeedSize / # \ \ / # SeedThresholdValue ----------> opThreshold --> opSeedLabeler --> opSeedFilter --> opSeedCache --> opSeedColorizer --> GUI # Create operators self.opChannelSlicer = OpMultiArraySlicer2(parent=self) self.opAverage = OpMultiArrayMerger(parent=self) self.opWatershed = OpVigraWatershed(parent=self) self.opWatershedCache = OpSlicedBlockedArrayCache(parent=self) self.opColorizer = OpColorizeLabels(parent=self) self.opThreshold = OpPixelOperator(parent=self) self.opSeedLabeler = OpVigraLabelVolume(parent=self) self.opSeedFilter = OpFilterLabels(parent=self) self.opSeedCache = OpSlicedBlockedArrayCache(parent=self) self.opSeedColorizer = OpColorizeLabels(parent=self) # Select specific input channels self.opChannelSlicer.Input.connect(self.InputImage) self.opChannelSlicer.SliceIndexes.connect(self.InputChannelIndexes) self.opChannelSlicer.AxisFlag.setValue('c') # Average selected channels def average(arrays): if len(arrays) == 0: return 0 else: return sum(arrays) / float(len(arrays)) self.opAverage.MergingFunction.setValue(average) self.opAverage.Inputs.connect(self.opChannelSlicer.Slices) # Threshold for seeds self.opThreshold.Input.connect(self.opAverage.Output) # Label seeds self.opSeedLabeler.Input.connect(self.opThreshold.Output) # Filter seeds self.opSeedFilter.MinLabelSize.connect(self.MinSeedSize) self.opSeedFilter.Input.connect(self.opSeedLabeler.Output) # Cache seeds self.opSeedCache.fixAtCurrent.connect(self.FreezeCache) self.opSeedCache.Input.connect(self.opSeedFilter.Output) # Color seeds for RBG display self.opSeedColorizer.Input.connect(self.opSeedCache.Output) self.opSeedColorizer.OverrideColors.setValue({0: (0, 0, 0, 0)}) # Compute watershed labels (possibly with seeds, see setupOutputs) self.opWatershed.InputImage.connect(self.opAverage.Output) self.opWatershed.PaddingWidth.connect(self.WatershedPadding) # Cache the watershed output self.opWatershedCache.fixAtCurrent.connect(self.FreezeCache) self.opWatershedCache.Input.connect(self.opWatershed.Output) # Colorize the watershed labels for RGB display self.opColorizer.Input.connect(self.opWatershedCache.Output) self.opColorizer.OverrideColors.connect(self.OverrideLabels) # Connnect external outputs the operators that provide them self.Seeds.connect(self.opSeedCache.Output) self.ColoredPixels.connect(self.opColorizer.Output) self.SelectedInputChannels.connect(self.opChannelSlicer.Slices) self.SummedInput.connect(self.opAverage.Output) self.ColoredSeeds.connect(self.opSeedColorizer.Output)
def __init__(self, *args, **kwargs): super(OpThresholdTwoLevels, self).__init__(*args, **kwargs) self.opReorderInput = OpReorderAxes(parent=self) self.opReorderInput.AxisOrder.setValue('tzyxc') self.opReorderInput.Input.connect(self.InputImage) self.opSmoother = OpAnisotropicGaussianSmoothing5d(parent=self) self.opSmoother.Sigmas.connect(self.SmootherSigma) self.opSmoother.Input.connect(self.opReorderInput.Output) self.opSmootherCache = OpBlockedArrayCache(parent=self) self.opSmootherCache.BlockShape.setValue((1, None, None, None, 1)) self.opSmootherCache.Input.connect(self.opSmoother.Output) self.opCoreChannelSelector = OpSingleChannelSelector(parent=self) self.opCoreChannelSelector.Index.connect(self.CoreChannel) self.opCoreChannelSelector.Input.connect(self.opSmootherCache.Output) self.opCoreThreshold = OpLabeledThreshold(parent=self) self.opCoreThreshold.Method.setValue(ThresholdMethod.SIMPLE) self.opCoreThreshold.FinalThreshold.connect(self.HighThreshold) self.opCoreThreshold.Input.connect(self.opCoreChannelSelector.Output) self.opCoreFilter = OpFilterLabels(parent=self) self.opCoreFilter.BinaryOut.setValue(False) self.opCoreFilter.MinLabelSize.connect(self.MinSize) self.opCoreFilter.MaxLabelSize.connect(self.MaxSize) self.opCoreFilter.Input.connect(self.opCoreThreshold.Output) self.opFinalChannelSelector = OpSingleChannelSelector(parent=self) self.opFinalChannelSelector.Index.connect(self.Channel) self.opFinalChannelSelector.Input.connect(self.opSmootherCache.Output) self.opSumInputs = OpMultiArrayMerger( parent=self) # see setupOutputs (below) for input connections self.opSumInputs.MergingFunction.setValue(sum) self.opFinalThreshold = OpLabeledThreshold(parent=self) self.opFinalThreshold.Method.connect(self.CurOperator) self.opFinalThreshold.FinalThreshold.connect(self.LowThreshold) self.opFinalThreshold.GraphcutBeta.connect(self.Beta) self.opFinalThreshold.CoreLabels.connect(self.opCoreFilter.Output) self.opFinalThreshold.Input.connect(self.opSumInputs.Output) self.opFinalFilter = OpFilterLabels(parent=self) self.opFinalFilter.BinaryOut.setValue(False) self.opFinalFilter.MinLabelSize.connect(self.MinSize) self.opFinalFilter.MaxLabelSize.connect(self.MaxSize) self.opFinalFilter.Input.connect(self.opFinalThreshold.Output) self.opReorderOutput = OpReorderAxes(parent=self) #self.opReorderOutput.AxisOrder.setValue('tzyxc') # See setupOutputs() self.opReorderOutput.Input.connect(self.opFinalFilter.Output) self.Output.connect(self.opReorderOutput.Output) self.opCache = OpBlockedArrayCache(parent=self) self.opCache.CompressionEnabled.setValue(True) self.opCache.Input.connect(self.opReorderOutput.Output) self.CachedOutput.connect(self.opCache.Output) self.CleanBlocks.connect(self.opCache.CleanBlocks) ## Debug outputs self.Smoothed.connect(self.opSmootherCache.Output) self.InputChannel.connect(self.opFinalChannelSelector.Output) self.SmallRegions.connect(self.opCoreThreshold.Output) self.FilteredSmallLabels.connect(self.opCoreFilter.Output) self.BeforeSizeFilter.connect(self.opFinalThreshold.Output) # Since hysteresis thresholding creates the big regions and immediately discards the bad ones, # we have to recreate it here if the user wants to view it as a debug layer self.opBigRegionsThreshold = OpLabeledThreshold(parent=self) self.opBigRegionsThreshold.Method.setValue(ThresholdMethod.SIMPLE) self.opBigRegionsThreshold.FinalThreshold.connect(self.LowThreshold) self.opBigRegionsThreshold.Input.connect( self.opFinalChannelSelector.Output) self.BigRegions.connect(self.opBigRegionsThreshold.Output)