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 )        
Beispiel #4
0
    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
Beispiel #6
0
    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)
Beispiel #7
0
    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}')
Beispiel #8
0
    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()
Beispiel #9
0
    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()
Beispiel #11
0
    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
Beispiel #17
0
    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
Beispiel #18
0
    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.
Beispiel #19
0
        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()
Beispiel #20
0
    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
Beispiel #21
0
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)
Beispiel #22
0
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()
Beispiel #23
0
    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)
Beispiel #25
0
    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)
Beispiel #26
0
    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
Beispiel #29
0
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()
Beispiel #30
0
    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] )