def __init__(self, block_roi, halo_padding, *args, **kwargs): super(self.__class__, self).__init__(*args, **kwargs) self.block_roi = block_roi # In global coordinates self._halo_padding = halo_padding self._opBinarySubRegion = OpSubRegion(parent=self) self._opBinarySubRegion.Input.connect(self.BinaryImage) self._opRawSubRegion = OpSubRegion(parent=self) self._opRawSubRegion.Input.connect(self.RawImage) self._opExtract = OpObjectExtraction(parent=self) self._opExtract.BinaryImage.connect(self._opBinarySubRegion.Output) self._opExtract.RawImage.connect(self._opRawSubRegion.Output) self._opExtract.Features.connect(self.SelectedFeatures) self.BlockwiseRegionFeatures.connect( self._opExtract.BlockwiseRegionFeatures) self._opPredict = OpObjectPredict(parent=self) self._opPredict.Features.connect(self._opExtract.RegionFeatures) self._opPredict.SelectedFeatures.connect(self.SelectedFeatures) self._opPredict.Classifier.connect(self.Classifier) self._opPredict.LabelsCount.connect(self.LabelsCount) self._opPredictionImage = OpRelabelSegmentation(parent=self) self._opPredictionImage.Image.connect(self._opExtract.LabelImage) self._opPredictionImage.Features.connect( self._opExtract.RegionFeatures) self._opPredictionImage.ObjectMap.connect(self._opPredict.Predictions)
def __init__(self, block_roi, halo_padding, *args, **kwargs): super(self.__class__, self).__init__(*args, **kwargs) self.block_roi = block_roi # In global coordinates self._halo_padding = halo_padding self._opBinarySubRegion = OpSubRegion(parent=self) self._opBinarySubRegion.Input.connect(self.BinaryImage) self._opRawSubRegion = OpSubRegion(parent=self) self._opRawSubRegion.Input.connect(self.RawImage) self._opExtract = OpObjectExtraction(parent=self) self._opExtract.BinaryImage.connect(self._opBinarySubRegion.Output) self._opExtract.RawImage.connect(self._opRawSubRegion.Output) self._opExtract.Features.connect(self.SelectedFeatures) self.BlockwiseRegionFeatures.connect( self._opExtract.BlockwiseRegionFeatures) self._opExtract._opRegFeats._opCache.name = "blockwise-regionfeats-cache" self._opPredict = OpObjectPredict(parent=self) self._opPredict.Features.connect(self._opExtract.RegionFeatures) self._opPredict.SelectedFeatures.connect(self.SelectedFeatures) self._opPredict.Classifier.connect(self.Classifier) self._opPredict.LabelsCount.connect(self.LabelsCount) self.ObjectwisePredictions.connect(self._opPredict.Predictions) self._opPredictionImage = OpRelabelSegmentation(parent=self) self._opPredictionImage.Image.connect(self._opExtract.LabelImage) self._opPredictionImage.Features.connect( self._opExtract.RegionFeatures) self._opPredictionImage.ObjectMap.connect(self._opPredict.Predictions) self._opPredictionCache = OpArrayCache(parent=self) self._opPredictionCache.Input.connect(self._opPredictionImage.Output) self._opProbabilityChannelsToImage = OpMultiRelabelSegmentation( parent=self) self._opProbabilityChannelsToImage.Image.connect( self._opExtract.LabelImage) self._opProbabilityChannelsToImage.ObjectMaps.connect( self._opPredict.ProbabilityChannels) self._opProbabilityChannelsToImage.Features.connect( self._opExtract.RegionFeatures) self._opProbabilityChannelStacker = OpMultiArrayStacker(parent=self) self._opProbabilityChannelStacker.Images.connect( self._opProbabilityChannelsToImage.Output) self._opProbabilityChannelStacker.AxisFlag.setValue('c') self._opProbabilityCache = OpArrayCache(parent=self) self._opProbabilityCache.Input.connect( self._opProbabilityChannelStacker.Output)
def testOutput(self): graph = Graph() data = numpy.random.random((1, 100, 100, 10, 1)) opProvider = OpArrayPiper(graph=graph) opProvider.Input.setValue(data) opSubRegion = OpSubRegion(graph=graph) opSubRegion.Input.connect(opProvider.Output) opSubRegion.Start.setValue((0, 20, 30, 5, 0)) opSubRegion.Stop.setValue((1, 30, 50, 8, 1)) subData = opSubRegion.Output(start=(0, 5, 10, 1, 0), stop=(1, 10, 20, 3, 1)).wait() assert (subData == data[0:1, 25:30, 40:50, 6:8, 0:1]).all()
def testDirtyPropagation(self): graph = Graph() data = numpy.random.random((1, 100, 100, 10, 1)) opProvider = OpArrayPiper(graph=graph) opProvider.Input.setValue(data) opSubRegion = OpSubRegion(graph=graph) opSubRegion.Input.connect(opProvider.Output) opSubRegion.Start.setValue((0, 20, 30, 5, 0)) opSubRegion.Stop.setValue((1, 30, 50, 8, 1)) gotDirtyRois = [] def handleDirty(slot, roi): gotDirtyRois.append(roi) opSubRegion.Output.notifyDirty(handleDirty) # Set an input dirty region that overlaps with the subregion key = make_key[0:1, 15:35, 32:33, 0:10, 0:1] opProvider.Input.setDirty(key) assert len(gotDirtyRois) == 1 assert gotDirtyRois[0].start == [0, 0, 2, 0, 0] assert gotDirtyRois[0].stop == [1, 10, 3, 3, 1] # Now mark a region that DOESN'T overlap with the subregion key = make_key[0:1, 70:80, 32:33, 0:10, 0:1] opProvider.Input.setDirty(key) # Should have gotten no extra dirty notifications assert len(gotDirtyRois) == 1
def getFeatureLayers(self, inputSlot, featureSlot): """ Generate a list of layers for the feature image produced by the given slot. """ layers = [] channelAxis = inputSlot.meta.axistags.channelIndex assert channelAxis == featureSlot.meta.axistags.channelIndex numInputChannels = inputSlot.meta.shape[channelAxis] numFeatureChannels = featureSlot.meta.shape[channelAxis] # Determine how many channels this feature has (up to 3) featureChannelsPerInputChannel = numFeatureChannels / numInputChannels assert 0 < featureChannelsPerInputChannel <= 3, "The feature selection Gui does not yet support features with more than three channels per input channel." for inputChannel in range(numInputChannels): # Determine the name for this feature featureName = featureSlot.meta.description assert featureName is not None if 2 <= numInputChannels <= 3: channelNames = ['R', 'G', 'B'] featureName += " (" + channelNames[inputChannel] + ")" if numInputChannels > 3: featureName += " (Ch. {})".format(inputChannel) opSubRegion = OpSubRegion(graph=self.mainOperator.graph) opSubRegion.Input.connect(featureSlot) start = [0] * len(featureSlot.meta.shape) start[channelAxis] = inputChannel * featureChannelsPerInputChannel stop = list(featureSlot.meta.shape) stop[channelAxis] = (inputChannel + 1) * featureChannelsPerInputChannel opSubRegion.Start.setValue(tuple(start)) opSubRegion.Stop.setValue(tuple(stop)) featureLayer = self.createStandardLayerFromSlot(opSubRegion.Output) featureLayer.visible = False featureLayer.opacity = 1.0 featureLayer.name = featureName layers.append(featureLayer) return layers
def setupOutputs(self): """ Inspect the file name and instantiate and connect an internal operator of the appropriate type. TODO: Handle datasets of non-standard (non-5d) dimensions. """ filePath = self.FilePath.value assert isinstance( filePath, (str, unicode )), "Error: filePath is not of type str. It's of type {}".format( type(filePath)) # Does this look like a relative path? useRelativePath = not isUrl(filePath) and not os.path.isabs(filePath) if useRelativePath: # If using a relative path, we need both inputs before proceeding if not self.WorkingDirectory.ready(): return else: # Convert this relative path into an absolute path filePath = os.path.normpath( os.path.join(self.WorkingDirectory.value, filePath)).replace('\\', '/') # Clean up before reconfiguring if self.internalOperators: self.Output.disconnect() self.opInjector.cleanUp() for op in self.internalOperators[::-1]: op.cleanUp() self.internalOperators = [] self.internalOutput = None if self._file is not None: self._file.close() openFuncs = [ self._attemptOpenAsKlb, self._attemptOpenAsUfmf, self._attemptOpenAsMmf, self._attemptOpenAsDvidVolume, self._attemptOpenAsTiffStack, self._attemptOpenAsStack, self._attemptOpenAsHdf5, self._attemptOpenAsNpy, self._attemptOpenAsRawBinary, self._attemptOpenAsBlockwiseFileset, self._attemptOpenAsRESTfulBlockwiseFileset, self._attemptOpenAsTiledVolume, self._attemptOpenAsTiff, self._attemptOpenWithVigraImpex ] # Try every method of opening the file until one works. iterFunc = openFuncs.__iter__() while not self.internalOperators: try: openFunc = iterFunc.next() except StopIteration: break self.internalOperators, self.internalOutput = openFunc(filePath) if self.internalOutput is None: raise RuntimeError("Can't read " + filePath + " because it has an unrecognized format.") # If we've got a ROI, append a subregion operator. if self.SubVolumeRoi.ready(): self._opSubRegion = OpSubRegion(parent=self) self._opSubRegion.Roi.setValue(self.SubVolumeRoi.value) self._opSubRegion.Input.connect(self.internalOutput) self.internalOutput = self._opSubRegion.Output self.opInjector = OpMetadataInjector(parent=self) self.opInjector.Input.connect(self.internalOutput) # Add metadata for estimated RAM usage if the internal operator didn't already provide it. if self.internalOutput.meta.ram_per_pixelram_usage_per_requested_pixel is None: ram_per_pixel = self.internalOutput.meta.dtype().nbytes if 'c' in self.internalOutput.meta.getTaggedShape(): ram_per_pixel *= self.internalOutput.meta.getTaggedShape()['c'] self.opInjector.Metadata.setValue( {'ram_per_pixelram_usage_per_requested_pixel': ram_per_pixel}) else: # Nothing to add self.opInjector.Metadata.setValue({}) # Directly connect our own output to the internal output self.Output.connect(self.opInjector.Output)
def setupOutputs(self): """ Inspect the file name and instantiate and connect an internal operator of the appropriate type. TODO: Handle datasets of non-standard (non-5d) dimensions. """ path_components = splitPath(self.FilePath.value) cwd = self.WorkingDirectory.value if self.WorkingDirectory.ready() else None abs_paths = [] for path in path_components: if isRelative(path): if cwd is None: return # FIXME: this mirrors old logic but I'm not sure if it's safe abs_paths.append(os.path.normpath(os.path.join(cwd, path)).replace("\\", "/")) else: abs_paths.append(path) filePath = os.path.pathsep.join(abs_paths) # Clean up before reconfiguring if self.internalOperators: self.Output.disconnect() self.opInjector.cleanUp() for op in self.internalOperators[::-1]: op.cleanUp() self.internalOperators = [] self.internalOutput = None if self._file is not None: self._file.close() openFuncs = [ self._attemptOpenAsKlb, self._attemptOpenAsUfmf, self._attemptOpenAsMmf, self._attemptOpenAsRESTfulPrecomputedChunkedVolume, self._attemptOpenAsDvidVolume, self._attemptOpenAsH5N5Stack, self._attemptOpenAsTiffStack, self._attemptOpenAsStack, self._attemptOpenAsH5N5, self._attemptOpenAsNpy, self._attemptOpenAsRawBinary, self._attemptOpenAsTiledVolume, self._attemptOpenAsH5BlockStore, self._attemptOpenAsBlockwiseFileset, self._attemptOpenAsRESTfulBlockwiseFileset, self._attemptOpenAsBigTiff, self._attemptOpenAsTiff, self._attemptOpenWithVigraImpex, ] # Try every method of opening the file until one works. iterFunc = openFuncs.__iter__() while not self.internalOperators: try: openFunc = next(iterFunc) except StopIteration: break self.internalOperators, self.internalOutput = openFunc(filePath) if self.internalOutput is None: raise RuntimeError("Can't read " + filePath + " because it has an unrecognized format.") # If we've got a ROI, append a subregion operator. if self.SubVolumeRoi.ready(): self._opSubRegion = OpSubRegion(parent=self) self._opSubRegion.Roi.setValue(self.SubVolumeRoi.value) self._opSubRegion.Input.connect(self.internalOutput) self.internalOutput = self._opSubRegion.Output self.opInjector = OpMetadataInjector(parent=self) self.opInjector.Input.connect(self.internalOutput) # Add metadata for estimated RAM usage if the internal operator didn't already provide it. if self.internalOutput.meta.ram_usage_per_requested_pixel is None: ram_per_pixel = self.internalOutput.meta.dtype().nbytes if "c" in self.internalOutput.meta.getTaggedShape(): ram_per_pixel *= self.internalOutput.meta.getTaggedShape()["c"] self.opInjector.Metadata.setValue({"ram_usage_per_requested_pixel": ram_per_pixel}) else: # Nothing to add self.opInjector.Metadata.setValue({}) # Directly connect our own output to the internal output self.Output.connect(self.opInjector.Output)