def connectInputs(self, laneIndex): opData = self.dataSelectionApplet.topLevelOperator.getLane(laneIndex) opTwoLevelThreshold = self.thresholdingApplet.topLevelOperator.getLane(laneIndex) op5raw = OpReorderAxes(parent=self) op5raw.AxisOrder.setValue("txyzc") op5predictions = OpReorderAxes(parent=self) op5predictions.AxisOrder.setValue("txyzc") if self.fillMissing != 'none': opFillMissingSlices = self.fillMissingSlicesApplet.topLevelOperator.getLane(laneIndex) opFillMissingSlices.Input.connect(opData.ImageGroup[0]) rawslot = opFillMissingSlices.Output else: rawslot = opData.ImageGroup[0] op5raw.Input.connect(rawslot) op5predictions.Input.connect(opData.ImageGroup[1]) opTwoLevelThreshold.RawInput.connect(op5raw.Output) opTwoLevelThreshold.InputImage.connect(op5predictions.Output) op5Binary = OpReorderAxes(parent=self) op5Binary.AxisOrder.setValue("txyzc") op5Binary.Input.connect(opTwoLevelThreshold.CachedOutput) return op5raw.Output, op5Binary.Output
def connectInputs(self, laneIndex): ## Access applet operators opTrainingFeatures = self.featureSelectionApplet.topLevelOperator.getLane( laneIndex) opClassify = self.pcApplet.topLevelOperator.getLane(laneIndex) opThreshold = self.thresholdingApplet.topLevelOperator.getLane( laneIndex) rawslot = self.createRawDataSourceSlot(laneIndex, canonicalOrder=False) atlas_slot = self.createAtlasSourceSlot(laneIndex) opTrainingFeatures.InputImage.connect(rawslot) opClassify.InputImages.connect(rawslot) opClassify.PredictionMasks.connect(atlas_slot) opClassify.FeatureImages.connect(opTrainingFeatures.OutputImage) opClassify.CachedFeatureImages.connect( opTrainingFeatures.CachedOutputImage) op5raw = OpReorderAxes(parent=self, AxisOrder="txyzc", Input=rawslot) op5pred = OpReorderAxes(parent=self, AxisOrder="txyzc", Input=opClassify.CachedPredictionProbabilities) opThreshold.RawInput.connect(op5raw.Output) opThreshold.InputImage.connect(op5pred.Output) opThreshold.InputChannelColors.connect(opClassify.PmapColors) op5threshold = OpReorderAxes(parent=self, AxisOrder="txyzc", Input=opThreshold.CachedOutput) return op5raw.Output, op5threshold.Output
def connectLane( self, laneIndex ): opData = self.dataSelectionApplet.topLevelOperator.getLane(laneIndex) opTwoLevelThreshold = self.thresholdTwoLevelsApplet.topLevelOperator.getLane(laneIndex) opObjExtraction = self.objectExtractionApplet.topLevelOperator.getLane(laneIndex) opTracking = self.trackingApplet.topLevelOperator.getLane(laneIndex) ## Connect operators ## op5Raw = OpReorderAxes(parent=self) op5Raw.AxisOrder.setValue("txyzc") op5Raw.Input.connect(opData.ImageGroup[0]) opTwoLevelThreshold.InputImage.connect( opData.ImageGroup[1] ) opTwoLevelThreshold.RawInput.connect( opData.ImageGroup[0] ) # Used for display only # Use OpReorderAxes for both input datasets such that they are guaranteed to # have the same axis order after thresholding op5Binary = OpReorderAxes( parent=self ) op5Binary.AxisOrder.setValue("txyzc") op5Binary.Input.connect( opTwoLevelThreshold.CachedOutput ) opObjExtraction.RawImage.connect( op5Raw.Output ) opObjExtraction.BinaryImage.connect( op5Binary.Output ) opTracking.RawImage.connect( op5Raw.Output ) opTracking.LabelImage.connect( opObjExtraction.LabelImage ) opTracking.ObjectFeatures.connect( opObjExtraction.RegionFeatures )
def connectLane(self, laneIndex): ## Access applet operators opData = self.dataSelectionApplet.topLevelOperator.getLane(laneIndex) opPreprocessing = self.preprocessingApplet.topLevelOperator.getLane( laneIndex) opCarvingLane = self.carvingApplet.topLevelOperator.getLane(laneIndex) opCarvingLane.connectToPreprocessingApplet(self.preprocessingApplet) op5Raw = OpReorderAxes(parent=self) op5Raw.AxisOrder.setValue("txyzc") op5Raw.Input.connect(opData.ImageGroup[DATA_ROLE_RAW_DATA]) op5Overlay = OpReorderAxes(parent=self) op5Overlay.AxisOrder.setValue("txyzc") op5Overlay.Input.connect(opData.ImageGroup[DATA_ROLE_OVERLAY]) ## Connect operators opPreprocessing.InputData.connect(op5Raw.Output) opPreprocessing.OverlayData.connect(op5Overlay.Output) opCarvingLane.InputData.connect(op5Raw.Output) opCarvingLane.OverlayData.connect(op5Overlay.Output) opCarvingLane.FilteredInputData.connect(opPreprocessing.FilteredImage) opCarvingLane.MST.connect(opPreprocessing.PreprocessedData) opCarvingLane.UncertaintyType.setValue("none") # Special input-input connection: WriteSeeds metadata must mirror the input data opCarvingLane.WriteSeeds.connect(opCarvingLane.InputData) self.preprocessingApplet.enableDownstream(False)
def setUpSources(self): """ Create big cubes with starting corners at multiples of 20, and small cubes offset 10 from that. Half of the image will be white, the other half gray. """ self.testingFeatures = { "Standard Object Features": { "Count": {}, "Mean": {}, "Mean in neighborhood": { "margin": (10, 10, 1) } } } # Big: Starting at 0,20,40, etc. # Small: Starting at 10,30,50, etc. self.bigCubes = cubes((100, 100, 100), 5, cubedist=20) self.smallCubes = cubes((100, 100, 100), 2, cubedist=20, cubeoffset=10) self.test_volume_binary = (self.bigCubes | self.smallCubes).astype( numpy.uint8) self.test_volume_binary = self.test_volume_binary.view( vigra.VigraArray) self.test_volume_binary.axistags = vigra.defaultAxistags('xyz') name = writeToTempFile(self.test_volume_binary, prefix='binary_') if name: logger.debug("Wrote binary image to '{}'".format(name)) # Gray: 0<=x<50 # White: 50<=x<100 self.test_volume_intensity = self.test_volume_binary * 255 self.test_volume_intensity[0:50] //= 2 self.test_volume_intensity = self.test_volume_intensity.view( vigra.VigraArray) self.test_volume_intensity.axistags = vigra.defaultAxistags('xyz') name = writeToTempFile(self.test_volume_intensity, prefix='intensity_') if name: logger.debug("Wrote intensity image to '{}'".format(name)) graph = Graph() self.graph = graph # provide 5d input op5Raw = OpReorderAxes(graph=graph) op5Raw.Input.setValue(self.test_volume_intensity) op5Raw.AxisOrder.setValue('txyzc') self.rawSource = op5Raw op5Binary = OpReorderAxes(graph=graph) op5Binary.Input.setValue(self.test_volume_binary) op5Binary.AxisOrder.setValue('txyzc') self.binarySource = op5Binary
def prepareVolnOp(self, possible_axes="tzyxc", num=5, AxisOrder=None, config_via_init=False): tagStr = "".join(random.sample(possible_axes, random.randint(2, num))) axisTags = vigra.defaultAxistags(tagStr) self.shape = [random.randint(20, 30) for tag in axisTags] self.array = numpy.random.rand(*self.shape) * 255 self.array = (float(250) / 255 * self.array + 5).astype(int) self.inArray = vigra.VigraArray(self.array, axistags=axisTags) opProvider = OpArrayProvider(graph=self.graph) opProvider.Input.setValue(self.inArray) if config_via_init: self.operator = OpReorderAxes(graph=self.graph, Input=opProvider.Output, AxisOrder=AxisOrder) else: self.operator.Input.connect(opProvider.Output) if AxisOrder is not None: self.operator.AxisOrder.setValue(AxisOrder)
def compare_results(self, opReaderResult, compare_path, input_axes, post_process=None, max_mse=None, max_part_uneqaul=None): if os.path.exists(compare_path): result = opReaderResult.Output[:].wait() opReaderCompare = OpInputDataReader(graph=Graph()) opReaderCompare.FilePath.setValue(compare_path) opReorderCompare = OpReorderAxes(parent=opReaderCompare) opReorderCompare.Input.connect(opReaderCompare.Output) opReorderCompare.AxisOrder.setValue(input_axes) compare = opReorderCompare.Output[:].wait() assert result.shape == compare.shape, (result.shape, compare.shape) if post_process: result = post_process(result) compare = post_process(compare) # for easy debugging: # ----------------------------------------------------------------- # import matplotlib.pyplot as plt # res = result.squeeze() # comp = compare.squeeze() # if len(res.shape) > 2: # res = res.reshape(-1, max(res.shape)) # comp = comp.reshape(-1, max(comp.shape)) # plt.figure() # plt.imshow(res) # plt.title(f'res {result.shape}') # plt.colorbar() # plt.figure() # plt.imshow(comp) # plt.title('comp') # plt.colorbar() # plt.figure() # plt.imshow(res - comp) # plt.title('diff') # plt.colorbar() # plt.show() # ----------------------------------------------------------------- if max_mse: assert max_mse > numpy.mean(numpy.square(result - compare)), \ numpy.mean(numpy.square(result - compare)) elif max_part_uneqaul: assert max_part_uneqaul > numpy.mean(~numpy.isclose(result, compare)), \ numpy.mean(~numpy.isclose(result, compare)) else: assert numpy.allclose(result, compare), f'{result.shape}, {compare.shape}' else: writer = OpFormattedDataExport(graph=Graph()) writer.Input.connect(opReaderResult.Output) writer.OutputFilenameFormat.setValue(compare_path) writer.TransactionSlot.setValue(True) writer.run_export() warnings.warn(f'created comparison data: {compare_path} with axis order {input_axes}')
def test_basic(self): opData = OpArrayCache(graph=self.graph) opData.blockShape.setValue(self.testData.shape) opData.Input.setValue(self.testData) filepath = os.path.join(self._tmpdir, 'multipage.tiff') logger.debug("writing to: {}".format(filepath)) opExport = OpExportMultipageTiff(graph=self.graph) opExport.Filepath.setValue(filepath) opExport.Input.connect(opData.Output) # Run the export opExport.run_export() opReader = OpInputDataReader(graph=self.graph) opReader.FilePath.setValue(filepath) # The reader assumes xyzc order. # We have to transpose the data before we compare. opReorderAxes = OpReorderAxes(graph=self.graph) opReorderAxes.AxisOrder.setValue(self._axisorder) opReorderAxes.Input.connect(opReader.Output) readData = opReorderAxes.Output[:].wait() logger.debug("Expected shape={}".format(self.testData.shape)) logger.debug("Read shape={}".format(readData.shape)) assert opReorderAxes.Output.meta.shape == self.testData.shape, "Exported files were of the wrong shape or number." assert (opReorderAxes.Output[:].wait() == self.testData.view( numpy.ndarray)).all(), "Exported data was not correct" # Cleanup opReorderAxes.cleanUp() opReader.cleanUp()
def test_Writer(self): opData = OpBlockedArrayCache(graph=self.graph) opData.BlockShape.setValue(self.testData.shape) opData.Input.setValue(self.testData) opWriter = OpStackWriter(graph=self.graph) opWriter.FilepathPattern.setValue(self._stack_filepattern) opWriter.Input.connect(opData.Output) # opWriter.Input.setValue( self.testData ) opWriter.SliceIndexOffset.setValue(22) # Run the export opWriter.run_export() globstring = self._stack_filepattern.format(slice_index=999) globstring = globstring.replace("999", "*") opReader = OpStackLoader(graph=self.graph) opReader.globstring.setValue(globstring) # (The OpStackLoader might produce different order.) opReorderAxes = OpReorderAxes(graph=self.graph) opReorderAxes.AxisOrder.setValue(self._axisorder) opReorderAxes.Input.connect(opReader.stack) readData = opReorderAxes.Output[:].wait() logger.debug("Expected shape={}".format(self.testData.shape)) logger.debug("Read shape={}".format(readData.shape)) assert (opReorderAxes.Output.meta.shape == self.testData.shape ), "Exported files were of the wrong shape or number." assert (opReorderAxes.Output[:].wait() == self.testData.view( numpy.ndarray)).all(), "Exported data was not correct"
def handleImportLabelsAction(): # Find the directory of the most recently opened image file mostRecentImageFile = PreferencesManager().get( 'DataSelection', 'recent image') if mostRecentImageFile is not None: defaultDirectory = os.path.split(mostRecentImageFile)[0] else: defaultDirectory = os.path.expanduser('~') fileNames = DataSelectionGui.getImageFileNamesToOpen( self, defaultDirectory) fileNames = map(str, fileNames) # For now, we require a single hdf5 file if len(fileNames) > 1: QMessageBox.critical( self, "Too many files", "Labels must be contained in a single hdf5 volume.") return if len(fileNames) == 0: # user cancelled return file_path = fileNames[0] internal_paths = DataSelectionGui.getPossibleInternalPaths( file_path) if len(internal_paths) == 0: QMessageBox.critical( self, "No volumes in file", "Couldn't find a suitable dataset in your hdf5 file.") return if len(internal_paths) == 1: internal_path = internal_paths[0] else: dlg = H5VolumeSelectionDlg(internal_paths, self) if dlg.exec_() == QDialog.Rejected: return selected_index = dlg.combo.currentIndex() internal_path = str(internal_paths[selected_index]) path_components = PathComponents(file_path) path_components.internalPath = str(internal_path) try: top_op = self.topLevelOperatorView opReader = OpInputDataReader(parent=top_op.parent) opReader.FilePath.setValue(path_components.totalPath()) # Reorder the axes op5 = OpReorderAxes(parent=top_op.parent) op5.AxisOrder.setValue( top_op.LabelInputs.meta.getAxisKeys()) op5.Input.connect(opReader.Output) # Finally, import the labels top_op.importLabels(top_op.current_view_index(), op5.Output) finally: op5.cleanUp() opReader.cleanUp()
def test_Writer(self): opData = OpArrayCache(graph=self.graph) opData.blockShape.setValue(self.testData.shape) opData.Input.setValue(self.testData) opExport = OpExportMultipageTiffSequence(graph=self.graph) opExport.FilepathPattern.setValue(self._stack_filepattern) opExport.Input.connect(opData.Output) opExport.SliceIndexOffset.setValue(22) # Run the export opExport.run_export() globstring = self._stack_filepattern.format(slice_index=999) globstring = globstring.replace('999', '*') opReader = OpTiffSequenceReader(graph=self.graph) opReader.GlobString.setValue(globstring) # (The OpStackLoader produces txyzc order.) opReorderAxes = OpReorderAxes(graph=self.graph) opReorderAxes.AxisOrder.setValue(self._axisorder) opReorderAxes.Input.connect(opReader.Output) readData = opReorderAxes.Output[:].wait() logger.debug("Expected shape={}".format(self.testData.shape)) logger.debug("Read shape={}".format(readData.shape)) assert opReorderAxes.Output.meta.shape == self.testData.shape, "Exported files were of the wrong shape or number." assert (opReorderAxes.Output[:].wait() == self.testData.view( numpy.ndarray)).all(), "Exported data was not correct" opReorderAxes.cleanUp() opReader.cleanUp()
def __init__(self, tiktorch_net, filename=None, HALO_SIZE=32, BATCH_SIZE=3): """ Args: tiktorch_net (tiktorch): tiktorch object to be loaded into this classifier object filename (None, optional): Save file name for future reference """ self._filename = filename if self._filename is None: self._filename = "" self.HALO_SIZE = HALO_SIZE self.BATCH_SIZE = BATCH_SIZE if tiktorch_net is None: print(self._filename) tiktorch_net = TikTorch.unserialize(self._filename) # print (self._filename) # assert tiktorch_net.return_hypercolumns == False # print('blah') self._tiktorch_net = tiktorch_net self._opReorderAxes = OpReorderAxes(graph=Graph()) self._opReorderAxes.AxisOrder.setValue("zcyx")
def __init__(self): # Set memory and number of threads here #lazyflow.request.Request.reset_thread_pool(2) #Memory.setAvailableRam(500*1024**2) binary_img = binaryImage() raw_img = rawImage() g = Graph() # Reorder axis operators self.op5Raw = OpReorderAxes(graph=g) self.op5Raw.AxisOrder.setValue("txyzc") #self.op5Raw.Input.connect(self.opReaderRaw.OutputImage)#self.opReaderRaw.OutputImage) self.op5Raw.Input.setValue(raw_img) self.op5Binary = OpReorderAxes(graph=g) self.op5Binary.AxisOrder.setValue("txyzc") #self.op5Binary.Input.connect(self.opReaderBinary.OutputImage) self.op5Binary.Input.setValue(binary_img) # Cache operators self.opCacheRaw = OpBlockedArrayCache(graph=g) self.opCacheRaw.Input.connect(self.op5Raw.Output) self.opCacheRaw.BlockShape.setValue((1, ) + self.op5Raw.Output.meta.shape[1:]) self.opCacheBinary = OpBlockedArrayCache(graph=g) self.opCacheBinary.Input.connect(self.op5Binary.Output) self.opCacheBinary.BlockShape.setValue( (1, ) + self.op5Binary.Output.meta.shape[1:]) # Label volume operator self.opLabel = OpLabelVolume(graph=g) self.opLabel.Input.connect(self.op5Binary.Output) #self.opLabel.Input.connect(self.opCacheBinary.Output) # Object extraction self.opObjectExtraction = OpObjectExtraction(graph=g) self.opObjectExtraction.RawImage.connect(self.op5Raw.Output) self.opObjectExtraction.BinaryImage.connect(self.op5Binary.Output) self.opObjectExtraction.Features.setValue(FEATURES) # Simplified object features operator (No overhead) self.opObjectFeaturesSimp = OpObjectFeaturesSimplified(graph=g) self.opObjectFeaturesSimp.RawVol.connect(self.opCacheRaw.Output) self.opObjectFeaturesSimp.BinaryVol.connect(self.opCacheBinary.Output)
def testLotsOfOptions(self): # NOTE: In this test, cmd-line args to nosetests will also end up getting "parsed" by ilastik. # That shouldn't be an issue, since the pixel classification workflow ignores unrecognized options. # See if __name__ == __main__ section, below. args = [] args.append("--project=" + self.PROJECT_FILE) args.append("--headless") #args.append( "--sys_tmp_dir=/tmp" ) # Batch export options args.append( '--output_format=png sequence' ) # If we were actually launching from the command line, 'png sequence' would be in quotes... args.append( "--output_filename_format={dataset_dir}/{nickname}_prediction_z{slice_index}.png" ) args.append("--export_dtype=uint8") args.append("--output_axis_order=zxyc") args.append("--pipeline_result_drange=(0.0,1.0)") args.append("--export_drange=(0,255)") args.append("--cutout_subregion=[(0,50,50,0,0), (1, 150, 150, 50, 2)]") args.append(self.SAMPLE_DATA) sys.argv = [ 'ilastik.py' ] # Clear the existing commandline args so it looks like we're starting fresh. sys.argv += args # Start up the ilastik.py entry script as if we had launched it from the command line # This will execute the batch mode script self.ilastik_startup.main() output_path = self.SAMPLE_DATA[:-4] + "_prediction_z{slice_index}.png" globstring = output_path.format(slice_index=999) globstring = globstring.replace('999', '*') opReader = OpStackLoader(graph=Graph()) opReader.globstring.setValue(globstring) # (The OpStackLoader produces txyzc order.) opReorderAxes = OpReorderAxes(graph=Graph()) opReorderAxes.AxisOrder.setValue('txyzc') opReorderAxes.Input.connect(opReader.stack) readData = opReorderAxes.Output[:].wait() # Check basic attributes assert readData.shape[:-1] == self.data[ 0:1, 50:150, 50:150, 0:50, 0:2].shape[:-1] # Assume channel is last axis assert readData.shape[ -1] == 2, "Wrong number of channels. Expected 2, got {}".format( readData.shape[-1]) # Clean-up. opReorderAxes.cleanUp() opReader.cleanUp()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._opReorderAxes = OpReorderAxes(parent=self) self._opReorderAxes.Input.connect(self.Input) self._opReorderAxes.AxisOrder.setValue(self._EXPORT_AXES)
def connectInputs(self, laneIndex): opData = self.dataSelectionApplet.topLevelOperator.getLane(laneIndex) opTwoLevelThreshold = self.thresholdingApplet.topLevelOperator.getLane(laneIndex) op5predictions = OpReorderAxes(parent=self) op5predictions.AxisOrder.setValue("txyzc") rawslot = self.createRawDataSourceSlot(laneIndex) op5predictions.Input.connect(opData.ImageGroup[self.InputImageRoles.PREDICTION_MAPS]) opTwoLevelThreshold.RawInput.connect(rawslot) opTwoLevelThreshold.InputImage.connect(op5predictions.Output) op5Binary = OpReorderAxes(parent=self) op5Binary.AxisOrder.setValue("txyzc") op5Binary.Input.connect(opTwoLevelThreshold.CachedOutput) return rawslot, op5Binary.Output
def connectInputs(self, laneIndex): op5raw = OpReorderAxes(parent=self) op5raw.AxisOrder.setValue("txyzc") op5pred = OpReorderAxes(parent=self) op5pred.AxisOrder.setValue("txyzc") op5threshold = OpReorderAxes(parent=self) op5threshold.AxisOrder.setValue("txyzc") ## Access applet operators opData = self.dataSelectionApplet.topLevelOperator.getLane(laneIndex) opTrainingFeatures = self.featureSelectionApplet.topLevelOperator.getLane( laneIndex) opClassify = self.pcApplet.topLevelOperator.getLane(laneIndex) opThreshold = self.thresholdingApplet.topLevelOperator.getLane( laneIndex) if self.fillMissing != 'none': opFillMissingSlices = self.fillMissingSlicesApplet.topLevelOperator.getLane( laneIndex) opFillMissingSlices.Input.connect(opData.Image) rawslot = opFillMissingSlices.Output else: rawslot = opData.Image opTrainingFeatures.InputImage.connect(rawslot) opClassify.InputImages.connect(rawslot) opClassify.FeatureImages.connect(opTrainingFeatures.OutputImage) opClassify.CachedFeatureImages.connect( opTrainingFeatures.CachedOutputImage) op5raw.Input.connect(rawslot) op5pred.Input.connect(opClassify.PredictionProbabilities) opThreshold.RawInput.connect(op5raw.Output) opThreshold.InputImage.connect(op5pred.Output) opThreshold.InputChannelColors.connect(opClassify.PmapColors) op5threshold.Input.connect(opThreshold.CachedOutput) return op5raw.Output, op5threshold.Output
def exportFinalSegmentation(self, outputPath, axisorder, progressCallback=None): assert self.FinalSegmentation.ready( ), "Can't export yet: The final segmentation isn't ready!" logger.info("Starting Final Segmentation Export...") opTranspose = OpReorderAxes(parent=self) opTranspose.AxisOrder.setValue(axisorder) opTranspose.Input.connect(self.FinalSegmentation) f = h5py.File(outputPath, 'w') opExporter = OpH5WriterBigDataset(parent=self) opExporter.hdf5File.setValue(f) opExporter.hdf5Path.setValue('split_result') opExporter.Image.connect(opTranspose.Output) if progressCallback is not None: opExporter.progressSignal.subscribe(progressCallback) req = Request(partial(self._runExporter, opExporter)) def cleanOps(): opExporter.cleanUp() opTranspose.cleanUp() def handleFailed(exc, exc_info): cleanOps() f.close() import traceback traceback.print_tb(exc_info[2]) msg = "Final Segmentation export FAILED due to the following error:\n{}".format( exc) logger.error(msg) def handleFinished(result): try: cleanOps() logger.info("FINISHED Final Segmentation Export") finally: f.close() def handleCancelled(): cleanOps() f.close() logger.info("Final Segmentation export was cancelled!") req.notify_failed(handleFailed) req.notify_finished(handleFinished) req.notify_cancelled(handleCancelled) req.submit() return req # Returned in case the user wants to cancel it.
def handleImportLabelsAction(): fileNames = ImageFileDialog( self, preferences_group="DataSelection", preferences_setting="recent image").getSelectedPaths() fileNames = list(map(str, fileNames)) # For now, we require a single hdf5 file if len(fileNames) > 1: QMessageBox.critical( self, "Too many files", "Labels must be contained in a single hdf5 volume.") return if len(fileNames) == 0: # user cancelled return file_path = fileNames[0] internal_paths = DatasetInfo.getPossibleInternalPathsFor(file_path) if len(internal_paths) == 0: QMessageBox.critical( self, "No volumes in file", "Couldn't find a suitable dataset in your hdf5 file.") return if len(internal_paths) == 1: internal_path = internal_paths[0] else: dlg = SubvolumeSelectionDlg(internal_paths, self) if dlg.exec_() == QDialog.Rejected: return selected_index = dlg.combo.currentIndex() internal_path = str(internal_paths[selected_index]) path_components = PathComponents(file_path) path_components.internalPath = str(internal_path) try: top_op = self.topLevelOperatorView opReader = OpInputDataReader(parent=top_op.parent) opReader.FilePath.setValue(path_components.totalPath()) # Reorder the axes op5 = OpReorderAxes(parent=top_op.parent) op5.AxisOrder.setValue(top_op.LabelInputs.meta.getAxisKeys()) op5.Input.connect(opReader.Output) # Finally, import the labels top_op.importLabels(top_op.current_view_index(), op5.Output) finally: op5.cleanUp() opReader.cleanUp()
def getVoluminaShapeForSlot(self, slot): shape = None if slot.ready() and slot.meta.axistags is not None: # Use an OpReorderAxes adapter to transpose the shape for us. op5 = OpReorderAxes(parent=slot.getRealOperator().parent) op5.Input.connect(slot) shape = op5.Output.meta.shape # We just needed the operator to determine the transposed shape. # Disconnect it so it can be garbage collected. op5.Input.disconnect() op5.cleanUp() return shape
def test_SlotMetaInfoDisplayWidget_shows_correct_info(qtbot): shape = {"x": 10, "y": 20, "z": 30, "c": 3} swapped_shape = {"c": 3, "y": 20, "x": 10, "z": 30} dtype = numpy.float32 graph = Graph() def create_array(shape: dict): arr = numpy.random.rand(*shape.values()).astype(dtype) return vigra.taggedView(arr, "".join(shape.keys())) data = create_array(shape) op = OpArrayPiper(graph=graph) op.Input.setValue(data) op_reorder = OpReorderAxes(graph=graph, AxisOrder="".join(swapped_shape.keys()), Input=op.Output) def init_widget(widget, slot): widget.initSlot(slot) qtbot.addWidget(widget) widget.show() return widget w = init_widget(SlotMetaInfoDisplayWidget(None), op.Output) out_widget = init_widget(OutputSlotMetaInfoDisplayWidget(None), op_reorder.Output) qtbot.waitForWindowShown(w) def verify_widget(w, shape): displayed_shape = tuple( int(s) for s in re.findall(r"[0-9]+", w.shapeDisplay.text())) assert displayed_shape == tuple(shape.values()) assert w.axisOrderDisplay.text() == "".join(shape.keys()) assert w.dtypeDisplay.text() == dtype.__name__ verify_widget(w, shape) verify_widget(out_widget, swapped_shape) new_shape = {"y": 1, "c": 40, "z": 10, "x": 30} new_swapped_shape = {"c": 40, "x": 30, "y": 1, "z": 10} new_data = create_array(new_shape) op.Input.setValue(new_data) op_reorder.AxisOrder.setValue("".join(new_swapped_shape.keys())) verify_widget(w, new_shape) verify_widget(out_widget, new_swapped_shape)
def reorder_axes(input_arr: numpy.ndarray, *, from_axes_tags: str, to_axes_tags: str): if isinstance(from_axes_tags, AxisTags): from_axes_tags = "".join(from_axes_tags.keys()) if isinstance(to_axes_tags, AxisTags): to_axes_tags = "".join(to_axes_tags.keys()) op = OpReorderAxes(graph=Graph()) tagged_arr = vigra.VigraArray(input_arr, axistags=vigra.defaultAxistags(from_axes_tags)) op.Input.setValue(tagged_arr) op.AxisOrder.setValue(to_axes_tags) return op.Output([]).wait()
def test_attempt_drop_nonsingleton_axis(self): """ Attempt to configure the operator with invalid settings by trying to drop a non-singleton axis. The execute method should assert in that case. """ data = numpy.zeros( (100,100,100), dtype=numpy.uint8 ) data = vigra.taggedView( data, vigra.defaultAxistags('xyz') ) op = OpReorderAxes( graph=Graph() ) op.Input.setValue( data ) # Attempt to drop some axes that can't be dropped. op.AxisOrder.setValue( 'txc' ) # Make sure this results in an error. self.assertRaises( AssertionError, op.Output[:].wait )
def connectLane(self, laneIndex): ## Access applet operators opData = self.dataSelectionApplet.topLevelOperator.getLane( laneIndex) opFeatureSelection = self.featureSelectionApplet.topLevelOperator.getLane( laneIndex) opPixelClassification = self.pixelClassificationApplet.topLevelOperator.getLane( laneIndex) opPreprocessing = self.preprocessingApplet.topLevelOperator.getLane( laneIndex) opCarvingLane = self.carvingApplet.topLevelOperator.getLane( laneIndex) op5 = OpReorderAxes(parent=self) op5.AxisOrder.setValue("txyzc") op5.Input.connect(opData.Image) ## Connect operators opFeatureSelection.InputImage.connect(op5.Output) opPixelClassification.InputImages.connect(op5.Output) opPixelClassification.FeatureImages.connect( opFeatureSelection.OutputImage) opPixelClassification.CachedFeatureImages.connect( opFeatureSelection.CachedOutputImage) # We assume the membrane boundaries are found in the first prediction class (channel 0) opSingleChannelSelector = OpSingleChannelSelector(parent=self) opSingleChannelSelector.Input.connect( opPixelClassification.PredictionProbabilities) opSingleChannelSelector.Index.setValue(0) opPreprocessing.OverlayData.connect(op5.Output) opPreprocessing.InputData.connect(opSingleChannelSelector.Output) opCarvingLane.OverlayData.connect(op5.Output) opCarvingLane.InputData.connect(opSingleChannelSelector.Output) opCarvingLane.FilteredInputData.connect( opPreprocessing.FilteredImage) # Special input-input connection: WriteSeeds metadata must mirror the input data opCarvingLane.WriteSeeds.connect(opCarvingLane.InputData) opCarvingLane.MST.connect(opPreprocessing.PreprocessedData) opCarvingLane.UncertaintyType.setValue("none") self.preprocessingApplet.enableDownstream(False)
def test_attempt_drop_nonsingleton_axis(self): """ Attempt to configure the operator with invalid settings by trying to drop a non-singleton axis. The execute method should assert in that case. """ data = numpy.zeros((100, 100, 100), dtype=numpy.uint8) data = vigra.taggedView(data, vigra.defaultAxistags("xyz")) # Attempt to drop some axes that can't be dropped. op = OpReorderAxes(graph=Graph(), Input=data, AxisOrder="txc") # Make sure this results in an error. req = op.Output[:] req.notify_failed( lambda *args: None ) # We expect an exception here, so disable the default fail handler to hide the traceback self.assertRaises(AssertionError, req.wait)
def testBasic_MultipageTiffSequence(self): data = 255 * numpy.random.random((5, 10, 50, 100, 3)) data = data.astype(numpy.uint8) data = vigra.taggedView(data, vigra.defaultAxistags('tzyxc')) # Must run this through an operator # Can't use opExport.setValue() because because OpStackWriter can't work with ValueRequests graph = Graph() opData = OpBlockedArrayCache(graph=graph) opData.BlockShape.setValue(data.shape) opData.Input.setValue(data) filepattern = self._tmpdir + '/test_export_x{x_start}-{x_stop}_y{y_start}-{y_stop}_t{slice_index}' opExport = OpExportSlot(graph=graph) opExport.Input.connect(opData.Output) opExport.OutputFormat.setValue('multipage tiff sequence') opExport.OutputFilenameFormat.setValue(filepattern) opExport.CoordinateOffset.setValue((7, 10, 20, 30, 0)) opExport.run_export() export_pattern = opExport.ExportPath.value globstring = export_pattern.format(slice_index=999) globstring = globstring.replace('999', '*') opReader = OpTiffSequenceReader(graph=graph) opReorderAxes = OpReorderAxes(graph=graph) try: opReader.GlobString.setValue(globstring) # (The OpStackLoader produces txyzc order.) opReorderAxes.AxisOrder.setValue('tzyxc') opReorderAxes.Input.connect(opReader.Output) assert opReorderAxes.Output.meta.shape == data.shape, "Exported files were of the wrong shape or number." assert (opReorderAxes.Output[:].wait() == data.view( numpy.ndarray)).all(), "Exported data was not correct" finally: opReorderAxes.cleanUp() opReader.cleanUp()
def test_basic(self): opSource = OpArrayPiper(graph=self.graph) opSource.Input.setValue(self.testData) opData = OpArrayCache(graph=self.graph) opData.blockShape.setValue(self.testData.shape) opData.Input.connect(opSource.Output) filepath = os.path.join(self._tmpdir, 'multipage.tiff') logger.debug("writing to: {}".format(filepath)) opExport = OpExportMultipageTiff(graph=self.graph) opExport.Filepath.setValue(filepath) opExport.Input.connect(opData.Output) # Run the export opExport.run_export() opReader = OpTiffReader(graph=self.graph) try: opReader.Filepath.setValue(filepath) # Re-order before comparing opReorderAxes = OpReorderAxes(graph=self.graph) try: opReorderAxes.AxisOrder.setValue(self._axisorder) opReorderAxes.Input.connect(opReader.Output) readData = opReorderAxes.Output[:].wait() logger.debug("Expected shape={}".format(self.testData.shape)) logger.debug("Read shape={}".format(readData.shape)) assert opReorderAxes.Output.meta.shape == self.testData.shape, \ "Exported files were of the wrong shape or number." assert (opReorderAxes.Output[:].wait() == self.testData.view( numpy.ndarray )).all(), \ "Exported data was not correct" finally: opReorderAxes.cleanUp() finally: opReader.cleanUp()
def __init__(self, *args, **kwargs): super(OpFormattedDataExport, self).__init__(*args, **kwargs) self._dirty = True opSubRegion = OpSubRegion(parent=self) opSubRegion.Input.connect(self.Input) self._opSubRegion = opSubRegion # If normalization parameters are provided, we inject a 'drange' # metadata item for downstream operators/gui to use. opDrangeInjection = OpMetadataInjector(parent=self) opDrangeInjection.Input.connect(opSubRegion.Output) self._opDrangeInjection = opDrangeInjection # Normalization and dtype conversion are performed in one step # using an OpPixelOperator. opNormalizeAndConvert = OpPixelOperator(parent=self) opNormalizeAndConvert.Input.connect(opDrangeInjection.Output) self._opNormalizeAndConvert = opNormalizeAndConvert # ConvertedImage shows the full result but WITHOUT axis reordering. self.ConvertedImage.connect(self._opNormalizeAndConvert.Output) opReorderAxes = OpReorderAxes(parent=self) opReorderAxes.Input.connect(opNormalizeAndConvert.Output) self._opReorderAxes = opReorderAxes self.ImageToExport.connect(opReorderAxes.Output) self._opExportSlot = OpExportSlot(parent=self) self._opExportSlot.Input.connect(opReorderAxes.Output) self._opExportSlot.OutputFormat.connect(self.OutputFormat) self.ExportPath.connect(self._opExportSlot.ExportPath) self.FormatSelectionErrorMsg.connect( self._opExportSlot.FormatSelectionErrorMsg) self.progressSignal = self._opExportSlot.progressSignal
def import_labeling_layer(labelLayer, labelingSlots, parent_widget=None): """ Prompt the user for layer import settings, and perform the layer import. :param labelLayer: The top label layer source :param labelingSlots: An instance of LabelingGui.LabelingSlots :param parent_widget: The Qt GUI parent object """ writeSeeds = labelingSlots.labelInput assert isinstance( writeSeeds, lazyflow.graph.Slot), "slot is of type %r" % (type(writeSeeds)) opLabels = writeSeeds.getRealOperator() assert isinstance(opLabels, lazyflow.graph.Operator ), "slot's operator is of type %r" % (type(opLabels)) recentlyImported = PreferencesManager().get('labeling', 'recently imported') mostRecentProjectPath = PreferencesManager().get('shell', 'recently opened') mostRecentImageFile = PreferencesManager().get('DataSelection', 'recent image') if recentlyImported: defaultDirectory = os.path.split(recentlyImported)[0] elif mostRecentProjectPath: defaultDirectory = os.path.split(mostRecentProjectPath)[0] elif mostRecentImageFile: defaultDirectory = os.path.split(mostRecentImageFile)[0] else: defaultDirectory = os.path.expanduser('~') fileNames = DataSelectionGui.getImageFileNamesToOpen( parent_widget, defaultDirectory) fileNames = map(str, fileNames) if not fileNames: return PreferencesManager().set('labeling', 'recently imported', fileNames[0]) try: # Initialize operators opImport = OpInputDataReader(parent=opLabels.parent) opCache = OpArrayCache(parent=opLabels.parent) opMetadataInjector = OpMetadataInjector(parent=opLabels.parent) opReorderAxes = OpReorderAxes(parent=opLabels.parent) # Set up the pipeline as follows: # # opImport --> opCache --> opMetadataInjector --------> opReorderAxes --(inject via setInSlot)--> labelInput # / / # User-specified axisorder labelInput.meta.axistags opImport.WorkingDirectory.setValue(defaultDirectory) opImport.FilePath.setValue(fileNames[0] if len(fileNames) == 1 else os.path.pathsep.join(fileNames)) assert opImport.Output.ready() opCache.blockShape.setValue(opImport.Output.meta.shape) opCache.Input.connect(opImport.Output) assert opCache.Output.ready() opMetadataInjector.Input.connect(opCache.Output) metadata = opCache.Output.meta.copy() opMetadataInjector.Metadata.setValue(metadata) opReorderAxes.Input.connect(opMetadataInjector.Output) # Transpose the axes for assignment to the labeling operator. opReorderAxes.AxisOrder.setValue(writeSeeds.meta.getAxisKeys()) # We'll show a little window with a busy indicator while the data is loading busy_dlg = QProgressDialog(parent=parent_widget) busy_dlg.setLabelText("Importing Label Data...") busy_dlg.setCancelButton(None) busy_dlg.setMinimum(100) busy_dlg.setMaximum(100) def close_busy_dlg(*args): QApplication.postEvent(busy_dlg, QCloseEvent()) # Load the data from file into our cache # When it's done loading, close the progress dialog. req = opCache.Output[:] req.notify_finished(close_busy_dlg) req.notify_failed(close_busy_dlg) req.submit() busy_dlg.exec_() readData = req.result maxLabels = len(labelingSlots.labelNames.value) # Can't use return_counts feature because that requires numpy >= 1.9 #unique_read_labels, readLabelCounts = numpy.unique(readData, return_counts=True) # This does the same as the above, albeit slower, and probably with more ram. unique_read_labels = numpy.unique(readData) readLabelCounts = numpy.bincount(readData.flat)[unique_read_labels] labelInfo = (maxLabels, (unique_read_labels, readLabelCounts)) del readData # Ask the user how to interpret the data. settingsDlg = LabelImportOptionsDlg(parent_widget, fileNames, opMetadataInjector.Output, labelingSlots.labelInput, labelInfo) def handle_updated_axes(): # The user is specifying a new interpretation of the file's axes updated_axisorder = str(settingsDlg.axesEdit.text()) metadata = opMetadataInjector.Metadata.value.copy() metadata.axistags = vigra.defaultAxistags(updated_axisorder) opMetadataInjector.Metadata.setValue(metadata) settingsDlg.axesEdit.editingFinished.connect(handle_updated_axes) dlg_result = settingsDlg.exec_() if dlg_result != LabelImportOptionsDlg.Accepted: return # Get user's chosen label mapping from dlg labelMapping = settingsDlg.labelMapping # Get user's chosen offsets. # Offsets in dlg only include the file axes, not the 5D axes expected by the label input, # so expand them to full 5D axes_5d = opReorderAxes.Output.meta.getAxisKeys() tagged_offsets = collections.OrderedDict( zip(axes_5d, [0] * len(axes_5d))) tagged_offsets.update( dict( zip(opMetadataInjector.Output.meta.getAxisKeys(), settingsDlg.imageOffsets))) imageOffsets = tagged_offsets.values() # Optimization if mapping is identity if labelMapping.keys() == labelMapping.values(): labelMapping = None # This will be fast (it's already cached) label_data = opReorderAxes.Output[:].wait() # Map input labels to output labels if labelMapping: # There are other ways to do a relabeling (e.g skimage.segmentation.relabel_sequential) # But this supports potentially huge values of unique_read_labels (in the billions), # without needing GB of RAM. mapping_indexes = numpy.searchsorted(unique_read_labels, label_data) new_labels = numpy.array( [labelMapping[x] for x in unique_read_labels]) label_data[:] = new_labels[mapping_indexes] label_roi = numpy.array(roiFromShape(opReorderAxes.Output.meta.shape)) label_roi += imageOffsets label_slice = roiToSlice(*label_roi) writeSeeds[label_slice] = label_data finally: opReorderAxes.cleanUp() opMetadataInjector.cleanUp() opCache.cleanUp() opImport.cleanUp()
def connectLane(self, laneIndex): opData = self.dataSelectionApplet.topLevelOperator.getLane(laneIndex) opObjExtraction = self.objectExtractionApplet.topLevelOperator.getLane(laneIndex) opTrackingFeatureExtraction = self.trackingFeatureExtractionApplet.topLevelOperator.getLane(laneIndex) opAnnotations = self.annotationsApplet.topLevelOperator.getLane(laneIndex) if not self.fromBinary: opTwoLevelThreshold = self.thresholdTwoLevelsApplet.topLevelOperator.getLane(laneIndex) opStructuredTracking = self.trackingApplet.topLevelOperator.getLane(laneIndex) opDataTrackingExport = self.dataExportTrackingApplet.topLevelOperator.getLane(laneIndex) ## Connect operators ## op5Raw = OpReorderAxes(parent=self) op5Raw.AxisOrder.setValue("txyzc") op5Raw.Input.connect(opData.ImageGroup[0]) opDivDetection = self.divisionDetectionApplet.topLevelOperator.getLane(laneIndex) opCellClassification = self.cellClassificationApplet.topLevelOperator.getLane(laneIndex) if not self.fromBinary: opTwoLevelThreshold.InputImage.connect( opData.ImageGroup[1] ) opTwoLevelThreshold.RawInput.connect( opData.ImageGroup[0] ) # Used for display only binarySrc = opTwoLevelThreshold.CachedOutput else: binarySrc = opData.ImageGroup[1] # Use Op5ifyers for both input datasets such that they are guaranteed to # have the same axis order after thresholding op5Binary = OpReorderAxes(parent=self) op5Binary.AxisOrder.setValue("txyzc") op5Binary.Input.connect(binarySrc) opObjExtraction.RawImage.connect( op5Raw.Output ) opObjExtraction.BinaryImage.connect( op5Binary.Output ) opTrackingFeatureExtraction.RawImage.connect( op5Raw.Output ) opTrackingFeatureExtraction.BinaryImage.connect( op5Binary.Output ) opTrackingFeatureExtraction.setDefaultFeatures(configConservation.allFeaturesObjectCount) opTrackingFeatureExtraction.FeatureNamesVigra.setValue(configConservation.allFeaturesObjectCount) feature_dict_division = {} feature_dict_division[config.features_division_name] = { name: {} for name in config.division_features } opTrackingFeatureExtraction.FeatureNamesDivision.setValue(feature_dict_division) if self.divisionDetectionApplet: opDivDetection.BinaryImages.connect( op5Binary.Output ) opDivDetection.RawImages.connect( op5Raw.Output ) opDivDetection.SegmentationImages.connect(opTrackingFeatureExtraction.LabelImage) opDivDetection.ObjectFeatures.connect(opTrackingFeatureExtraction.RegionFeaturesAll) opDivDetection.ComputedFeatureNames.connect(opTrackingFeatureExtraction.ComputedFeatureNamesAll) opCellClassification.BinaryImages.connect( op5Binary.Output ) opCellClassification.RawImages.connect( op5Raw.Output ) opCellClassification.SegmentationImages.connect(opTrackingFeatureExtraction.LabelImage) opCellClassification.ObjectFeatures.connect(opTrackingFeatureExtraction.RegionFeaturesAll) opCellClassification.ComputedFeatureNames.connect(opTrackingFeatureExtraction.ComputedFeatureNamesNoDivisions) opAnnotations.RawImage.connect( op5Raw.Output ) opAnnotations.BinaryImage.connect( op5Binary.Output ) opAnnotations.LabelImage.connect( opObjExtraction.LabelImage ) opAnnotations.ObjectFeatures.connect( opObjExtraction.RegionFeatures ) opAnnotations.ComputedFeatureNames.connect(opObjExtraction.Features) opAnnotations.DivisionProbabilities.connect( opDivDetection.Probabilities ) opAnnotations.DetectionProbabilities.connect( opCellClassification.Probabilities ) opAnnotations.MaxNumObj.connect (opCellClassification.MaxNumObj) opStructuredTracking.RawImage.connect( op5Raw.Output ) opStructuredTracking.LabelImage.connect( opTrackingFeatureExtraction.LabelImage ) opStructuredTracking.ObjectFeatures.connect( opTrackingFeatureExtraction.RegionFeaturesVigra ) opStructuredTracking.ComputedFeatureNames.connect( opTrackingFeatureExtraction.FeatureNamesVigra ) if self.divisionDetectionApplet: opStructuredTracking.ObjectFeaturesWithDivFeatures.connect( opTrackingFeatureExtraction.RegionFeaturesAll) opStructuredTracking.ComputedFeatureNamesWithDivFeatures.connect( opTrackingFeatureExtraction.ComputedFeatureNamesAll ) opStructuredTracking.DivisionProbabilities.connect( opDivDetection.Probabilities ) opStructuredTracking.DetectionProbabilities.connect( opCellClassification.Probabilities ) opStructuredTracking.NumLabels.connect( opCellClassification.NumLabels ) opStructuredTracking.Annotations.connect (opAnnotations.Annotations) opStructuredTracking.Labels.connect (opAnnotations.Labels) opStructuredTracking.Divisions.connect (opAnnotations.Divisions) opStructuredTracking.Appearances.connect (opAnnotations.Appearances) opStructuredTracking.Disappearances.connect (opAnnotations.Disappearances) opStructuredTracking.MaxNumObj.connect (opCellClassification.MaxNumObj) opDataTrackingExport.Inputs.resize(3) opDataTrackingExport.Inputs[0].connect( opStructuredTracking.RelabeledImage ) opDataTrackingExport.Inputs[1].connect( opStructuredTracking.MergerOutput ) opDataTrackingExport.Inputs[2].connect( opStructuredTracking.LabelImage ) opDataTrackingExport.RawData.connect( op5Raw.Output ) opDataTrackingExport.RawDatasetInfo.connect( opData.DatasetGroup[0] )