Beispiel #1
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")
Beispiel #3
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 #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 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 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 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 testLotsOfOptions(self):
        #OLD_LAZYFLOW_STATUS_MONITOR_SECONDS = os.getenv("LAZYFLOW_STATUS_MONITOR_SECONDS", None)
        #os.environ["LAZYFLOW_STATUS_MONITOR_SECONDS"] = "1"
        
        # 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( '--export_source=Simple Segmentation' )
        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}_segmentation_z{slice_index}.png" )
        args.append( "--export_dtype=uint8" )
        args.append( "--output_axis_order=zxyc" )
         
        args.append( "--pipeline_result_drange=(0,2)" )
        args.append( "--export_drange=(0,255)" )
 
        args.append( "--cutout_subregion=[(0,50,50,0,0), (1, 150, 150, 50, 1)]" )
        args.append( self.SAMPLE_DATA )
 
        old_sys_argv = list(sys.argv)
        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
        try:
            self.ilastik_startup.main()
        finally:
            sys.argv = old_sys_argv
#             if OLD_LAZYFLOW_STATUS_MONITOR_SECONDS:
#                 os.environ["LAZYFLOW_STATUS_MONITOR_SECONDS"] = OLD_LAZYFLOW_STATUS_MONITOR_SECONDS
 
        output_path = self.SAMPLE_DATA[:-4] + "_segmentation_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( 'tzyxc' )
        opReorderAxes.Input.connect( opReader.stack )
         
        try:
            readData = opReorderAxes.Output[:].wait()
     
            # Check basic attributes
            assert readData.shape[:-1] == self.data[0:1, 50:150, 50:150, 0:50, 0:1].shape[:-1] # Assume channel is last axis
            assert readData.shape[-1] == 1, "Wrong number of channels.  Expected 1, got {}".format( readData.shape[-1] )
        finally:
            # Clean-up.
            opReorderAxes.cleanUp()
            opReader.cleanUp()
    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 = 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 = OpStackLoader( 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.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"
        
        opReorderAxes.cleanUp()
        opReader.cleanUp()
Beispiel #11
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()
            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 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 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 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 = 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 = 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 #16
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 #17
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 #18
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 #19
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()
    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
        ilastik_entry_file_path = os.path.join( os.path.split( ilastik.__file__ )[0], "../ilastik.py" )
        imp.load_source( 'main', ilastik_entry_file_path )

        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()
Beispiel #21
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"
Beispiel #22
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}')
    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 __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 #26
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 #27
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()
Beispiel #28
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 #29
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 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()
Beispiel #32
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 #33
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 #35
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)
    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 #37
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 = vigra_bincount(readData)[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 )
            
            if opReorderAxes._invalid_axes:
                settingsDlg.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
                # Red background
                settingsDlg.axesEdit.setStyleSheet("QLineEdit { background: rgb(255, 128, 128);"
                                                   "selection-background-color: rgb(128, 128, 255); }")
        settingsDlg.axesEdit.editingFinished.connect( handle_updated_axes )
        
        # Initialize
        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()
class ObjectExtractionTimeComparison(object):
    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 run(self):

        #         # Load caches beforehand (To remove overhead of reading frames)
        #         with Timer() as timerCaches:
        #             rawVol = self.opCacheRaw.Output([]).wait()
        #             binaryVol = self.opCacheBinary.Output([]).wait()
        #
        #         print "Caches took {} secs".format(timerCaches.seconds())
        #
        #         del rawVol
        #         del binaryVol

        # Profile object extraction simplified
        print(
            "\nStarting object extraction simplified (single-thread, without cache)"
        )

        with Timer() as timerObjectFeaturesSimp:
            featsObjectFeaturesSimp = self.opObjectFeaturesSimp.Features(
                []).wait()

        print("Simplified object extraction took: {} seconds".format(
            timerObjectFeaturesSimp.seconds()))

        # Profile object extraction optimized
        print("\nStarting object extraction (multi-thread, without cache)")

        with Timer() as timerObjectExtraction:
            featsObjectExtraction = self.opObjectExtraction.RegionFeatures(
                []).wait()

        print("Object extraction took: {} seconds".format(
            timerObjectExtraction.seconds()))

        # Profile for basic multi-threaded feature computation
        # just a multi-threaded loop that labels volumes and extract object features directly (No operators, no plugin system, no overhead, just a loop)
        featsBasicFeatureComp = dict.fromkeys(
            list(range(self.op5Raw.Output.meta.shape[0])), None)

        print("\nStarting basic multi-threaded feature computation")
        pool = RequestPool()
        for t in range(0, self.op5Raw.Output.meta.shape[0], 1):
            pool.add(
                Request(
                    partial(self._computeObjectFeatures, t,
                            featsBasicFeatureComp)))

        with Timer() as timerBasicFeatureComp:
            pool.wait()

        print(
            "Basic multi-threaded feature extraction took: {} seconds".format(
                timerBasicFeatureComp.seconds()))

    # Compute object features for single frame
    def _computeObjectFeatures(self, t, result):
        roi = [slice(None) for i in range(len(self.op5Raw.Output.meta.shape))]
        roi[0] = slice(t, t + 1)
        roi = tuple(roi)

        #         rawVol = self.opCacheRaw.Output(roi).wait()
        #         binaryVol = self.opCacheBinary.Output(roi).wait()

        rawVol = self.op5Raw.Output(roi).wait()
        binaryVol = self.op5Binary.Output(roi).wait()

        features = [
            'Count', 'Coord<Minimum>', 'RegionCenter',
            'Coord<Principal<Kurtosis>>', 'Coord<Maximum>'
        ]

        for i in range(t, t + 1):
            labelVol = vigra.analysis.labelImageWithBackground(
                binaryVol[i - t].squeeze(), background_value=int(0))
            res = vigra.analysis.extractRegionFeatures(
                rawVol[i - t].squeeze().astype(np.float32),
                labelVol.squeeze().astype(np.uint32),
                features,
                ignoreLabel=0)

            # Cleanup results (as done in vigra_objfeats)
            local_features = [x for x in features if "Global<" not in x]
            nobj = res[local_features[0]].shape[0]
            result[i] = cleanup(res, nobj, features)
class TikTorchLazyflowClassifier(LazyflowPixelwiseClassifierABC):
    HDF5_GROUP_FILENAME = "pytorch_network_path"

    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 predict_probabilities_pixelwise(self,
                                        feature_image,
                                        roi,
                                        axistags=None):
        """
        Implicitly assumes that feature_image is includes the surrounding HALO!
        roi must be chosen accordingly
        """
        logger.info(
            f"predicting using pytorch network for image of shape {feature_image.shape} and roi {roi}"
        )
        logger.info(
            f"Stats of input: min={feature_image.min()}, max={feature_image.max()}, mean={feature_image.mean()}"
        )
        logger.info(
            f"expected pytorch input shape is {self._tiktorch_net.expected_input_shape}"
        )
        logger.info(
            f"expected pytorch output shape is {self._tiktorch_net.expected_output_shape}"
        )

        # print(self._tiktorch_net.expected_input_shape)
        # print(self._tiktorch_net.expected_output_shape)

        num_channels = len(self.known_classes)
        expected_shape = [stop - start for start, stop in zip(roi[0], roi[1])
                          ] + [num_channels]

        self._opReorderAxes.Input.setValue(
            vigra.VigraArray(feature_image, axistags=axistags))
        self._opReorderAxes.AxisOrder.setValue("zcyx")
        reordered_feature_image = self._opReorderAxes.Output([]).wait()

        # normalizing patch
        # reordered_feature_image = (reordered_feature_image - reordered_feature_image.mean()) / (reordered_feature_image.std() + 0.000001)

        if len(self._tiktorch_net.get("window_size")) == 2:
            exp_input_shape = numpy.array(
                self._tiktorch_net.expected_input_shape)
            exp_input_shape = tuple(numpy.append(1, exp_input_shape))
            print(exp_input_shape)
        else:
            exp_input_shape = self._tiktorch_net.expected_input_shape

        logger.info(
            f"input axistags are {axistags}, "
            f"Shape after reordering input is {reordered_feature_image.shape}, "
            f"axistags are {self._opReorderAxes.Output.meta.axistags}")

        slice_shape = list(reordered_feature_image.shape[1::])  # ignore z axis
        # assuming [z, y, x]
        result_roi = numpy.array(roi)
        if slice_shape != list(exp_input_shape[1::]):
            logger.info(f"Expected input shape is {exp_input_shape[1::]}, "
                        f"but got {slice_shape}, reshaping...")

            # adding a zero border to images that have the specific shape

            exp_shape = list(self._tiktorch_net.expected_input_shape[1::])
            zero_img = numpy.zeros(exp_shape)

            # diff shape: cyx
            diff_shape = numpy.array(
                exp_input_shape[1::]) - numpy.array(slice_shape)
            # diff_shape = numpy.array(self._tiktorch_net.expected_input_shape) - numpy.array(slice_shape)
            # offset shape z, y, x, c for easy indexing, with c = 0, z = 0
            offset = numpy.array([0, 0, 0, 0])
            logger.info(f"Diff_shape {diff_shape}")

            # at least one of y, x (diff_shape[1], diff_shape[2]) should be off
            # let's determine how to adjust the offset -> offset[2] and offset[3]
            # caveat: this code assumes that image requests were tiled in a regular
            # pattern starting from left upper corner.
            # We use a blocked array-cache to achieve that
            # y-offset:
            if diff_shape[1] > 0:
                # was the halo added to the upper side of the feature image?
                # HACK: this only works because we assume the data to be in zyx!!!
                if roi[0][1] == 0:
                    # no, doesn't seem like it
                    offset[1] = self.HALO_SIZE

            # x-offsets:
            if diff_shape[2] > 0:
                # was the halo added to the upper side of the feature image?
                # HACK: this only works because we assume the data to be in zyx!!!
                if roi[0][2] == 0:
                    # no, doesn't seem like it
                    offset[2] = self.HALO_SIZE

            # HACK: still assuming zyxc
            result_roi[0] += offset[0:3]
            result_roi[1] += offset[0:3]
            reorder_feature_image_extents = numpy.array(
                reordered_feature_image.shape)
            # add the offset:
            reorder_feature_image_extents[2:4] += offset[1:3]
            # zero_img[:, :, offset[1]:reorder_feature_image_extents[2], offset[2]:reorder_feature_image_extents[3]] = \
            #     reordered_feature_image

            # reordered_feature_image = zero_img

            pad_img = numpy.pad(
                reordered_feature_image,
                [
                    (0, 0),
                    (0, 0),
                    (offset[1],
                     exp_input_shape[2] - reorder_feature_image_extents[2]),
                    (offset[2],
                     exp_input_shape[3] - reorder_feature_image_extents[3]),
                ],
                "reflect",
            )

            reordered_feature_image = pad_img

            logger.info(f"New Image shape {reordered_feature_image.shape}")

        result = numpy.zeros([reordered_feature_image.shape[0], num_channels] +
                             list(reordered_feature_image.shape[2:]))

        logger.info(f"forward")

        # we always predict in 2D, per z-slice, so we loop over z
        for z in range(0, reordered_feature_image.shape[0], self.BATCH_SIZE):
            # logger.warning("Dumping to {}".format('"/Users/chaubold/Desktop/dump.h5"'))
            # vigra.impex.writeHDF5(reordered_feature_image[z,...], "data", "/Users/chaubold/Desktop/dump.h5")

            # create batch of desired num slices. Multiple slices can be processed on multiple GPUs!
            batch = [
                reordered_feature_image[zi:zi + 1, ...].reshape(
                    self._tiktorch_net.expected_input_shape)
                for zi in range(
                    z,
                    min(z + self.BATCH_SIZE, reordered_feature_image.shape[0]))
            ]
            logger.info(f"batch info: {[x.shape for x in batch]}")

            print("batch info:", [x.shape for x in batch])

            # if len(self._tiktorch_net.get('window_size')) == 2:
            #     print("BATTCHHHHH", batch.shape)

            result_batch = self._tiktorch_net.forward(batch)
            logger.info(
                f"Resulting slices from {z} to {z + len(batch)} have shape {result_batch[0].shape}"
            )

            print("Resulting slices from ", z, " to ", z + len(batch),
                  " have shape ", result_batch[0].shape)

            for i, zi in enumerate(range(z, (z + len(batch)))):
                result[zi:(zi + 1), ...] = result_batch[i]

        logger.info(f"Obtained a predicted block of shape {result.shape}")

        print("Obtained a predicted block of shape ", result.shape)

        self._opReorderAxes.Input.setValue(
            vigra.VigraArray(result, axistags=vigra.makeAxistags("zcyx")))
        # axistags is vigra.AxisTags, but opReorderAxes expects a string
        self._opReorderAxes.AxisOrder.setValue("".join(axistags.keys()))
        result = self._opReorderAxes.Output([]).wait()
        logger.info(f"Reordered result to shape {result.shape}")

        # FIXME: not needed for real neural net results:
        logger.info(
            f"Stats of result: min={result.min()}, max={result.max()}, mean={result.mean()}"
        )

        # cut out the required roi
        logger.info(f"Roi shape {result_roi}")

        # crop away halo and reorder axes to match "axistags"
        # crop in X and Y:
        cropped_result = result[roiToSlice(*result_roi)]

        logger.info(
            f"cropped the predicted block to shape {cropped_result.shape}")

        return cropped_result

    @property
    def known_classes(self):
        return list(range(self._tiktorch_net.expected_output_shape[0]))

    @property
    def feature_count(self):
        return self._tiktorch_net.expected_input_shape[0]

    def get_halo_shape(self, data_axes="zyxc"):
        if len(data_axes) == 4:
            return (0, self.HALO_SIZE, self.HALO_SIZE, 0)
        # FIXME: assuming 'yxc' !
        elif len(data_axes) == 3:
            return (self.HALO_SIZE, self.HALO_SIZE, 0)

    def serialize_hdf5(self, h5py_group):
        logger.debug("Serializing")
        h5py_group[self.HDF5_GROUP_FILENAME] = self._filename
        h5py_group["pickled_type"] = pickle.dumps(type(self), 0)

        # HACK: can this be done more elegantly?
        with tempfile.TemporaryFile() as f:
            self._tiktorch_net.serialize(f)
            f.seek(0)
            h5py_group["classifier"] = numpy.void(f.read())

    @classmethod
    def deserialize_hdf5(cls, h5py_group):
        # TODO: load from HDF5 instead of hard coded path!
        logger.debug("Deserializing")
        # HACK:
        # filename = PYTORCH_MODEL_FILE_PATH
        filename = h5py_group[cls.HDF5_GROUP_FILENAME]
        logger.debug("Deserializing from {}".format(filename))

        with tempfile.TemporaryFile() as f:
            f.write(h5py_group["classifier"].value)
            f.seek(0)
            loaded_pytorch_net = TikTorch.unserialize(f)

        return TikTorchLazyflowClassifier(loaded_pytorch_net, filename)
Beispiel #40
0
        def impl():
            shell = self.shell
            workflow = shell.projectManager.workflow
            carvingApplet = workflow.carvingApplet
            gui = carvingApplet.getMultiLaneGui()
            op_carving = carvingApplet.topLevelOperator.getLane(0)

            # activate the carving applet
            shell.setSelectedAppletDrawer(2)
            # let the gui catch up
            QApplication.processEvents()
            self.waitForViews(gui.currentGui().editor.imageViews)
            # inject the labels
            op5 = OpReorderAxes(parent=op_carving.parent)
            opReader = OpInputDataReader(parent=op_carving.parent)
            try:
                opReader.FilePath.setValue(f"{self.reference_files['carving_label_file']}/exported_data")
                op5.AxisOrder.setValue(op_carving.WriteSeeds.meta.getAxisKeys())
                op5.Input.connect(opReader.Output)
                label_data = op5.Output[:].wait()
            finally:
                op5.cleanUp()
                opReader.cleanUp()
            slicing = roi.fullSlicing(label_data.shape)
            op_carving.WriteSeeds[slicing] = label_data

            gui.currentGui().labelingDrawerUi.segment.click()
            QApplication.processEvents()

            op_carving.saveObjectAs("Object 1")
            op_carving.deleteObject("<not saved yet>")

            # export the mesh:
            req = gui.currentGui()._exportMeshes(["Object 1"], [self.output_obj_file])
            req.wait()

            # compare meshes
            with open(self.output_obj_file, "r") as f:
                left = f.read()

            with open(self.reference_files["output_obj_file"], "r") as f:
                right = f.read()

            # TODO: might result in errors due to rounding on different systems
            assert left == right

            # export the completed segments layer
            layermatch = [
                x.name.startswith("Completed segments (unicolor)") for x in gui.currentGui().editor.layerStack
            ]
            assert sum(layermatch) == 1, "Completed segments (unicolor) Layer expected."
            completed_segments_layer = gui.currentGui().editor.layerStack[layermatch.index(True)]
            opExport = get_export_operator(completed_segments_layer)
            try:
                opExport.OutputFilenameFormat.setValue(self.output_file)
                opExport.run_export()
            finally:
                opExport.cleanUp()

            assert os.path.exists(self.output_file)

            # compare completed segments
            with h5py.File(self.reference_files["output_file"], "r") as f_left:
                data_left = f_left["exported_data"][:]

            with h5py.File(self.output_file, "r") as f_right:
                data_right = f_right["exported_data"][:]

            numpy.testing.assert_array_almost_equal(data_left, data_right)

            # Save the project
            saveThread = self.shell.onSaveProjectActionTriggered()
            saveThread.join()