def __init__(self, parent=None, graph=None): super(OpCropSelection, self).__init__(parent=parent, graph=graph) # Hook up Cropping Pipeline self.opCropPipeline = OpMultiLaneWrapper( OpCropPipeline, parent=self, broadcastingSlotNames=['DeleteCrop']) self.opCropPipeline = OpCropPipeline(parent=self) self.CropNames.setValue([]) self.CropColors.setValue([]) self.PmapColors.setValue([]) self.NonzeroCropBlocks.connect(self.opCropPipeline.nonzeroBlocks) self.Crops.setValue(dict()) def _updateNumClasses(*args): """ When the number of labels changes, we MUST make sure that the prediction image changes its shape (the number of channels). Since setupOutputs is not called for mere dirty notifications, but is called in response to setValue(), we use this function to call setValue(). """ numClasses = len(self.CropNames.value) self.NumClasses.setValue(numClasses) self.CropNames.notifyDirty(_updateNumClasses) def inputResizeHandler(slot, oldsize, newsize): if (newsize == 0): self.LabelImages.resize(0) self.NonzeroLabelBlocks.resize(0) self.PredictionProbabilities.resize(0) self.CachedPredictionProbabilities.resize(0) self.InputImage.notifyResized(inputResizeHandler)
def __init__(self, *args, **kwargs): super(OpNestedMultiOps, self).__init__(*args, **kwargs) self.opSum1 = OpMultiLaneWrapper(OpSum, parent=self) self.opSum2 = OpMultiLaneWrapper(OpSum, parent=self) self.opSum3 = OpMultiLaneWrapper(OpSum, parent=self) self.opSum1.InputA.connect(self.InputA) self.opSum1.InputB.connect(self.InputB) self.opSum2.InputA.connect(self.InputA) self.opSum2.InputB.connect(self.InputB) self.opSum3.InputA.connect(self.opSum1.Output) self.opSum3.InputB.connect(self.opSum2.Output) self.Output.connect(self.opSum3.Output)
def __createTopLevelOperator(self): """ Called by the default implementation of ``topLevelOperator`` to create a multi-image operator by wrapping single-image operators. """ assert self.__topLevelOperator is None operatorClass = self.singleLaneOperatorClass operatorInitArgs, operatorInitKwargs = self.singleLaneOperatorInitArgs broadcastingSlots = self.broadcastingSlots if operatorClass is NotImplemented or broadcastingSlots is NotImplemented: message = "Could not create top-level operator for {}\n".format( self.__class__) message += "StandardApplet subclasses must implement the singleLaneOperatorClass and broadcastingSlots" message += " members OR override topLevelOperator themselves." raise NotImplementedError(message) if self.__workflow is None: message = "Could not create top-level operator for {}\n".format( self.__class__) message += "Please initialize StandardApplet base class with a workflow object." raise NotImplementedError(message) self.__topLevelOperator = OpMultiLaneWrapper( self.singleLaneOperatorClass, operator_args=operatorInitArgs, operator_kwargs=operatorInitKwargs, parent=self.__workflow, broadcastingSlotNames=self.broadcastingSlots)
def __init__( self, workflow, title, is_batch: bool = False, default_export_filename: str = "", pluginExportFunc: Optional[PluginExportCallable] = None, ): self.export_op = None self._default_export_filename = default_export_filename self.__topLevelOperator = OpMultiLaneWrapper( OpTrackingBaseDataExport, parent=workflow, promotedSlotNames=set(["RawData", "Inputs", "RawDatasetInfo"])) extra_serial_slots = [ SerialSlot(self.topLevelOperator.SelectedPlugin), SerialSlot(self.topLevelOperator.SelectedExportSource), SerialDictSlot(self.topLevelOperator.AdditionalPluginArguments), ] self._serializers = [ DataExportSerializer(self.topLevelOperator, title, extra_serial_slots) ] self._pluginExportFunc = pluginExportFunc super(TrackingBaseDataExportApplet, self).__init__(workflow, title, isBatch=is_batch)
def __init__(self, workflow, title, isBatch=False): # Designed to be subclassed: If the subclass defined its own top-level operator, # don't create one here. self.__topLevelOperator = None if self.topLevelOperator is None: self.__topLevelOperator = OpMultiLaneWrapper( OpDataExport, parent=workflow, promotedSlotNames=set(["RawData", "Inputs", "RawDatasetInfo"])) # Users can temporarily disconnect the 'transaction' # slot to force all slots to be applied atomically. self.topLevelOperator.TransactionSlot.setValue(True) super(DataExportApplet, self).__init__(title) self._gui = None self._title = title # This applet is designed to be subclassed. # If the user provided his own serializer, don't create one here. self.__serializers = None if self.dataSerializers is None: self.__serializers = [ DataExportSerializer(self.topLevelOperator, title) ] # This flag is set by the gui and checked by the workflow self.busy = False
def __init__(self, workflow, title, is_batch=False, default_export_filename=''): self.export_op = None self._default_export_filename = default_export_filename self.__topLevelOperator = OpMultiLaneWrapper( OpTrackingBaseDataExport, parent=workflow, promotedSlotNames=set(['RawData', 'Inputs', 'RawDatasetInfo'])) extra_serial_slots = [ SerialSlot(self.topLevelOperator.SelectedPlugin), SerialSlot(self.topLevelOperator.SelectedExportSource), SerialDictSlot(self.topLevelOperator.AdditionalPluginArguments) ] self._serializers = [ DataExportSerializer(self.topLevelOperator, title, extra_serial_slots) ] super(TrackingBaseDataExportApplet, self).__init__(workflow, title, isBatch=is_batch)
def __init__(self, blockDims=None, *args, **kwargs): super(OpLabelingTopLevel, self).__init__(*args, **kwargs) # Use a wrapper to create a labeling operator for each image lane self.opLabelLane = OpMultiLaneWrapper( OpLabelingSingleLane, operator_kwargs={'blockDims': blockDims}, parent=self) # Special connection: Label Input must get its metadata (shape, axistags) from the main input image. self.LabelInputs.connect(self.InputImages) # Connect external inputs -> internal inputs self.opLabelLane.InputImage.connect(self.InputImages) self.opLabelLane.LabelInput.connect(self.LabelInputs) self.opLabelLane.LabelEraserValue.connect(self.LabelEraserValue) self.opLabelLane.LabelDelete.connect(self.LabelDelete) # Initialize the delete input to -1, which means "no label". # Now changing this input to a positive value will cause label deletions. # (The deleteLabel input is monitored for changes.) self.LabelDelete.setValue(-1) # Connect internal outputs -> external outputs self.LabelImages.connect(self.opLabelLane.LabelImage) self.NonzeroLabelBlocks.connect(self.opLabelLane.NonzeroLabelBlocks) self.LabelColors.setValue([]) self.LabelNames.setValue([])
def __init__(self, *args, **kwargs): super(OpEdgeTrainingWithMulticut, self).__init__(*args, **kwargs) opEdgeTraining = OpEdgeTraining(parent=self) opEdgeTraining.EdgeLabelsDict.connect(self.EdgeLabelsDict) # This is necessary because OpEdgeTraining occasionally calls self.EdgeLabelsDict.setValue() opEdgeTraining.EdgeLabelsDict.backpropagate_values = True opEdgeTraining.FeatureNames.connect(self.FeatureNames) opEdgeTraining.FreezeClassifier.connect(self.FreezeClassifier) opEdgeTraining.RawData.connect(self.RawData) opEdgeTraining.VoxelData.connect(self.VoxelData) opEdgeTraining.Superpixels.connect(self.Superpixels) opEdgeTraining.GroundtruthSegmentation.connect( self.GroundtruthSegmentation) opEdgeTraining.WatershedSelectedInput.connect( self.WatershedSelectedInput) opEdgeTraining.TrainRandomForest.connect(self.TrainRandomForest) self.Rag.connect(opEdgeTraining.Rag) self.EdgeProbabilities.connect(opEdgeTraining.EdgeProbabilities) self.EdgeProbabilitiesDict.connect( opEdgeTraining.EdgeProbabilitiesDict) self.NaiveSegmentation.connect(opEdgeTraining.NaiveSegmentation) opMulticut = OpMultiLaneWrapper(OpMulticut, broadcastingSlotNames=[ "Beta", "SolverName", "FreezeCache", "ProbabilityThreshold" ], parent=self) opMulticut.Beta.connect(self.Beta) opMulticut.SolverName.connect(self.SolverName) opMulticut.FreezeCache.connect(self.FreezeCache) opMulticut.RawData.connect(self.RawData) opMulticut.Superpixels.connect(opEdgeTraining.Superpixels) opMulticut.Rag.connect(opEdgeTraining.Rag) opMulticut.EdgeProbabilities.connect(opEdgeTraining.EdgeProbabilities) opMulticut.EdgeProbabilitiesDict.connect( opEdgeTraining.EdgeProbabilitiesDict) opMulticut.ProbabilityThreshold.connect(self.ProbabilityThreshold) self.Output.connect(opMulticut.Output) self.EdgeLabelDisagreementDict.connect( opMulticut.EdgeLabelDisagreementDict) self.opEdgeTraining = opEdgeTraining self.opMulticut = opMulticut # Must expose these members, which are needed by the serializers or GUI # (Therefore, they are really part of those classes public API, or should be.) self.opRagCache = self.opEdgeTraining.opRagCache self.opEdgeFeaturesCache = self.opEdgeTraining.opEdgeFeaturesCache self.opClassifierCache = self.opEdgeTraining.opClassifierCache self.setEdgeLabelsFromGroundtruth = self.opEdgeTraining.setEdgeLabelsFromGroundtruth
def __init__( self, workflow, title, isBatch=False ): # Our operator is a subclass of the generic data export operator self._topLevelOperator = OpMultiLaneWrapper( OpNansheDataExport, parent=workflow, promotedSlotNames=set(['RawData', 'Inputs', 'RawDatasetInfo']) ) self._gui = None self._title = title self._serializers = [ DataExportSerializer(self._topLevelOperator, title) ] # Base class init super(NansheDataExportApplet, self).__init__(workflow, title, isBatch)
def __init__(self, workflow, title, isBatch=False): # Our operator is a subclass of the generic data export operator self._topLevelOperator = OpMultiLaneWrapper( OpPixelClassificationDataExport, parent=workflow, promotedSlotNames=set(["RawData", "Inputs", "RawDatasetInfo", "ConstraintDataset"]), ) self._gui = None self._title = title self._serializers = [DataExportSerializer(self._topLevelOperator, title)] # Base class init super(PixelClassificationDataExportApplet, self).__init__(workflow, title, isBatch)
def __init__(self, workflow, projectFileGroupName, hintOverlayFile=None, pmapOverlayFile=None): if hintOverlayFile is not None: assert isinstance(hintOverlayFile, str) if not hasattr(self, '_topLevelOperator'): op_kwargs = { 'hintOverlayFile' : hintOverlayFile, 'pmapOverlayFile' : pmapOverlayFile } self._topLevelOperator = OpMultiLaneWrapper( OpCarving, parent=workflow, operator_kwargs=op_kwargs ) super(CarvingApplet, self).__init__(workflow, projectFileGroupName) self._projectFileGroupName = projectFileGroupName self._serializers = [CarvingSerializer(self.topLevelOperator, self._projectFileGroupName)]
def __init__(self, workflow, title, isBatch=False): self._topLevelOperator = OpMultiLaneWrapper( OpNNClassificationDataExport, parent=workflow, promotedSlotNames=set(["RawData", "Inputs", "RawDatasetInfo"]), ) self._title = title self._serializers = [ DataExportSerializer(self._topLevelOperator, title) ] # Base class init super(NNClassificationDataExportApplet, self).__init__(workflow, title, isBatch)
def __init__(self, workflow, title, isBatch=False): self._topLevelOperator = OpMultiLaneWrapper( OpDataExport, parent=workflow, promotedSlotNames=set(['RawData', 'Input', 'RawDatasetInfo'])) # Users can temporarily disconnect the 'transaction' # slot to force all slots to be applied atomically. self._topLevelOperator.TransactionSlot.setValue(True) super(DataExportApplet, self).__init__(title, syncWithImageIndex=not isBatch) self._gui = None self._title = title self._serializers = [ DataExportSerializer(self._topLevelOperator, title) ]
def __init__(self, workflow, title): self._topLevelOperator = OpMultiLaneWrapper(OpBatchIo, parent=workflow, promotedSlotNames=set([ 'DatasetPath', 'ImageToExport', 'OutputFileNameBase', 'RawImage' ])) super(BatchIoApplet, self).__init__(title, syncWithImageIndex=False) self._serializableItems = [ BatchIoSerializer(self._topLevelOperator, title) ] self._gui = None self._title = title
def __init__(self, workflow, *args, **kwargs): if 'default_export_filename' in kwargs: default_export_filename = kwargs['default_export_filename'] del kwargs['default_export_filename'] else: default_export_filename = "" self.export_op = None self._default_export_filename = default_export_filename self.__topLevelOperator = OpMultiLaneWrapper( OpTrackingBaseDataExport, parent=workflow, promotedSlotNames=set(['RawData', 'Inputs', 'RawDatasetInfo'])) super(TrackingBaseDataExportApplet, self).__init__(workflow, *args, **kwargs)
def __init__(self, workflow, title, opCounting, isBatch=False): # Our operator is a subclass of the generic data export operator self._topLevelOperator = OpMultiLaneWrapper( OpCountingDataExport, parent=workflow, promotedSlotNames=set(["RawData", "Inputs", "RawDatasetInfo"])) self._gui = None self._title = title self._serializers = [ DataExportSerializer( self._topLevelOperator, title, [SerialSlot(self._topLevelOperator.CsvFilepath)]) ] self.opCounting = opCounting # Base class init super(CountingDataExportApplet, self).__init__(workflow, title, isBatch)
def __init__(self, workflow, title): # Operator is a subclass of the generic batch operator. self._topLevelOperator = OpMultiLaneWrapper(OpCountingBatchResults, parent=workflow, promotedSlotNames=set([ 'DatasetPath', 'ImageToExport', 'OutputFileNameBase', 'RawImage' ])) super(CountingBatchResultsApplet, self).__init__(title, syncWithImageIndex=False) # Serializer is the same as the batch io self._serializableItems = [ BatchIoSerializer(self._topLevelOperator, title) ] self._gui = None self._title = title
def __init__(self, *args, **kwargs): super(OpEdgeTraining, self).__init__(*args, **kwargs) self.opCreateRag = OpMultiLaneWrapper(OpCreateRag, parent=self) self.opCreateRag.Superpixels.connect(self.Superpixels) self.opRagCache = OpMultiLaneWrapper( OpValueCache, parent=self, broadcastingSlotNames=['fixAtCurrent']) self.opRagCache.Input.connect(self.opCreateRag.Rag) self.opRagCache.name = 'opRagCache' self.opComputeEdgeFeatures = OpMultiLaneWrapper( OpComputeEdgeFeatures, parent=self, broadcastingSlotNames=['FeatureNames']) self.opComputeEdgeFeatures.FeatureNames.connect(self.FeatureNames) self.opComputeEdgeFeatures.VoxelData.connect(self.VoxelData) self.opComputeEdgeFeatures.Rag.connect(self.opRagCache.Output) self.opEdgeFeaturesCache = OpMultiLaneWrapper( OpValueCache, parent=self, broadcastingSlotNames=['fixAtCurrent']) self.opEdgeFeaturesCache.Input.connect( self.opComputeEdgeFeatures.EdgeFeaturesDataFrame) self.opEdgeFeaturesCache.name = 'opEdgeFeaturesCache' self.opTrainEdgeClassifier = OpTrainEdgeClassifier(parent=self) self.opTrainEdgeClassifier.EdgeLabelsDict.connect(self.EdgeLabelsDict) self.opTrainEdgeClassifier.EdgeFeaturesDataFrame.connect( self.opEdgeFeaturesCache.Output) # classifier cache input is set after training. self.opClassifierCache = OpValueCache(parent=self) self.opClassifierCache.Input.connect( self.opTrainEdgeClassifier.EdgeClassifier) self.opClassifierCache.fixAtCurrent.connect(self.FreezeClassifier) self.opClassifierCache.name = 'opClassifierCache' self.opPredictEdgeProbabilities = OpMultiLaneWrapper( OpPredictEdgeProbabilities, parent=self, broadcastingSlotNames=['EdgeClassifier']) self.opPredictEdgeProbabilities.EdgeClassifier.connect( self.opClassifierCache.Output) self.opPredictEdgeProbabilities.EdgeFeaturesDataFrame.connect( self.opEdgeFeaturesCache.Output) self.opEdgeProbabilitiesCache = OpMultiLaneWrapper( OpValueCache, parent=self, broadcastingSlotNames=['fixAtCurrent']) self.opEdgeProbabilitiesCache.Input.connect( self.opPredictEdgeProbabilities.EdgeProbabilities) self.opEdgeProbabilitiesCache.name = 'opEdgeProbabilitiesCache' self.opEdgeProbabilitiesCache.fixAtCurrent.connect( self.FreezeClassifier) self.opEdgeProbabilitiesDict = OpMultiLaneWrapper( OpEdgeProbabilitiesDict, parent=self) self.opEdgeProbabilitiesDict.Rag.connect(self.opRagCache.Output) self.opEdgeProbabilitiesDict.EdgeProbabilities.connect( self.opEdgeProbabilitiesCache.Output) self.opEdgeProbabilitiesDictCache = OpMultiLaneWrapper( OpValueCache, parent=self, broadcastingSlotNames=['fixAtCurrent']) self.opEdgeProbabilitiesDictCache.Input.connect( self.opEdgeProbabilitiesDict.EdgeProbabilitiesDict) self.opEdgeProbabilitiesDictCache.name = 'opEdgeProbabilitiesDictCache' self.opNaiveSegmentation = OpMultiLaneWrapper(OpNaiveSegmentation, parent=self) self.opNaiveSegmentation.Superpixels.connect(self.Superpixels) self.opNaiveSegmentation.Rag.connect(self.opRagCache.Output) self.opNaiveSegmentation.EdgeProbabilities.connect( self.opEdgeProbabilitiesCache.Output) self.opNaiveSegmentationCache = OpMultiLaneWrapper( OpBlockedArrayCache, parent=self, broadcastingSlotNames=[ 'CompressionEnabled', 'fixAtCurrent', 'BypassModeEnabled' ]) self.opNaiveSegmentationCache.CompressionEnabled.setValue(True) self.opNaiveSegmentationCache.Input.connect( self.opNaiveSegmentation.Output) self.opNaiveSegmentationCache.name = 'opNaiveSegmentationCache' self.Rag.connect(self.opRagCache.Output) self.EdgeProbabilities.connect(self.opEdgeProbabilitiesCache.Output) self.EdgeProbabilitiesDict.connect( self.opEdgeProbabilitiesDictCache.Output) self.NaiveSegmentation.connect(self.opNaiveSegmentationCache.Output) # All input multi-slots should be kept in sync # Output multi-slots will auto-sync via the graph multiInputs = filter(lambda s: s.level >= 1, self.inputs.values()) for s1 in multiInputs: for s2 in multiInputs: if s1 != s2: def insertSlot(a, b, position, finalsize): a.insertSlot(position, finalsize) s1.notifyInserted(partial(insertSlot, s2)) def removeSlot(a, b, position, finalsize): a.removeSlot(position, finalsize) s1.notifyRemoved(partial(removeSlot, s2)) # If superpixels change, we have to delete our edge labels. # Since we're dealing with multi-lane slot, setting up dirty handlers is a two-stage process. # (1) React to lane insertion by subscribing to dirty signals for the new lane. # (2) React to each lane's dirty signal by deleting the labels for that lane. def subscribe_to_dirty_sp(slot, position, finalsize): # A new lane was added. Subscribe to it's dirty signal. assert slot is self.Superpixels self.Superpixels[position].notifyDirty( self.handle_dirty_superpixels) self.Superpixels[position].notifyReady( self.handle_dirty_superpixels) self.Superpixels[position].notifyUnready( self.handle_dirty_superpixels) # When a new lane is added, set up the listener for dirtyness. self.Superpixels.notifyInserted(subscribe_to_dirty_sp)
def __init__(self, *args, **kwargs): """ Instantiate all internal operators and connect them together. """ super(OpCounting, self).__init__(*args, **kwargs) # Default values for some input slots self.FreezePredictions.setValue(True) self.LabelNames.setValue(["Foreground", "Background"]) self.LabelColors.setValue([(255, 0, 0), (0, 255, 0)]) self.PmapColors.setValue([(255, 0, 0), (0, 255, 0)]) # SPECIAL connection: The LabelInputs slot doesn't get it's data # from the InputImages slot, but it's shape must match. self.LabelInputs.connect(self.InputImages) self.BoxLabelInputs.connect(self.InputImages) # Hook up Labeling Pipeline self.opLabelPipeline = OpMultiLaneWrapper(OpLabelPipeline, parent=self) self.opLabelPipeline.RawImage.connect(self.InputImages) self.opLabelPipeline.LabelInput.connect(self.LabelInputs) self.opLabelPipeline.BoxLabelInput.connect(self.BoxLabelInputs) self.LabelImages.connect(self.opLabelPipeline.Output) self.NonzeroLabelBlocks.connect(self.opLabelPipeline.nonzeroBlocks) self.BoxLabelImages.connect(self.opLabelPipeline.BoxOutput) self.GetFore = OpMultiLaneWrapper(OpPixelOperator, parent=self) def conv(arr): numpy.place(arr, arr == 2, 0) return arr.astype(numpy.float) self.GetFore.Function.setValue(conv) self.GetFore.Input.connect(self.opLabelPipeline.Output) self.LabelPreviewer = OpMultiLaneWrapper(OpLabelPreviewer, parent=self) self.LabelPreviewer.Input.connect(self.GetFore.Output) self.LabelPreview.connect(self.LabelPreviewer.Output) # Hook up the Training operator self.opUpperBound = OpUpperBound(parent=self, graph=self.graph) self.UpperBound.connect(self.opUpperBound.UpperBound) self.boxViewer = OpBoxViewer(parent=self, graph=self.graph) self.opTrain = OpTrainCounter(parent=self, graph=self.graph) self.opTrain.inputs['ForegroundLabels'].connect(self.GetFore.Output) self.opTrain.inputs['BackgroundLabels'].connect( self.opLabelPipeline.Output) self.opTrain.inputs['Images'].connect(self.CachedFeatureImages) self.opTrain.inputs["nonzeroLabelBlocks"].connect( self.opLabelPipeline.nonzeroBlocks) self.opTrain.inputs['fixClassifier'].setValue(True) self.opTrain.inputs["UpperBound"].connect(self.opUpperBound.UpperBound) # Hook up the Classifier Cache # The classifier is cached here to allow serializers to force in # a pre-calculated classifier (loaded from disk) self.classifier_cache = OpValueCache(parent=self, graph=self.graph) self.classifier_cache.inputs["Input"].connect( self.opTrain.outputs['Classifier']) self.Classifier.connect(self.classifier_cache.Output) # Hook up the prediction pipeline inputs self.opPredictionPipeline = OpMultiLaneWrapper(OpPredictionPipeline, parent=self) self.opPredictionPipeline.FeatureImages.connect(self.FeatureImages) self.opPredictionPipeline.CachedFeatureImages.connect( self.CachedFeatureImages) self.opPredictionPipeline.MaxLabel.setValue(2) self.opPredictionPipeline.Classifier.connect( self.classifier_cache.Output) self.opPredictionPipeline.FreezePredictions.connect( self.FreezePredictions) self.opPredictionPipeline.PredictionsFromDisk.connect( self.PredictionsFromDisk) # Prediction pipeline outputs -> Top-level outputs self.PredictionProbabilities.connect( self.opPredictionPipeline.PredictionProbabilities) self.CachedPredictionProbabilities.connect( self.opPredictionPipeline.CachedPredictionProbabilities) self.HeadlessPredictionProbabilities.connect( self.opPredictionPipeline.HeadlessPredictionProbabilities) #self.HeadlessUint8PredictionProbabilities.connect( self.opPredictionPipeline.HeadlessUint8PredictionProbabilities ) #self.PredictionProbabilityChannels.connect( self.opPredictionPipeline.PredictionProbabilityChannels ) #self.SegmentationChannels.connect( self.opPredictionPipeline.SegmentationChannels ) self.UncertaintyEstimate.connect( self.opPredictionPipeline.UncertaintyEstimate) self.Density.connect( self.opPredictionPipeline.CachedPredictionProbabilities) self.OutputSum.connect(self.opPredictionPipeline.OutputSum) def inputResizeHandler(slot, oldsize, newsize): if (newsize == 0): self.LabelImages.resize(0) self.NonzeroLabelBlocks.resize(0) self.PredictionProbabilities.resize(0) self.CachedPredictionProbabilities.resize(0) self.InputImages.notifyResized(inputResizeHandler) # Debug assertions: Check to make sure the non-wrapped operators stayed that way. assert self.opTrain.Images.operator == self.opTrain def handleNewInputImage(multislot, index, *args): def handleInputReady(slot): self._checkConstraints(index) self.setupCaches(multislot.index(slot)) multislot[index].notifyReady(handleInputReady) self.InputImages.notifyInserted(handleNewInputImage) # All input multi-slots should be kept in sync # Output multi-slots will auto-sync via the graph multiInputs = filter(lambda s: s.level >= 1, self.inputs.values()) for s1 in multiInputs: for s2 in multiInputs: if s1 != s2: def insertSlot(a, b, position, finalsize): a.insertSlot(position, finalsize) s1.notifyInserted(partial(insertSlot, s2)) def removeSlot(a, b, position, finalsize): a.removeSlot(position, finalsize) s1.notifyRemoved(partial(removeSlot, s2)) self.options = self.opTrain.options
def __init__(self, *args, **kwargs): """ Instantiate all internal operators and connect them together. """ super(OpPixelClassification, self).__init__(*args, **kwargs) # Default values for some input slots self.FreezePredictions.setValue(True) self.LabelNames.setValue([]) self.LabelColors.setValue([]) self.PmapColors.setValue([]) # SPECIAL connection: The LabelInputs slot doesn't get it's data # from the InputImages slot, but it's shape must match. self.LabelInputs.connect(self.InputImages) # Hook up Labeling Pipeline self.opLabelPipeline = OpMultiLaneWrapper(OpLabelPipeline, parent=self) self.opLabelPipeline.RawImage.connect(self.InputImages) self.opLabelPipeline.LabelInput.connect(self.LabelInputs) self.LabelImages.connect(self.opLabelPipeline.Output) self.NonzeroLabelBlocks.connect(self.opLabelPipeline.nonzeroBlocks) # Find the highest label in all the label images self.opMaxLabel = OpMaxValue(parent=self) self.opMaxLabel.Inputs.connect(self.opLabelPipeline.MaxLabel) self.MaxLabelValue.connect(self.opMaxLabel.Output) # Hook up the Training operator self.opTrain = OpTrainRandomForestBlocked(parent=self) self.opTrain.inputs['Labels'].connect(self.opLabelPipeline.Output) self.opTrain.inputs['Images'].connect(self.CachedFeatureImages) self.opTrain.inputs['MaxLabel'].connect(self.opMaxLabel.Output) self.opTrain.inputs["nonzeroLabelBlocks"].connect( self.opLabelPipeline.nonzeroBlocks) self.opTrain.inputs['fixClassifier'].setValue(False) # Hook up the Classifier Cache # The classifier is cached here to allow serializers to force in # a pre-calculated classifier (loaded from disk) self.classifier_cache = OpValueCache(parent=self) self.classifier_cache.inputs["Input"].connect( self.opTrain.outputs['Classifier']) self.Classifier.connect(self.classifier_cache.Output) # Hook up the prediction pipeline inputs self.opPredictionPipeline = OpMultiLaneWrapper(OpPredictionPipeline, parent=self) self.opPredictionPipeline.FeatureImages.connect(self.FeatureImages) self.opPredictionPipeline.CachedFeatureImages.connect( self.CachedFeatureImages) self.opPredictionPipeline.MaxLabel.connect(self.opMaxLabel.Output) self.opPredictionPipeline.Classifier.connect( self.classifier_cache.Output) self.opPredictionPipeline.FreezePredictions.connect( self.FreezePredictions) self.opPredictionPipeline.PredictionsFromDisk.connect( self.PredictionsFromDisk) # Prediction pipeline outputs -> Top-level outputs self.PredictionProbabilities.connect( self.opPredictionPipeline.PredictionProbabilities) self.CachedPredictionProbabilities.connect( self.opPredictionPipeline.CachedPredictionProbabilities) self.HeadlessPredictionProbabilities.connect( self.opPredictionPipeline.HeadlessPredictionProbabilities) self.HeadlessUint8PredictionProbabilities.connect( self.opPredictionPipeline.HeadlessUint8PredictionProbabilities) self.PredictionProbabilityChannels.connect( self.opPredictionPipeline.PredictionProbabilityChannels) self.SegmentationChannels.connect( self.opPredictionPipeline.SegmentationChannels) self.UncertaintyEstimate.connect( self.opPredictionPipeline.UncertaintyEstimate) def inputResizeHandler(slot, oldsize, newsize): if (newsize == 0): self.LabelImages.resize(0) self.NonzeroLabelBlocks.resize(0) self.PredictionProbabilities.resize(0) self.CachedPredictionProbabilities.resize(0) self.InputImages.notifyResized(inputResizeHandler) # Debug assertions: Check to make sure the non-wrapped operators stayed that way. assert self.opMaxLabel.Inputs.operator == self.opMaxLabel assert self.opTrain.Images.operator == self.opTrain def handleNewInputImage(multislot, index, *args): def handleInputReady(slot): self._checkConstraints(index) self.setupCaches(multislot.index(slot)) multislot[index].notifyReady(handleInputReady) self.InputImages.notifyInserted(handleNewInputImage) # All input multi-slots should be kept in sync # Output multi-slots will auto-sync via the graph multiInputs = filter(lambda s: s.level >= 1, self.inputs.values()) for s1 in multiInputs: for s2 in multiInputs: if s1 != s2: def insertSlot(a, b, position, finalsize): a.insertSlot(position, finalsize) s1.notifyInserted(partial(insertSlot, s2)) def removeSlot(a, b, position, finalsize): a.removeSlot(position, finalsize) s1.notifyRemoved(partial(removeSlot, s2))
def __init__(self, *args, **kwargs): """ Instantiate all internal operators and connect them together. """ super(OpPixelClassification, self).__init__(*args, **kwargs) # Default values for some input slots self.FreezePredictions.setValue(True) self.LabelNames.setValue([]) self.LabelColors.setValue([]) self.PmapColors.setValue([]) # SPECIAL connection: The LabelInputs slot doesn't get it's data # from the InputImages slot, but it's shape must match. self.LabelInputs.connect(self.InputImages) # Hook up Labeling Pipeline self.opLabelPipeline = OpMultiLaneWrapper( OpLabelPipeline, parent=self, broadcastingSlotNames=['DeleteLabel']) self.opLabelPipeline.RawImage.connect(self.InputImages) self.opLabelPipeline.LabelInput.connect(self.LabelInputs) self.opLabelPipeline.DeleteLabel.setValue(-1) self.LabelImages.connect(self.opLabelPipeline.Output) self.NonzeroLabelBlocks.connect(self.opLabelPipeline.nonzeroBlocks) # Hook up the Training operator self.opTrain = OpTrainClassifierBlocked(parent=self) self.opTrain.ClassifierFactory.connect(self.ClassifierFactory) self.opTrain.Labels.connect(self.opLabelPipeline.Output) self.opTrain.Images.connect(self.FeatureImages) self.opTrain.nonzeroLabelBlocks.connect( self.opLabelPipeline.nonzeroBlocks) # Hook up the Classifier Cache # The classifier is cached here to allow serializers to force in # a pre-calculated classifier (loaded from disk) self.classifier_cache = OpValueCache(parent=self) self.classifier_cache.name = "OpPixelClassification.classifier_cache" self.classifier_cache.inputs["Input"].connect( self.opTrain.outputs['Classifier']) self.classifier_cache.inputs["fixAtCurrent"].connect( self.FreezePredictions) self.Classifier.connect(self.classifier_cache.Output) # Hook up the prediction pipeline inputs self.opPredictionPipeline = OpMultiLaneWrapper(OpPredictionPipeline, parent=self) self.opPredictionPipeline.FeatureImages.connect(self.FeatureImages) self.opPredictionPipeline.CachedFeatureImages.connect( self.CachedFeatureImages) self.opPredictionPipeline.Classifier.connect( self.classifier_cache.Output) self.opPredictionPipeline.FreezePredictions.connect( self.FreezePredictions) self.opPredictionPipeline.PredictionsFromDisk.connect( self.PredictionsFromDisk) self.opPredictionPipeline.PredictionMask.connect(self.PredictionMasks) # Feature Selection Stuff self.opFeatureMatrixCaches = OpMultiLaneWrapper(OpFeatureMatrixCache, parent=self) self.opFeatureMatrixCaches.LabelImage.connect( self.opLabelPipeline.Output) self.opFeatureMatrixCaches.FeatureImage.connect(self.FeatureImages) self.opFeatureMatrixCaches.LabelImage.setDirty( ) # do I still need this? def _updateNumClasses(*args): """ When the number of labels changes, we MUST make sure that the prediction image changes its shape (the number of channels). Since setupOutputs is not called for mere dirty notifications, but is called in response to setValue(), we use this function to call setValue(). """ numClasses = len(self.LabelNames.value) self.opTrain.MaxLabel.setValue(numClasses) self.opPredictionPipeline.NumClasses.setValue(numClasses) self.NumClasses.setValue(numClasses) self.LabelNames.notifyDirty(_updateNumClasses) # Prediction pipeline outputs -> Top-level outputs self.PredictionProbabilities.connect( self.opPredictionPipeline.PredictionProbabilities) self.PredictionProbabilitiesUint8.connect( self.opPredictionPipeline.PredictionProbabilitiesUint8) self.CachedPredictionProbabilities.connect( self.opPredictionPipeline.CachedPredictionProbabilities) self.HeadlessPredictionProbabilities.connect( self.opPredictionPipeline.HeadlessPredictionProbabilities) self.HeadlessUint8PredictionProbabilities.connect( self.opPredictionPipeline.HeadlessUint8PredictionProbabilities) self.PredictionProbabilityChannels.connect( self.opPredictionPipeline.PredictionProbabilityChannels) self.SegmentationChannels.connect( self.opPredictionPipeline.SegmentationChannels) self.UncertaintyEstimate.connect( self.opPredictionPipeline.UncertaintyEstimate) self.SimpleSegmentation.connect( self.opPredictionPipeline.SimpleSegmentation) self.HeadlessUncertaintyEstimate.connect( self.opPredictionPipeline.HeadlessUncertaintyEstimate) def inputResizeHandler(slot, oldsize, newsize): if (newsize == 0): self.LabelImages.resize(0) self.NonzeroLabelBlocks.resize(0) self.PredictionProbabilities.resize(0) self.CachedPredictionProbabilities.resize(0) self.InputImages.notifyResized(inputResizeHandler) # Debug assertions: Check to make sure the non-wrapped operators stayed that way. assert self.opTrain.Images.operator == self.opTrain def handleNewInputImage(multislot, index, *args): def handleInputReady(slot): self._checkConstraints(index) self.setupCaches(multislot.index(slot)) multislot[index].notifyReady(handleInputReady) self.InputImages.notifyInserted(handleNewInputImage) # If any feature image changes shape, we need to verify that the # channels are consistent with the currently cached classifier # Otherwise, delete the currently cached classifier. def handleNewFeatureImage(multislot, index, *args): def handleFeatureImageReady(slot): def handleFeatureMetaChanged(slot): if (self.classifier_cache.fixAtCurrent.value and self.classifier_cache.Output.ready() and slot.meta.shape is not None): classifier = self.classifier_cache.Output.value channel_names = slot.meta.channel_names if classifier and classifier.feature_names != channel_names: self.classifier_cache.resetValue() slot.notifyMetaChanged(handleFeatureMetaChanged) multislot[index].notifyReady(handleFeatureImageReady) self.FeatureImages.notifyInserted(handleNewFeatureImage) def handleNewMaskImage(multislot, index, *args): def handleInputReady(slot): self._checkConstraints(index) multislot[index].notifyReady(handleInputReady) self.PredictionMasks.notifyInserted(handleNewMaskImage) # All input multi-slots should be kept in sync # Output multi-slots will auto-sync via the graph multiInputs = filter(lambda s: s.level >= 1, self.inputs.values()) for s1 in multiInputs: for s2 in multiInputs: if s1 != s2: def insertSlot(a, b, position, finalsize): a.insertSlot(position, finalsize) s1.notifyInserted(partial(insertSlot, s2)) def removeSlot(a, b, position, finalsize): a.removeSlot(position, finalsize) s1.notifyRemoved(partial(removeSlot, s2))
def __init__(self, *args, connectionFactory, **kwargs): """ Instantiate all internal operators and connect them together. """ super(OpNNClassification, self).__init__(*args, **kwargs) self._connectionFactory = connectionFactory # # Default values for some input slots self.FreezePredictions.setValue(True) self.LabelNames.setValue([]) self.LabelColors.setValue([]) self.PmapColors.setValue([]) self.Checkpoints.setValue([]) self._binary_model = None # SPECIAL connection: the LabelInputs slot doesn't get it's data # from the InputImages slot, but it's shape must match. self.LabelInputs.connect(self.InputImages) self.opBlockShape = OpMultiLaneWrapper(OpBlockShape, parent=self) self.opBlockShape.RawImage.connect(self.InputImages) self.opBlockShape.ModelSession.connect(self.ModelSession) # self.opModel = OpModel(parent=self.parent, connectionFactory=connectionFactory) # self.opModel.ServerConfig.connect(self.ServerConfig) # self.opModel.ModelBinary.connect(self.ModelBinary) # self.ModelSession.connect(self.opModel.TiktorchModel) # self.NumClasses.connect(self.opModel.NumClasses) # Hook up Labeling Pipeline self.opLabelPipeline = OpMultiLaneWrapper( OpLabelPipeline, parent=self, broadcastingSlotNames=["DeleteLabel"]) self.opLabelPipeline.RawImage.connect(self.InputImages) self.opLabelPipeline.LabelInput.connect(self.LabelInputs) self.opLabelPipeline.DeleteLabel.setValue(-1) self.LabelImages.connect(self.opLabelPipeline.Output) self.NonzeroLabelBlocks.connect(self.opLabelPipeline.nonzeroBlocks) # TRAINING OPERATOR self.opTrain = OpTikTorchTrainClassifierBlocked(parent=self) self.opTrain.ModelSession.connect(self.ModelSession) self.opTrain.Labels.connect(self.opLabelPipeline.Output) self.opTrain.Images.connect(self.InputImages) self.opTrain.BlockShape.connect(self.opBlockShape.BlockShapeTrain) self.opTrain.nonzeroLabelBlocks.connect( self.opLabelPipeline.nonzeroBlocks) self.opTrain.MaxLabel.connect(self.NumClasses) # CLASSIFIER CACHE # This cache stores exactly one object: the classifier itself. self.classifier_cache = OpValueCache(parent=self) self.classifier_cache.name = "OpNetworkClassification.classifier_cache" self.classifier_cache.inputs["Input"].connect( self.opTrain.UpdatedModelSession) self.classifier_cache.inputs["fixAtCurrent"].connect( self.FreezePredictions) self.Classifier.connect(self.classifier_cache.Output) # Hook up the prediction pipeline inputs self.opPredictionPipeline = OpMultiLaneWrapper(OpPredictionPipeline, parent=self) self.opPredictionPipeline.RawImage.connect(self.InputImages) # self.opPredictionPipeline.Classifier.connect(self.classifier_cache.Output) self.opPredictionPipeline.Classifier.connect(self.ModelSession) self.opPredictionPipeline.NumClasses.connect(self.NumClasses) self.opPredictionPipeline.FreezePredictions.connect( self.FreezePredictions) self.PredictionProbabilities.connect( self.opPredictionPipeline.PredictionProbabilities) self.CachedPredictionProbabilities.connect( self.opPredictionPipeline.CachedPredictionProbabilities) self.PredictionProbabilityChannels.connect( self.opPredictionPipeline.PredictionProbabilityChannels) def inputResizeHandler(slot, oldsize, newsize): if newsize == 0: self.LabelImages.resize(0) self.NonzeroLabelBlocks.resize(0) self.PredictionProbabilities.resize(0) self.CachedPredictionProbabilities.resize(0) self.InputImages.notifyResized(inputResizeHandler) # Debug assertions: Check to make sure the non-wrapped operators stayed that way. assert self.opTrain.Images.operator == self.opTrain def handleNewInputImage(multislot, index, *args): def handleInputReady(slot): self._checkConstraints(index) self.setupCaches(multislot.index(slot)) multislot[index].notifyReady(handleInputReady) self.InputImages.notifyInserted(handleNewInputImage) # All input multi-slots should be kept in sync # Output multi-slots will auto-sync via the graph multiInputs = [s for s in list(self.inputs.values()) if s.level >= 1] for s1 in multiInputs: for s2 in multiInputs: if s1 != s2: def insertSlot(a, b, position, finalsize): a.insertSlot(position, finalsize) s1.notifyInserted(partial(insertSlot, s2)) def removeSlot(a, b, position, finalsize): a.removeSlot(position, finalsize) s1.notifyRemoved(partial(removeSlot, s2))
def __init__(self, *args, **kwargs): super(OpObjectClassification, self).__init__(*args, **kwargs) # internal operators opkwargs = dict(parent=self) self.opTrain = OpObjectTrain(parent=self) self.opPredict = OpMultiLaneWrapper(OpObjectPredict, **opkwargs) self.opLabelsToImage = OpMultiLaneWrapper(OpRelabelSegmentation, **opkwargs) self.opPredictionsToImage = OpMultiLaneWrapper(OpRelabelSegmentation, **opkwargs) self.opPredictionImageCache = OpMultiLaneWrapper( OpSlicedBlockedArrayCache, **opkwargs) self.opProbabilityChannelsToImage = OpMultiLaneWrapper( OpMultiRelabelSegmentation, **opkwargs) self.opBadObjectsToImage = OpMultiLaneWrapper(OpRelabelSegmentation, **opkwargs) self.opBadObjectsToWarningMessage = OpBadObjectsToWarningMessage( parent=self) self.classifier_cache = OpValueCache(parent=self) # connect inputs self.opTrain.Features.connect(self.ObjectFeatures) self.opTrain.Labels.connect(self.LabelInputs) self.opTrain.FixClassifier.setValue(False) self.opTrain.SelectedFeatures.connect(self.SelectedFeatures) self.classifier_cache.Input.connect(self.opTrain.Classifier) # Find the highest label in all the label images self.opMaxLabel = OpMaxLabel(parent=self) self.opMaxLabel.Inputs.connect(self.LabelInputs) self.opPredict.Features.connect(self.ObjectFeatures) self.opPredict.Classifier.connect(self.classifier_cache.Output) self.opPredict.LabelsCount.connect(self.opMaxLabel.Output) self.opPredict.SelectedFeatures.connect(self.SelectedFeatures) self.opLabelsToImage.Image.connect(self.SegmentationImages) self.opLabelsToImage.ObjectMap.connect(self.LabelInputs) self.opLabelsToImage.Features.connect(self.ObjectFeatures) self.opPredictionsToImage.Image.connect(self.SegmentationImages) self.opPredictionsToImage.ObjectMap.connect(self.opPredict.Predictions) self.opPredictionsToImage.Features.connect(self.ObjectFeatures) #self.opPredictionImageCache.name = "prediction_image_cache" self.opPredictionImageCache.fixAtCurrent.connect( self.FreezePredictions) self.opPredictionImageCache.Input.connect( self.opPredictionsToImage.Output) self.opProbabilityChannelsToImage.Image.connect( self.SegmentationImages) self.opProbabilityChannelsToImage.ObjectMaps.connect( self.opPredict.ProbabilityChannels) self.opProbabilityChannelsToImage.Features.connect(self.ObjectFeatures) class OpWrappedCache(Operator): """ This quick hack is necessary because there's not currently a way to wrap an OperatorWrapper. We need to double-wrap the cache, so we need this operator to provide the first level of wrapping. """ Input = InputSlot(level=1) innerBlockShape = InputSlot() outerBlockShape = InputSlot() fixAtCurrent = InputSlot(value=False) Output = OutputSlot(level=1) def __init__(self, *args, **kwargs): super(OpWrappedCache, self).__init__(*args, **kwargs) self._innerOperator = OperatorWrapper( OpSlicedBlockedArrayCache, parent=self) self._innerOperator.Input.connect(self.Input) self._innerOperator.fixAtCurrent.connect(self.fixAtCurrent) self._innerOperator.innerBlockShape.connect( self.innerBlockShape) self._innerOperator.outerBlockShape.connect( self.outerBlockShape) self.Output.connect(self._innerOperator.Output) def execute(self, slot, subindex, roi, destination): assert False, "Shouldn't get here." def propagateDirty(self, slot, subindex, roi): pass # Nothing to do... # Wrap the cache for probability channels twice TWICE. self.opProbChannelsImageCache = OpMultiLaneWrapper(OpWrappedCache, parent=self) self.opProbChannelsImageCache.Input.connect( self.opProbabilityChannelsToImage.Output) self.opProbChannelsImageCache.fixAtCurrent.connect( self.FreezePredictions) self.opBadObjectsToImage.Image.connect(self.SegmentationImages) self.opBadObjectsToImage.ObjectMap.connect(self.opPredict.BadObjects) self.opBadObjectsToImage.Features.connect(self.ObjectFeatures) self.opBadObjectsToWarningMessage.BadObjects.connect( self.opTrain.BadObjects) self.opPredict.InputProbabilities.connect(self.InputProbabilities) self.LabelNames.setValue([]) self.LabelColors.setValue([]) self.PmapColors.setValue([]) # connect outputs self.NumLabels.connect(self.opMaxLabel.Output) self.LabelImages.connect(self.opLabelsToImage.Output) self.Predictions.connect(self.opPredict.Predictions) self.Probabilities.connect(self.opPredict.Probabilities) self.CachedProbabilities.connect(self.opPredict.CachedProbabilities) self.PredictionImages.connect(self.opPredictionImageCache.Output) self.UncachedPredictionImages.connect(self.opPredictionsToImage.Output) self.PredictionProbabilityChannels.connect( self.opProbChannelsImageCache.Output) self.BadObjects.connect(self.opPredict.BadObjects) self.BadObjectImages.connect(self.opBadObjectsToImage.Output) self.Warnings.connect(self.opBadObjectsToWarningMessage.WarningMessage) self.Classifier.connect(self.classifier_cache.Output) self.SegmentationImagesOut.connect(self.SegmentationImages) self.Eraser.setValue(100) self.DeleteLabel.setValue(-1) self._labelBBoxes = [] self._ambiguousLabels = [] self._needLabelTransfer = False def handleNewInputImage(multislot, index, *args): def handleInputReady(slot): self.setupCaches(multislot.index(slot)) multislot[index].notifyReady(handleInputReady) self.SegmentationImages.notifyInserted(handleNewInputImage)
def __init__(self, workflow, *args, **kwargs): self._topLevelOperator = OpMultiLaneWrapper(OpSplitBodyCarving, parent=workflow) super(SplitBodyCarvingApplet, self).__init__(workflow, *args, **kwargs) self._serializers = None