예제 #1
0
class TestOutputOutputConnection(object):

    def setUp(self):
        self.g = Graph()
        self.op = OpOuter(graph=self.g)

    def tearDown(self):
        self.g.stopGraph()

    def test_value(self):
        """
        This test checks, that requests produce correct
        results in the case of output-output connections
        (the o-o connection exists inside the OpOuter...
        """
        self.op.Input.setValue(True)
        result = self.op.Output[:].wait()[0]
        assert result == True, "result = %r" % result
        self.op.Input.setValue(False)
        result = self.op.Output[:].wait()[0]
        assert result == False, "result = %r" % result

    def test_execute(self):
        """
        This test checks that the execute method of the outer
        operator is not called, when the output slot of the
        op is connect to the output slot of another (inner) operator
        """
        self.op.Input.setValue(True)
        self.op._was_executed = False
        result = self.op.Output[:].wait()[0]
        assert self.op._was_executed is False
예제 #2
0
class TestSlot_notifyMetaChanged(object):
    def setUp(self):
        self.g = Graph()

    def tearDown(self):
        self.g.stopGraph()

    def test_inputslot_changed(self):
        # test that the changed callback is called
        # when the slot meta information changes
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        # test normal InputSlot
        opa.Input1.notifyMetaChanged(callBack)
        opa.Input1.connect(ops.Output1)
        assert upval[0] == True

        upval[0] = False
        opa.Input1.connect(ops.Output2)
        assert upval[0] == True

        # test InputSlot with default value
        upval[0] = False
        opa.Input3.notifyMetaChanged(callBack)
        opa.Input3.connect(ops.Output1)
        assert upval[0] == True

        upval[0] = False
    def __init__(self, argv):
        QMainWindow.__init__(self)
        
        #Normalize the data if true
        self._normalize_data=True
        
        if 'notnormalize' in sys.argv:
            print sys.argv
            self._normalize_data=False
            sys.argv.remove('notnormalize')

        self.opPredict = None
        self.opTrain = None
        self.opThreshold = None
        self._colorTable16 = self._createDefault16ColorColorTable()
        
        #self.g = Graph(7, 2048*1024**2*5)
        self.g = Graph()
        self.fixableOperators = []
        
        self.featureDlg=None

        
        #The old ilastik provided the following scale names:
        #['Tiny', 'Small', 'Medium', 'Large', 'Huge', 'Megahuge', 'Gigahuge']
        #The corresponding scales are:
        self.featScalesList=[0.3, 0.7, 1, 1.6, 3.5, 5.0, 10.0]
        
        self.initUic()
        
        #if the filename was specified on command line, load it
        if len(sys.argv) >= 2:
            def loadFile():
                self._openFile(sys.argv[1:])
            QTimer.singleShot(0, loadFile)
class TestMultiInputInputConnection(object):

    def setUp(self):
        self.g = Graph()
        self.op = OpC(graph=self.g)

    def tearDown(self):
        self.g.stopGraph()

    def test_wrapping(self):
        opm = operators.Op5ToMulti(graph=self.g)
        opm.Input0.setValue(1)

        self.op.Input.connect(opm.Outputs)

        assert len(self.op.internalOp.Output) == 1
        assert self.op.internalOp.Output[0].meta.shape is not None
        assert self.op.internalOp.Output[0].value == 1
class TestInputInputConnection(object):

    def setUp(self):
        self.g = Graph()
        self.op = OpA(graph=self.g)

    def tearDown(self):
        self.g.stopGraph()

    def test_value(self):
        self.op.Input.setValue(True)
        result = self.op.Output[:].allocate().wait()[0]
        assert result == True, "result = %r" % result
        self.op.Input.setValue(False)
        result = self.op.Output[:].allocate().wait()[0]
        assert result == False, "result = %r" % result

    def test_disconnect(self):
        self.op.internalOp.Input.disconnect()
        self.op.internalOp.Input.connect(self.op.Input)


    def test_wrapping(self):
        opm = operators.Op5ToMulti(graph=self.g)
        opm.Input0.setValue(1)

        op = OperatorWrapper( OpA, graph=self.g )
        op.Input.connect(opm.Outputs)
        result = op.Output[0][:].allocate().wait()[0]
        assert result == 1

        opm.Input1.setValue(2)
        result = op.Output[1][:].allocate().wait()[0]
        assert result == 2

        # Note: operator wrappers do not "restore" back to unwrapped operators after disconnect
        # (That was their behavior at some point, but no longer.)
        op.Input.disconnect()
        op.Input.resize(0)
        op.Input.setValue(2)
        assert len(op.Input) == 0
        assert len(op.Output) == 0
예제 #6
0
    def testReportGeneration(self):
        graph = Graph()
        sampleData = numpy.random.randint(0, 256, size=(50, 50, 50))
        sampleData = sampleData.astype(numpy.uint8)
        sampleData = vigra.taggedView(sampleData, axistags="xyz")

        opData = OpArrayPiper(graph=graph)
        opData.Input.setValue(sampleData)

        op = OpCompressedCache(parent=None, graph=graph)
        op.BlockShape.setValue((25, 25, 25))
        op.Input.connect(opData.Output)

        before = time.time()
        assert op.Output.ready()
        assert op.usedMemory() == 0.0, "cache must not be filled at this point"
        op.Output[...].wait()
        assert op.usedMemory() > 0.0, "cache must contain data at this point"
        after = time.time()

        r = MemInfoNode()
        op.generateReport(r)
        # not sure how good this can be compressed, but the cache
        # should hold memory by now
        assert r.usedMemory > 0
        # check sanity of last access time
        assert r.lastAccessTime >= before, str(r.lastAccessTime)
        assert r.lastAccessTime <= after, str(r.lastAccessTime)
        assert r.fractionOfUsedMemoryDirty == 0.0

        opData.Input.setDirty((slice(0, 25), slice(0, 25), slice(0, 25)))
        assert op.fractionOfUsedMemoryDirty() < 1.0
        assert op.fractionOfUsedMemoryDirty() > 0

        opData.Input.setDirty(slice(None))
        assert op.fractionOfUsedMemoryDirty() == 1.0
예제 #7
0
    def test_3d_with_compression(self, tmp_path):
        """
        This tests that we can read a compressed (LZW) TIFF file.

        Note: It would be nice to test JPEG compression here, but strangely when vigra
        writes a JPEG-compressed TIFF, it is somehow messed up.  The image has two image
        'series' in it, so the thing seems to have twice as many planes as it should.
        Furthermore, vigra doesn't seem to read it back correctly, or maybe I'm missing something...
        """
        data = numpy.random.randint(0, 255, (50, 100, 200, 3), dtype="uint8")

        tiff_path = str(tmp_path / "test-3d.tiff")
        for z_slice in data:
            vigra.impex.writeImage(vigra.taggedView(z_slice, "yxc"),
                                   tiff_path,
                                   dtype="NATIVE",
                                   compression="LZW",
                                   mode="a")

        op = OpTiffReader(graph=Graph())
        op.Filepath.setValue(tiff_path)
        assert op.Output.ready()
        assert (op.Output[20:30, 50:100, 50:150].wait() == data[20:30, 50:100,
                                                                50:150]).all()
예제 #8
0
    def __init__(
        self,
        *,
        filePath: str,
        project_file: h5py.File = None,
        sequence_axis: str = None,
        nickname: str = "",
        drange: Tuple[Number, Number] = None,
        **info_kwargs,
    ):
        """
        sequence_axis: Axis along which to stack (only applicable for stacks).
        """
        self.sequence_axis = sequence_axis
        self.base_dir = str(Path(project_file.filename).absolute().parent) if project_file else os.getcwd()
        assert os.path.isabs(self.base_dir)  # FIXME: if file_project was opened as a relative path, this would break
        self.expanded_paths = self.expand_path(filePath, cwd=self.base_dir)
        assert len(self.expanded_paths) == 1 or self.sequence_axis
        if len({PathComponents(ep).extension for ep in self.expanded_paths}) > 1:
            raise Exception(f"Multiple extensions unsupported as a single data source: {self.expanded_paths}")
        self.filePath = os.path.pathsep.join(self.expanded_paths)

        op_reader = OpInputDataReader(
            graph=Graph(), WorkingDirectory=self.base_dir, FilePath=self.filePath, SequenceAxis=self.sequence_axis
        )
        meta = op_reader.Output.meta.copy()
        op_reader.cleanUp()

        super().__init__(
            default_tags=meta.axistags,
            nickname=nickname or self.create_nickname(self.expanded_paths),
            laneShape=meta.shape,
            laneDtype=meta.dtype,
            drange=drange or meta.get("drange"),
            **info_kwargs,
        )
예제 #9
0
    def test_hysteresis(self):
        data = self.data
        core_binary = (data == 5)
        core_labels = np.empty_like(data, dtype=np.uint32)
        core_labels[0, ..., 0] = vigra.analysis.labelMultiArrayWithBackground(
            core_binary[0, ..., 0].astype(np.uint8))

        op = OpLabeledThreshold(graph=Graph())
        op.Method.setValue(ThresholdMethod.HYSTERESIS)
        op.FinalThreshold.setValue(0.5)
        op.Input.setValue(data.copy())
        op.CoreLabels.setValue(core_labels)

        result = op.Output[:].wait()

        label_values = np.unique(result)[1:]
        assert len(label_values) == 1

        expected_result = np.where(data, label_values[0], 0)
        expected_result[0, :, 5:, 0, 0] = 0  # Right half won't survive

        #print expected_result[0,:,:,0,0]
        #print result[0,:,:,0,0]
        assert (result == expected_result).all()
예제 #10
0
    def create_input(cls, filepath, input_axes, outmin=None, outmax=None, dtype=None):
        """ Creates a file from the data at 'filepath' that has 'input_axes' """
        basename = os.path.basename(filepath)
        reader = OpInputDataReader(graph=Graph())
        assert os.path.exists(filepath), '{} not found'.format(filepath)
        reader.FilePath.setValue(os.path.abspath(filepath))

        writer = OpFormattedDataExport(parent=reader)
        if outmin is not None:
            writer.ExportMin.setValue(outmin)
        if outmax is not None:
            writer.ExportMax.setValue(outmax)
        if dtype is not None:
            writer.ExportDtype.setValue(dtype)

        writer.OutputAxisOrder.setValue(input_axes)
        writer.Input.connect(reader.Output)
        writer.OutputFilenameFormat.setValue(os.path.join(
            cls.dir, basename.split('.')[0] + '_' + input_axes))
        writer.TransactionSlot.setValue(True)
        input_path = writer.ExportPath.value
        writer.run_export()

        return input_path
예제 #11
0
    def __init__(self, headless, workflow_cmdline_args, *args, **kwargs):
        # Create a graph to be shared by all operators
        graph = Graph()
        super(StopWatchWorkflow, self).__init__(headless,
                                                graph=graph,
                                                *args,
                                                **kwargs)
        #self.name = OperatorWrapper(OpName( graph=graph)
        #self.name.Output[0].setValue("void")

        self._applets = []

        # Create applets
        self.dataSelectionApplet = DataSelectionApplet(
            self,
            "Input Data",
            "Input Data",
            supportIlastik05Import=True,
            batchDataGui=False)
        self.stopWatchApplet = StopWatchApplet(self, "Stop Watch",
                                               "Stop Watch")

        self._applets.append(self.dataSelectionApplet)
        self._applets.append(self.stopWatchApplet)
예제 #12
0
    def test_graphcut(self):
        if _has_graphcut:
            data = self.data
            
            # Core labels don't matter in this graphcut test
            #core_binary = (data == 5)
            core_labels = np.empty_like(data, dtype=np.uint32)
            #core_labels[0,...,0] = vigra.analysis.labelMultiArrayWithBackground(core_binary[0,...,0].astype(np.uint8))

            op = OpLabeledThreshold(graph=Graph())
            op.Method.setValue(ThresholdMethod.GRAPHCUT)
            op.FinalThreshold.setValue(0.5)
            op.Input.setValue(data.copy())
            op.CoreLabels.setValue(core_labels)
            op.GraphcutBeta.setValue(0.5) # High enough to fill the hole in the third segment
            
            result = op.Output[:].wait()
            result_yx = result[0,:,:,0,0]
            #print result_yx
            
            label_values = np.unique(result)[1:]
            assert len(label_values) == 3        
            assert len(np.unique(result_yx[1:12, 1:5])) == 1 # Same as 'simple'
            assert len(np.unique(result_yx[7:10, 6:9])) == 1 # Almost same as simple, but with the hole filled in.
예제 #13
0
    def testReconnect(self):
        """
        Can we connect an image, then replace it with a differently-ordered image?
        """
        predRaw = np.zeros((20, 22, 21, 3), dtype=np.uint32)
        pred1 = vigra.taggedView(predRaw, axistags='zyxc')
        pred2 = vigra.taggedView(predRaw, axistags='tyxc')

        oper5d = OpThresholdTwoLevels(graph=Graph())
        oper5d.InputImage.setValue(pred1)
        oper5d.MinSize.setValue(self.minSize)
        oper5d.MaxSize.setValue(self.maxSize)
        oper5d.HighThreshold.setValue(self.highThreshold)
        oper5d.LowThreshold.setValue(self.lowThreshold)
        oper5d.SmootherSigma.setValue(self.sigma)
        oper5d.Channel.setValue(0)
        oper5d.CoreChannel.setValue(0)
        oper5d.CurOperator.setValue(1)

        out5d = oper5d.CachedOutput[:].wait()

        oper5d.InputImage.disconnect() # FIXME: Why is this line necessary? Ideally, it shouldn't be...
        oper5d.InputImage.setValue(pred2)
        out5d = oper5d.CachedOutput[:].wait()
예제 #14
0
    def testSetInSlot(self):
        graph = Graph()
        opDataProvider = OpArrayPiperWithAccessCount(graph=graph)
        opCache = OpUnblockedArrayCache(graph=graph)

        data = np.random.random((100, 100, 100)).astype(np.float32)
        opDataProvider.Input.setValue(vigra.taggedView(data, "zyx"))
        opCache.Input.connect(opDataProvider.Output)

        # Write two blocks
        opCache.Input[10:20, 10:20, 10:20] = 2 * np.ones((10, 10, 10), dtype=np.float32)
        opCache.Input[20:30, 20:30, 20:30] = 3 * np.ones((10, 10, 10), dtype=np.float32)

        # They should be valid now
        assert opCache.CleanBlocks.value == [tuple(make_key[10:20, 10:20, 10:20]), tuple(make_key[20:30, 20:30, 20:30])]

        assert (opCache.Output[10:20, 10:20, 10:20].wait() == 2).all()
        assert (opCache.Output[20:30, 20:30, 20:30].wait() == 3).all()

        # Mark a big dirty area
        opDataProvider.Input.setDirty((10, 10, 10), (40, 40, 40))

        # No blocks left in the cache
        assert opCache.CleanBlocks.value == []
    def testDirtyPropagation(self):
        g = Graph()
        vol = np.asarray(
            [[0, 0, 0, 0], [0, 0, 1, 1], [0, 1, 0, 1], [0, 1, 0, 1]],
            dtype=np.uint8)
        vol = vigra.taggedView(vol, axistags='xy').withAxes(*'xyz')

        chunkShape = (2, 2, 1)

        opCache = OpCompressedCache(graph=g)
        opCache.Input.setValue(vol)
        opCache.BlockShape.setValue(chunkShape)

        op = OpLazyCC(graph=g)
        op.Input.connect(opCache.Output)
        op.ChunkShape.setValue(chunkShape)

        out1 = op.Output[:2, :2].wait()
        assert np.all(out1 == 0)

        opCache.Input[0:1, 0:1, 0:1] = np.asarray([[[1]]], dtype=np.uint8)

        out2 = op.Output[:1, :1].wait()
        assert np.all(out2 > 0)
예제 #16
0
    def testEvenFunnierAxes(self):
        vol = numpy.random.randint(0, 255, size=(5, 17, 31, 42, 11))
        vol = vol.astype(numpy.uint8)
        # don't care about corner cases
        vol[vol == 128] = 129
        vol[vol == 127] = 126
        desiredResult = numpy.where(vol > 128, 1, 0)
        vol = vigra.taggedView(vol, axistags='xtycz')

        oper5d = OpThresholdTwoLevels(graph=Graph())
        oper5d.InputImage.setValue(vol)
        oper5d.MinSize.setValue(1)
        oper5d.MaxSize.setValue(vol.size)
        oper5d.LowThreshold.setValue(128)
        oper5d.SmootherSigma.setValue({'z': 0.0, 'y': 0.0, 'x': 0.0})
        oper5d.CurOperator.setValue(self.curOperator)

        #for i in range(vol.shape[3]):
        for i in range(2, 5):  # just test some sample slices (runtime :)
            oper5d.Channel.setValue(i)
            oper5d.CoreChannel.setValue(i)
            out5d = oper5d.Output[:].wait()
            out5d[out5d > 0] = 1
            numpy.testing.assert_array_equal(out5d.squeeze(), desiredResult[..., i, :])
예제 #17
0
    def test_xyz_stack_c(self):
        # expected_volume_zyxc, globstring = self._prepare_data_zyx_stack_c()
        expected_volume, globstring = self._prepare_data(
            'rand_3d_stack_c',
            (2, 3, 5, 4),
            'czxy',
            'c'
        )

        graph = Graph()
        op = OpStackLoader(graph=graph)
        op.SequenceAxis.setValue('c')
        op.globstring.setValue(globstring)

        assert len(op.stack.meta.axistags) == 4
        assert op.stack.meta.getAxisKeys() == list('czyx')
        assert op.stack.meta.dtype == expected_volume.dtype

        volume_from_stack = op.stack[:].wait()
        volume_from_stack = vigra.taggedView(volume_from_stack, 'czyx')
        volume_from_stack = volume_from_stack.withAxes(*'czxy')

        assert (volume_from_stack == expected_volume).all(), \
            "3D Volume stacked along c did not match expected data."
예제 #18
0
    def testReconnectWithoutRequest_masked(self):
        vol = numpy.ma.zeros((200, 100, 50), dtype=numpy.float32)
        vol.set_fill_value(numpy.float32(numpy.nan))
        vol[0] = numpy.ma.masked
        vol1 = vol
        vol2 = vol1.T
        graph = Graph()

        opData1 = OpArrayPiper(graph=graph)
        opData1.Input.meta.has_mask = True
        opData1.Input.meta.axistags = vigra.defaultAxistags('xyz')
        opData1.Input.setValue(vol1)

        op = OpCompressedCache(graph=graph)
        op.Input.connect(opData1.Output)
        op.BlockShape.setValue((200, 100, 10))
        out = op.Output[...].wait()

        assert (out == vol).all() and \
               (out.mask == vol.mask).all() and \
               ((out.fill_value == vol.fill_value) |
                (numpy.isnan(out.fill_value) & numpy.isnan(vol.fill_value))).all(),\
            "Incorrect output!"

        op.BlockShape.setValue((50, 100, 10))

        # Older versions of OpCompressedCache threw an exception here because
        #  we tried to access the cache after changing the blockshape.
        # But in the current version, we claim that's okay.
        out = op.Output[...].wait()

        assert (out == vol).all() and \
               (out.mask == vol.mask).all() and \
               ((out.fill_value == vol.fill_value) |
                (numpy.isnan(out.fill_value) & numpy.isnan(vol.fill_value))).all(),\
            "Incorrect output!"
예제 #19
0
    def setUp(self):
        segimg = segImage()
        binimg = (segimg>0).astype(np.uint8)
        labels = {0 : np.array([0, 1, 2]),
                  1 : np.array([0, 1, 1, 2])}

        rawimg = np.indices(segimg.shape).sum(0).astype(np.float32)
        rawimg = rawimg.view(vigra.VigraArray)
        rawimg.axistags = vigra.defaultAxistags('txyzc')

        g = Graph()

        features = {"Standard Object Features": {"Count":{}, "RegionCenter":{}, "Coord<Principal<Kurtosis>>":{}, \
                                      "Coord<Minimum>":{}, "Coord<Maximum>":{}, "Mean":{}, \
                                      "Mean in neighborhood":{"margin":(30, 30, 1)}}}
        
        sel_features = {"Standard Object Features": {"Count":{}, "Mean":{}, "Mean in neighborhood":{"margin":(30, 30, 1)}, "Variance":{}}}
        
        self.extrOp = OpObjectExtraction(graph=g)
        self.extrOp.BinaryImage.setValue(binimg)
        self.extrOp.RawImage.setValue(rawimg)
        self.extrOp.Features.setValue(features)
    
        assert self.extrOp.RegionFeatures.ready()

        self.trainop = OpObjectTrain(graph=g)
        self.trainop.Features.resize(1)
        self.trainop.Features.connect(self.extrOp.RegionFeatures)
        self.trainop.SelectedFeatures.setValue(sel_features)
        self.trainop.LabelsCount.setValue(2)
        self.trainop.Labels.resize(1)
        self.trainop.Labels.setValues([labels])
        self.trainop.FixClassifier.setValue(False)
        self.trainop.ForestCount.setValue(1)
        
        assert self.trainop.Classifier.ready()
예제 #20
0
    def testSingletonZ(self):
        vol = np.zeros((82, 70, 1, 5, 5), dtype=np.uint8)
        vol = vigra.taggedView(vol, axistags="xyzct")

        blocks = np.zeros(vol.shape, dtype=np.uint8)
        blocks[30:50, 40:60, :, 2:4, 3:5] = 1
        blocks[30:50, 40:60, :, 2:4, 0:2] = 2
        blocks[60:70, 30:40, :, :, :] = 3

        vol[blocks == 1] = 255
        vol[blocks == 2] = 255
        vol[blocks == 3] = 255

        op = OpLabelVolume(graph=Graph())
        op.Method.setValue(self.method)
        op.Input.setValue(vol)

        out = op.Output[...].wait()
        tags = op.Output.meta.getTaggedShape()
        out = vigra.taggedView(out, axistags="".join([s for s in tags]))

        for c in range(out.shape[3]):
            for t in range(out.shape[4]):
                assertEquivalentLabeling(blocks[..., c, t], out[..., c, t])
예제 #21
0
    def testBasic(self):
        graph = Graph()
        op = OpTiledVolumeReader(graph=graph)
        op.DescriptionFilePath.setValue(
            self.data_setup.VOLUME_DESCRIPTION_FILE)
        op.tiled_volume.TEST_MODE = True

        roi = numpy.array([(10, 150, 100), (30, 550, 550)])
        result_out = op.Output(*roi).wait()

        # We expect a channel dimension to be added automatically...
        assert (result_out.shape == roi[1] - roi[0]).all()

        ref_path_comp = PathComponents(self.data_setup.REFERENCE_VOL_PATH)
        with h5py.File(ref_path_comp.externalPath, "r") as f:
            ref_data = f[ref_path_comp.internalPath][:]

        expected = ref_data[roiToSlice(*roi)]

        # numpy.save('/tmp/expected.npy', expected)
        # numpy.save('/tmp/result_out.npy', result_out)

        # We can't expect the pixels to match exactly because compression was used to create the tiles...
        assert (expected == result_out).all()
예제 #22
0
    def testNoOp(self):
        oper5d = OpThresholdTwoLevels(graph=Graph())
        oper5d.InputImage.setValue(self.data5d)
        oper5d.MinSize.setValue(1)
        oper5d.MaxSize.setValue(self.data5d.size)
        oper5d.LowThreshold.setValue(-0.01)
        oper5d.SmootherSigma.setValue({'z': 0.0, 'y': 0.0, 'x': 0.0})
        oper5d.Channel.setValue(0)
        oper5d.CoreChannel.setValue(0)
        oper5d.CurOperator.setValue(self.curOperator)

        out5d = oper5d.Output[:].wait()
        numpy.testing.assert_array_equal(out5d.shape, self.data5d.shape)

        # the image should be white, because of negative threshold
        assert numpy.all(out5d > 0),\
            "{}% elements <= 0".format((out5d <= 0).sum()/float(out5d.size)*100)

        oper5d.LowThreshold.setValue(1.01)
        out5d = oper5d.Output[:].wait()

        # the image should be black, because of threshold larger than 1
        assert numpy.all(out5d == 0),\
            "{}% elements > 0".format((out5d > 0).sum()/float(out5d.size)*100)
예제 #23
0
    def testBasic(self):
        tmpdir = tempfile.mkdtemp()
        try:
            filepath = tmpdir + "/random_data.klb"
            shape = (1, 1, 30, 40, 50)
            data_tczyx = np.indices(shape).sum(0).astype(np.uint8)
            pyklb.writefull(data_tczyx,
                            filepath,
                            blocksize_xyzct=np.array([10, 10, 10, 1, 1],
                                                     dtype=np.uint32))
            readback = pyklb.readroi(filepath, (0, 0, 0, 0, 0),
                                     np.array(shape) - 1)

            op = OpKlbReader(graph=Graph())
            op.FilePath.setValue(filepath)

            assert op.Output.meta.shape == shape
            assert op.Output.meta.dtype == np.uint8

            read_data = op.Output[:].wait()
            assert (read_data == data_tczyx).all()

        finally:
            shutil.rmtree(tmpdir)
예제 #24
0
    def testOpSelectLabels(self):
        op = OpSelectLabels(graph=Graph())

        small = numpy.asarray(
            [[0, 0, 0],
             [0, 1, 0],
             [0, 0, 0]]).astype(np.uint32)
        big = numpy.asarray(
            [[0, 1, 0],
             [1, 1, 1],
             [0, 1, 0]]).astype(np.uint32)

        small = vigra.taggedView(small[:,:,None], 'yxc')
        big = vigra.taggedView(big[:,:,None], 'yxc')

        op.BigLabels.setValue(big)
        op.SmallLabels.setValue(small)
        out = op.Output[...].wait()
        numpy.testing.assert_array_equal(out, big)

        op.BigLabels.setValue(big)
        op.SmallLabels.setValue(small*0)
        out = op.Output[...].wait()
        numpy.testing.assert_array_equal(out, big*0)
예제 #25
0
    def test_lzw_compressed_file(self):
        """
        This test is loosely related to
          https://github.com/ilastik/ilastik/issues/1415

        Tests whether lzw compressed tiff files can be read.
        """
        import os
        basepath = os.path.split(__file__)[0]
        compressed_tiff_file = '{}/data/inputdata/compressed_lzw.tiff'.format(
            basepath)
        # generate checker-board, as in the file
        data = numpy.zeros((10, 20, 3)).astype(numpy.uint8)
        for i in range(data.shape[0]):
            if i % 2 == 0:
                data[i, 1::2, :] = 255
            else:
                data[i, 0::2, :] = 255

        op = OpTiffReader(graph=Graph())
        op.Filepath.setValue(compressed_tiff_file)
        assert op.Output.ready()
        assert op.Output.meta.shape == data.shape
        assert_array_equal(data, op.Output[:].wait())
예제 #26
0
    def testReconnectWithoutRequest(self):
        vol = numpy.zeros((200, 100, 50), dtype=numpy.float32)
        vol1 = vigra.taggedView(vol, axistags='xyz')
        vol2 = vigra.taggedView(vol, axistags='zyx').withAxes(*'xyz')
        graph = Graph()

        opData1 = OpArrayPiper(graph=graph)
        opData1.Input.setValue(vol1)

        op = OpCompressedCache(graph=graph)
        op.Input.connect(opData1.Output)
        op.BlockShape.setValue((200, 100, 10))
        out = op.Output[...].wait().view(numpy.ndarray)

        assert (out == vol).all(), "Incorrect output!"

        op.BlockShape.setValue((50, 100, 10))

        # Older versions of OpCompressedCache threw an exception here because
        #  we tried to access the cache after changing the blockshape.
        # But in the current version, we claim that's okay.
        out = op.Output[...].wait()

        assert (out == vol).all(), "Incorrect output!"
예제 #27
0
    def testCleanup(self):
        try:
            CacheMemoryManager().disable()
            sampleData = numpy.indices((100, 200, 150),
                                       dtype=numpy.float32).sum(0)
            sampleData = vigra.taggedView(sampleData, axistags="xyz")

            graph = Graph()
            opData = OpArrayPiper(graph=graph)
            opData.Input.setValue(sampleData)

            op = OpCompressedCache(graph=graph)
            # logger.debug("Setting block shape...")
            op.BlockShape.setValue([100, 75, 50])
            op.Input.connect(opData.Output)
            x = op.Output[...].wait()
            op.Input.disconnect()
            r = weakref.ref(op)
            del op
            gc.collect()
            assert r(
            ) is None, "OpBlockedArrayCache was not cleaned up correctly"
        finally:
            CacheMemoryManager().enable()
예제 #28
0
        def testMargin(self):
            graph = Graph()
            vol = np.zeros((100, 110, 10), dtype=np.float32)
            # draw a big plus sign
            vol[50:70, :, :] = 1.0
            vol[:, 60:80, :] = 1.0
            vol = vigra.taggedView(vol, axistags='zyx').withAxes(*'tzyxc')
            labels = np.zeros((100, 110, 10), dtype=np.uint32)
            labels[45:75, 55:85, 3:4] = 1
            labels = vigra.taggedView(labels,
                                      axistags='zyx').withAxes(*'tzyxc')

            op = OpObjectsSegment(graph=graph)
            piper = OpArrayPiper(graph=graph)
            piper.Input.setValue(vol)
            op.Prediction.connect(piper.Output)
            op.LabelImage.setValue(labels)

            # without margin
            op.MarginZYX.setValue(np.asarray((0, 0, 0)))
            out = op.Output[...].wait()
            out = vigra.taggedView(out, axistags=op.Output.meta.axistags)
            out = out.withAxes(*'zyx')
            vol = vol.withAxes(*'zyx')
            assert_array_equal(out[50:70, 60:80, 3] > 0,
                               vol[50:70, 60:80, 3] > .5)
            assert np.all(out[:45, ...] == 0)

            # with margin
            op.MarginZYX.setValue(np.asarray((5, 5, 0)))
            out = op.Output[...].wait()
            out = vigra.taggedView(out, axistags=op.Output.meta.axistags)
            out = out.withAxes(*'zyx')
            assert_array_equal(out[45:75, 55:85, 3] > 0,
                               vol[45:75, 55:85, 3] > .5)
            assert np.all(out[:40, ...] == 0)
예제 #29
0
 def setUp(self):
     self.g = Graph()
     self.op = OpOuter(graph=self.g)
예제 #30
0
        non_singleton_dims = filter(lambda (k, v): k != 'c' and v > 1,
                                    tagged_shape.items())
        assert len(non_singleton_dims) <= 2, \
            "Image to export must have no more than 2 non-singleton dimensions.\n"\
            "You are attempting to export a {}D result into a 2D file format."\
            .format( len(non_singleton_dims) )

        data = self._opExportToArray.run_export_to_array()
        data = vigra.taggedView(data, self.Input.meta.axistags)
        data = data.squeeze()
        if len(data.shape) == 1 or len(
                data.shape) == 2 and data.axistags.channelIndex < 2:
            data = data[numpy.newaxis, :]
        assert len(data.shape) == 2 or (len(data.shape) == 3 and data.axistags.channelIndex < 3), \
            "Image has shape {}, channelIndex is {}".format(data.shape, data.axistags.channelIndex)

        vigra.impex.writeImage(data, self.Filepath.value)


if __name__ == "__main__":
    a = numpy.random.random((1, 100, 1, 100, 1)) * 255
    a = a.astype(numpy.uint8)
    a = vigra.taggedView(a, vigra.defaultAxistags('txyzc'))

    from lazyflow.graph import Graph
    op = OpExport2DImage(graph=Graph())
    op.Input.setValue(a)
    op.Filepath.setValue('/tmp/test.png')

    op.run_export()
예제 #31
0
class TestSlot_notifyDisconnect(object):

    def setUp(self):
        self.g = Graph()

    def tearDown(self):
        self.g.stopGraph()

    def test_disconnect(self):
        # test that the notifyConnect callback is called
        # when the slot is connected
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        # check the disconnect callback is called upon disconnect
        opa.Input1.connect(ops.Output1)
        opa.Input1.notifyDisconnect(callBack)
        opa.Input1.disconnect()
        assert upval[0] == True

        # check the disconnect callback is called upon reconnect
        opa.Input1.connect(ops.Output1)
        upval[0] = False
        opa.Input1.connect(ops.Output2)
        assert upval[0] == True

        # check the disconnect callback is called upon setValue when being already connected
        opa.Input1.connect(ops.Output1)
        upval[0] = False
        opa.Input1.disconnect()
        opa.Input1.setValue(19)
        assert upval[0] == True

    def test_no_disconnect(self):
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        opa.Input1.notifyDisconnect(callBack)

        # check the disconnect callback is not called when reconnecting to the same slot
        opa.Input1.connect(ops.Output1)
        upval[0] = False
        opa.Input1.connect(ops.Output1)
        assert upval[0] == False

        # check the disconnect callback is not called when setting the same value again
        opa.Input1.disconnect()
        opa.Input1.setValue(10)
        upval[0] = False
        opa.Input1.setValue(10)
        assert upval[0] == False

    def test_unregister_disconnect(self):
        # check that unregistering a disconnect callback works
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        opa.Input1.connect(ops.Output1)

        opa.Input1.notifyDisconnect(callBack)
        opa.Input1.unregisterDisconnect(callBack)

        opa.Input1.disconnect()

        assert upval[0] == False
예제 #32
0
            shape = tuple(self._slot.meta.shape)
            axes = "".join(self._slot.meta.getAxisKeys())
            dtype = self._slot.meta.dtype.__name__
        else:
            shape = axes = dtype = ""

        if not sip.isdeleted(self.shapeEdit):
            self.shapeEdit.setText(str(shape))
            self.axisOrderEdit.setText(axes)
            self.dtypeEdit.setText(dtype)


if __name__ == "__main__":
    import numpy
    import vigra
    from PyQt4.QtGui import QApplication
    from lazyflow.graph import Graph
    from lazyflow.operators import OpArrayCache

    data = numpy.zeros((10, 20, 30, 3), dtype=numpy.float32)
    data = vigra.taggedView(data, 'zyxc')

    op = OpArrayCache(graph=Graph())
    op.Input.setValue(data)

    app = QApplication([])
    w = SlotMetaInfoDisplayWidget(None)
    w.initSlot(op.Output)
    w.show()
    app.exec_()
예제 #33
0
    # when the dot happen to be in the centre of the movable squere in the
    # image then we show a one on the top left corner
    # ===========================================================================
    from ilastik.widgets.boxListView import BoxListView
    from PyQt5.QtWidgets import QWidget

    app = QApplication([])

    boxListModel = BoxListModel()

    h, w = (500, 500)

    LV = BoxListView()
    LV.setModel(boxListModel)
    LV._table.setShowGrid(True)
    g = Graph()

    cron = QTimer()
    cron.start(500 * 100)

    op = OpArrayPiper2(graph=g)  # Generate random noise
    shape = (1, w, h, 1, 1)

    # array = np.random.randint(0,255,500*500).reshape(shape).astype(np.uint8)
    import scipy

    array = scipy.misc.lena().astype(np.uint8)
    array = vigra.sampling.resize(array.astype(np.float32), (h, w)).reshape(shape).astype(np.uint8)
    op.Input.setValue(array)

    def do():
예제 #34
0
    def __init__( self, shell, headless, workflow_cmdline_args, project_creation_args, *args, **kwargs ):
        graph = kwargs['graph'] if 'graph' in kwargs else Graph()
        if 'graph' in kwargs: del kwargs['graph']

        super(StructuredTrackingWorkflowBase, self).__init__(shell, headless, workflow_cmdline_args, project_creation_args, graph=graph, *args, **kwargs)

        data_instructions = 'Use the "Raw Data" tab to load your intensity image(s).\n\n'
        if self.fromBinary:
            data_instructions += 'Use the "Binary Image" tab to load your segmentation image(s).'
        else:
            data_instructions += 'Use the "Prediction Maps" tab to load your pixel-wise probability image(s).'

        # Create applets
        self.dataSelectionApplet = DataSelectionApplet(self,
            "Input Data",
            "Input Data",
            batchDataGui=False,
            forceAxisOrder=['txyzc'],
            instructionText=data_instructions,
            max_lanes=1)

        opDataSelection = self.dataSelectionApplet.topLevelOperator
        if self.fromBinary:
            opDataSelection.DatasetRoles.setValue( ['Raw Data', 'Binary Image'] )
        else:
            opDataSelection.DatasetRoles.setValue( ['Raw Data', 'Prediction Maps'] )

        if not self.fromBinary:
            self.thresholdTwoLevelsApplet = ThresholdTwoLevelsApplet( self,"Threshold and Size Filter","ThresholdTwoLevels" )

        self.divisionDetectionApplet = ObjectClassificationApplet(workflow=self,
                                                                     name="Division Detection (optional)",
                                                                     projectFileGroupName="DivisionDetection",
                                                                     selectedFeatures=configConservation.selectedFeaturesDiv)

        self.cellClassificationApplet = ObjectClassificationApplet(workflow=self,
                                                                     name="Object Count Classification",
                                                                     projectFileGroupName="CountClassification",
                                                                     selectedFeatures=configConservation.selectedFeaturesObjectCount)

        self.trackingFeatureExtractionApplet = TrackingFeatureExtractionApplet(name="Object Feature Computation",workflow=self, interactive=False)

        self.objectExtractionApplet = ObjectExtractionApplet(name="Object Feature Computation",workflow=self, interactive=False)

        self.annotationsApplet = AnnotationsApplet( name="Training", workflow=self )
        opAnnotations = self.annotationsApplet.topLevelOperator

        self.trackingApplet = StructuredTrackingApplet( name="Tracking - Structured Learning", workflow=self )
        opStructuredTracking = self.trackingApplet.topLevelOperator

        if SOLVER=="CPLEX" or SOLVER=="GUROBI":
            self._solver="ILP"
        elif SOLVER=="DPCT":
            self._solver="Flow-based"
        else:
            self._solver=None
        opStructuredTracking._solver = self._solver

        self.default_tracking_export_filename = '{dataset_dir}/{nickname}-tracking_exported_data.csv'
        self.dataExportTrackingApplet = TrackingBaseDataExportApplet(self, "Tracking Result Export",default_export_filename=self.default_tracking_export_filename)
        opDataExportTracking = self.dataExportTrackingApplet.topLevelOperator
        opDataExportTracking.SelectionNames.setValue( ['Tracking-Result', 'Merger-Result', 'Object-Identities'] )
        opDataExportTracking.WorkingDirectory.connect( opDataSelection.WorkingDirectory )
        self.dataExportTrackingApplet.set_exporting_operator(opStructuredTracking)
        self.dataExportTrackingApplet.prepare_lane_for_export = self.prepare_lane_for_export
        self.dataExportTrackingApplet.post_process_lane_export = self.post_process_lane_export

        # configure export settings
        settings = {'file path': self.default_tracking_export_filename, 'compression': {}, 'file type': 'h5'}
        selected_features = ['Count', 'RegionCenter', 'RegionRadii', 'RegionAxes']
        opStructuredTracking.ExportSettings.setValue( (settings, selected_features) )

        self._applets = []
        self._applets.append(self.dataSelectionApplet)
        if not self.fromBinary:
            self._applets.append(self.thresholdTwoLevelsApplet)
        self._applets.append(self.trackingFeatureExtractionApplet)
        self._applets.append(self.divisionDetectionApplet)

        self.batchProcessingApplet = BatchProcessingApplet(self, "Batch Processing", self.dataSelectionApplet, self.dataExportTrackingApplet)

        self._applets.append(self.cellClassificationApplet)
        self._applets.append(self.objectExtractionApplet)
        self._applets.append(self.annotationsApplet)
        self._applets.append(self.trackingApplet)
        self._applets.append(self.dataExportTrackingApplet)

        if self.divisionDetectionApplet:
            opDivDetection = self.divisionDetectionApplet.topLevelOperator
            opDivDetection.SelectedFeatures.setValue(configConservation.selectedFeaturesDiv)
            opDivDetection.LabelNames.setValue(['Not Dividing', 'Dividing'])
            opDivDetection.AllowDeleteLabels.setValue(False)
            opDivDetection.AllowAddLabel.setValue(False)
            opDivDetection.EnableLabelTransfer.setValue(False)

        opCellClassification = self.cellClassificationApplet.topLevelOperator
        opCellClassification.SelectedFeatures.setValue(configConservation.selectedFeaturesObjectCount )
        opCellClassification.SuggestedLabelNames.setValue( ['False Detection',] + [str(1) + ' Object'] + [str(i) + ' Objects' for i in range(2,10) ] )
        opCellClassification.AllowDeleteLastLabelOnly.setValue(True)
        opCellClassification.EnableLabelTransfer.setValue(False)

        if workflow_cmdline_args:

            if '--testFullAnnotations' in workflow_cmdline_args:
                self.testFullAnnotations = True
            else:
                self.testFullAnnotations = False

            self._data_export_args, unused_args = self.dataExportTrackingApplet.parse_known_cmdline_args( workflow_cmdline_args )
            self._batch_input_args, unused_args = self.batchProcessingApplet.parse_known_cmdline_args( workflow_cmdline_args )
        else:
            unused_args = None
            self._data_export_args = None
            self._batch_input_args = None
            self.testFullAnnotations = False

        if unused_args:
            logger.warning("Unused command-line args: {}".format( unused_args ))
예제 #35
0
    def __init__(self, shell, headless, workflow_cmdline_args,
                 project_creation_args, *args, **kwargs):

        # Create a graph to be shared by all operators
        graph = Graph()
        super(NNClassificationWorkflow, self).__init__(shell,
                                                       headless,
                                                       workflow_cmdline_args,
                                                       project_creation_args,
                                                       graph=graph,
                                                       *args,
                                                       **kwargs)
        self._applets = []
        self._workflow_cmdline_args = workflow_cmdline_args
        # Parse workflow-specific command-line args
        parser = argparse.ArgumentParser()
        # parser.add_argument('--print-labels-by-slice', help="Print the number of labels for each Z-slice of each image.", action="store_true")

        # Parse the creation args: These were saved to the project file when this project was first created.
        parsed_creation_args, unused_args = parser.parse_known_args(
            project_creation_args)

        # Parse the cmdline args for the current session.
        parsed_args, unused_args = parser.parse_known_args(
            workflow_cmdline_args)
        # self.print_labels_by_slice = parsed_args.print_labels_by_slice

        data_instructions = (
            "Select your input data using the 'Raw Data' tab shown on the right.\n\n"
            "Power users: Optionally use the 'Prediction Mask' tab to supply a binary image that tells ilastik where it should avoid computations you don't need."
        )

        # Applets for training (interactive) workflow
        self.dataSelectionApplet = self.createDataSelectionApplet()
        opDataSelection = self.dataSelectionApplet.topLevelOperator

        # see role constants, above
        opDataSelection.DatasetRoles.setValue(
            NNClassificationWorkflow.ROLE_NAMES)

        self.nnClassificationApplet = NNClassApplet(self, "NNClassApplet")

        self.dataExportApplet = NNClassificationDataExportApplet(
            self, "Data Export")

        # Configure global DataExport settings
        opDataExport = self.dataExportApplet.topLevelOperator
        opDataExport.WorkingDirectory.connect(opDataSelection.WorkingDirectory)
        opDataExport.SelectionNames.setValue(self.EXPORT_NAMES)

        self.batchProcessingApplet = BatchProcessingApplet(
            self, "Batch Processing", self.dataSelectionApplet,
            self.dataExportApplet)

        # Expose for shell
        self._applets.append(self.dataSelectionApplet)
        self._applets.append(self.nnClassificationApplet)
        self._applets.append(self.dataExportApplet)
        self._applets.append(self.batchProcessingApplet)

        if unused_args:
            # We parse the export setting args first.  All remaining args are considered input files by the input applet.
            self._batch_export_args, unused_args = self.dataExportApplet.parse_known_cmdline_args(
                unused_args)
            self._batch_input_args, unused_args = self.batchProcessingApplet.parse_known_cmdline_args(
                unused_args)
        else:
            self._batch_input_args = None
            self._batch_export_args = None

        if unused_args:
            logger.warn("Unused command-line args: {}".format(unused_args))
예제 #36
0
        self.progressSignal(100)

    def propagateDirty(self, slot, subindex, roi):
        # The output from this operator isn't generally connected to other operators.
        # If someone is using it that way, we'll assume that the user wants to know that
        # the input image has become dirty and may need to be written to disk again.
        self.WriteImage.setDirty(slice(None))


if __name__ == "__main__":
    from lazyflow.graph import Graph
    import h5py
    import sys

    traceLogger.addHandler(logging.StreamHandler(sys.stdout))
    traceLogger.setLevel(logging.DEBUG)
    traceLogger.debug("HELLO")

    f = h5py.File("/tmp/flyem_sample_stack.h5", "r")
    internalPath = "volume/data"

    # OpStackToH5Writer
    graph = Graph()
    opStackToH5 = OpStackToH5Writer()
    opStackToH5.GlobString.setValue("/tmp/flyem_sample_stack/*.png")
    opStackToH5.hdf5Group.setValue(f)
    opStackToH5.hdf5Path.setValue(internalPath)

    success = opStackToH5.WriteImage.value
    assert success
예제 #37
0
def generate_trained_project_file(new_project_path,
                                  raw_data_paths,
                                  label_data_paths,
                                  feature_selections,
                                  classifier_factory=None):
    """
    Create a new project file from scratch, add the given raw data files,
    inject the corresponding labels, configure the given feature selections,
    and (if provided) override the classifier type ('factory').

    Finally, request the classifier object from the pipeline (which forces training),
    and save the project.

    new_project_path: Where to save the new project file
    raw_data_paths: A list of paths to the raw data images to train with
    label_data_paths: A list of paths to the label image data to train with
    feature_selections: A matrix of bool, representing the selected features
    classifier_factory: Override the classifier type.  Must be a subclass of either:
                        - lazyflow.classifiers.LazyflowVectorwiseClassifierFactoryABC
                        - lazyflow.classifiers.LazyflowPixelwiseClassifierFactoryABC
    """
    assert len(raw_data_paths) == len(
        label_data_paths
    ), "Number of label images must match number of raw images."

    import ilastik_main
    from ilastik.workflows.pixelClassification import PixelClassificationWorkflow
    from lazyflow.graph import Graph
    from lazyflow.operators.ioOperators import OpInputDataReader
    from lazyflow.roi import roiToSlice, roiFromShape

    ##
    ## CREATE PROJECT
    ##

    # Manually configure the arguments to ilastik, as if they were parsed from the command line.
    # (Start with empty args and fill in below.)
    ilastik_args = ilastik_main.parse_args([])
    ilastik_args.new_project = new_project_path
    ilastik_args.headless = True
    ilastik_args.workflow = "Pixel Classification"

    shell = ilastik_main.main(ilastik_args)
    assert isinstance(shell.workflow, PixelClassificationWorkflow)

    ##
    ## CONFIGURE GRAYSCALE INPUT
    ##

    data_selection_applet = shell.workflow.dataSelectionApplet

    # To configure data selection, start with empty cmdline args and manually fill them in
    data_selection_args, _ = data_selection_applet.parse_known_cmdline_args(
        [], PixelClassificationWorkflow.ROLE_NAMES)
    data_selection_args.raw_data = raw_data_paths
    data_selection_args.preconvert_stacks = True

    # Simplest thing here is to configure using cmd-line interface
    data_selection_applet.configure_operator_with_parsed_args(
        data_selection_args)

    ##
    ## APPLY FEATURE MATRIX (from matrix above)
    ##

    opFeatures = shell.workflow.featureSelectionApplet.topLevelOperator
    opFeatures.Scales.setValue(ScalesList)
    opFeatures.FeatureIds.setValue(FeatureIds)
    opFeatures.SelectionMatrix.setValue(feature_selections)

    ##
    ## CUSTOMIZE CLASSIFIER TYPE
    ##

    opPixelClassification = shell.workflow.pcApplet.topLevelOperator
    if classifier_factory is not None:
        opPixelClassification.ClassifierFactory.setValue(classifier_factory)

    ##
    ## READ/APPLY LABEL VOLUMES
    ##

    # Read each label volume and inject the label data into the appropriate training slot
    cwd = os.getcwd()
    max_label_class = 0
    for lane, label_data_path in enumerate(label_data_paths):
        graph = Graph()
        opReader = OpInputDataReader(graph=graph)
        try:
            opReader.WorkingDirectory.setValue(cwd)
            opReader.FilePath.setValue(label_data_path)

            print("Reading label volume: {}".format(label_data_path))
            label_volume = opReader.Output[:].wait()
        finally:
            opReader.cleanUp()

        raw_shape = opPixelClassification.InputImages[lane].meta.shape
        if label_volume.ndim != len(raw_shape):
            # Append a singleton channel axis
            assert label_volume.ndim == len(raw_shape) - 1
            label_volume = label_volume[..., None]

        # Auto-calculate the max label value
        max_label_class = max(max_label_class, label_volume.max())

        print("Applying label volume to lane #{}".format(lane))
        entire_volume_slicing = roiToSlice(*roiFromShape(label_volume.shape))
        opPixelClassification.LabelInputs[lane][
            entire_volume_slicing] = label_volume

    assert max_label_class > 1, "Not enough label classes were found in your label data."
    label_names = list(map(str, list(range(max_label_class))))
    opPixelClassification.LabelNames.setValue(label_names)

    ##
    ## TRAIN CLASSIFIER
    ##

    # Make sure the caches in the pipeline are not 'frozen'.
    # (This is the equivalent of 'live update' mode in the GUI.)
    opPixelClassification.FreezePredictions.setValue(False)

    # Request the classifier object from the pipeline.
    # This forces the pipeline to produce (train) the classifier.
    _ = opPixelClassification.Classifier.value

    ##
    ## SAVE PROJECT
    ##

    # save project file (includes the new classifier).
    shell.projectManager.saveProject(force_all_save=False)
예제 #38
0
class TestSlot_notifyConnect(object):

    def setUp(self):
        self.g = Graph()

    def tearDown(self):
        self.g.stopGraph()

    def test_connect(self):
        # test that the notifyConnect callback is called
        # when the slot is connected
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)
        opa.Input2.connect(ops.Output2)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        # check the connect callback is called
        opa.Input1._notifyConnect(callBack)
        opa.Input1.connect(ops.Output1)
        assert upval[0] == True


        # check the connect callback is called for a slot with default value
        upval[0] = False
        opa.Input3._notifyConnect(callBack)
        opa.Input3.connect(ops.Output3)
        assert upval[0] == True


        # check the connect callback is called for a multi inputslot
        upval[0] = False
        opa.Input4._notifyConnect(callBack)
        opa.Input4.connect(ops.Output4)
        assert upval[0] == True


    def test_no_connect(self):
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        opa.Input1._notifyConnect(callBack)

        # check the connect callback is not called when reconnecting to the same slot
        opa.Input1.connect(ops.Output1)
        upval[0] = False
        opa.Input1.connect(ops.Output1)
        assert upval[0] == False

        # check the connect callback is not called when setting the same value again
        opa.Input1.disconnect()
        opa.Input1.setValue(10)
        upval[0] = False
        opa.Input1.setValue(10)
        assert upval[0] == False

    def test_unregister_connect(self):
        # check that unregistering a connect callback works
        ops = OpS(graph=self.g)
        opa = OpA(graph=self.g)

        upval = [False]

        def callBack(slot):
            upval[0] = True

        opa.Input1._notifyConnect(callBack)
        opa.Input1._unregisterConnect(callBack)

        opa.Input1.connect(ops.Output1)
        assert upval[0] == False
class Main(QMainWindow):    
    haveData        = pyqtSignal()
    dataReadyToView = pyqtSignal()
        
    def __init__(self, argv):
        QMainWindow.__init__(self)
        
        #Normalize the data if true
        self._normalize_data=True
        
        if 'notnormalize' in sys.argv:
            print sys.argv
            self._normalize_data=False
            sys.argv.remove('notnormalize')

        self.opPredict = None
        self.opTrain = None
        self.opThreshold = None
        self._colorTable16 = self._createDefault16ColorColorTable()
        
        #self.g = Graph(7, 2048*1024**2*5)
        self.g = Graph()
        self.fixableOperators = []
        
        self.featureDlg=None

        
        #The old ilastik provided the following scale names:
        #['Tiny', 'Small', 'Medium', 'Large', 'Huge', 'Megahuge', 'Gigahuge']
        #The corresponding scales are:
        self.featScalesList=[0.3, 0.7, 1, 1.6, 3.5, 5.0, 10.0]
        
        self.initUic()
        
        #if the filename was specified on command line, load it
        if len(sys.argv) >= 2:
            def loadFile():
                self._openFile(sys.argv[1:])
            QTimer.singleShot(0, loadFile)
        
    def setIconToViewMenu(self):
            self.actionOnly_for_current_view.setIcon(QIcon(self.editor.imageViews[self.editor._lastImageViewFocus]._hud.axisLabel.pixmap()))
        
    def initUic(self):
        p = os.path.split(__file__)[0]+'/'
        if p == "/": p = "."+p
        uic.loadUi(p+"MainWindow_cc.ui", self) 
        #connect the window and graph creation to the opening of the file
        self.actionOpen.triggered.connect(self.openFile)
        self.actionQuit.triggered.connect(qApp.quit)
        
        def toggleDebugPatches(show):
            self.editor.showDebugPatches = show
        def fitToScreen():
            shape = self.editor.posModel.shape
            for i, v in enumerate(self.editor.imageViews):
                s = list(copy.copy(shape))
                del s[i]
                v.changeViewPort(v.scene().data2scene.mapRect(QRectF(0,0,*s)))  
                
        def fitImage():
            if hasattr(self.editor, '_lastImageViewFocus'):
                self.editor.imageViews[self.editor._lastImageViewFocus].fitImage()
                
        def restoreImageToOriginalSize():
            if hasattr(self.editor, '_lastImageViewFocus'):
                self.editor.imageViews[self.editor._lastImageViewFocus].doScaleTo()
                    
        def rubberBandZoom():
            if hasattr(self.editor, '_lastImageViewFocus'):
                if not self.editor.imageViews[self.editor._lastImageViewFocus]._isRubberBandZoom:
                    self.editor.imageViews[self.editor._lastImageViewFocus]._isRubberBandZoom = True
                    self.editor.imageViews[self.editor._lastImageViewFocus]._cursorBackup = self.editor.imageViews[self.editor._lastImageViewFocus].cursor()
                    self.editor.imageViews[self.editor._lastImageViewFocus].setCursor(Qt.CrossCursor)
                else:
                    self.editor.imageViews[self.editor._lastImageViewFocus]._isRubberBandZoom = False
                    self.editor.imageViews[self.editor._lastImageViewFocus].setCursor(self.editor.imageViews[self.editor._lastImageViewFocus]._cursorBackup)
                
        
        def hideHud():
            if self.editor.imageViews[0]._hud.isVisible():
                hide = False
            else:
                hide = True
            for i, v in enumerate(self.editor.imageViews):
                v.hideHud(hide)
                
        def toggleSelectedHud():
            if hasattr(self.editor, '_lastImageViewFocus'):
                self.editor.imageViews[self.editor._lastImageViewFocus].toggleHud()
                
        def centerAllImages():
            for i, v in enumerate(self.editor.imageViews):
                v.centerImage()
                
        def centerImage():
            if hasattr(self.editor, '_lastImageViewFocus'):
                self.editor.imageViews[self.editor._lastImageViewFocus].centerImage()
                self.actionOnly_for_current_view.setEnabled(True)
        
        self.actionCenterAllImages.triggered.connect(centerAllImages)
        self.actionCenterImage.triggered.connect(centerImage)
        self.actionToggleAllHuds.triggered.connect(hideHud)
        self.actionToggleSelectedHud.triggered.connect(toggleSelectedHud)
        self.actionShowDebugPatches.toggled.connect(toggleDebugPatches)
        self.actionFitToScreen.triggered.connect(fitToScreen)
        self.actionFitImage.triggered.connect(fitImage)
        self.actionReset_zoom.triggered.connect(restoreImageToOriginalSize)
        self.actionRubberBandZoom.triggered.connect(rubberBandZoom)
        
        self.haveData.connect(self.initGraph)
        self.dataReadyToView.connect(self.initEditor)
        
        self.layerstack = LayerStackModel()
        
        model = LabelListModel()
        self.labelListView.setModel(model)
        self.labelListModel=model
        
        self.labelListModel.rowsAboutToBeRemoved.connect(self.onLabelAboutToBeRemoved)
        self.labelListModel.labelSelected.connect(self.switchLabel)
        
        def onDataChanged(topLeft, bottomRight):
            firstRow = topLeft.row()
            lastRow  = bottomRight.row()
        
            firstCol = topLeft.column()
            lastCol  = bottomRight.column()
            
            if lastCol == firstCol == 0:
                assert(firstRow == lastRow) #only one data item changes at a time

                #in this case, the actual data (for example color) has changed
                self.switchColor(firstRow+1, self.labelListModel[firstRow].color)
                self.editor.scheduleSlicesRedraw()
            else:
                #this column is used for the 'delete' buttons, we don't care
                #about data changed here
                pass
            
        self.labelListModel.dataChanged.connect(onDataChanged)
        
        self.AddLabelButton.clicked.connect(self.addLabel)
        
        self.SelectFeaturesButton.clicked.connect(self.onFeatureButtonClicked)
        self.StartClassificationButton.clicked.connect(self.startClassification)        
        self.StartClassificationButton.setEnabled(False)

        self.checkInteractive.setEnabled(False)
        self.checkInteractive.toggled.connect(self.toggleInteractive)   

        self.interactionComboBox.currentIndexChanged.connect(self.changeInteractionMode)
        self.interactionComboBox.setEnabled(False)

        self.AddThresholdButton.clicked.connect(self.addThresholdOperator)
        self.AddThresholdButton.setEnabled(False)
        self.CCButton.clicked.connect(self.addCCOperator)
        self.CCButton.setEnabled(False)

        self._initFeatureDlg()
        
    def toggleInteractive(self, checked):
        print "toggling interactive mode to '%r'" % checked
        
        #Check if the number of labels in the layer stack is equals to the number of Painted labels
        if checked==True:
            labels =numpy.unique(numpy.asarray(self.opLabels.outputs["nonzeroValues"][:].allocate().wait()[0]))           
            nPaintedLabels=labels.shape[0]
            nLabelsLayers = self.labelListModel.rowCount()
            selectedFeatures = numpy.asarray(self.featureDlg.featureTableWidget.createSelectedFeaturesBoolMatrix())
            
            if nPaintedLabels!=nLabelsLayers:
                self.checkInteractive.setCheckState(0)
                mexBox=QMessageBox()
                mexBox.setText("Did you forget to paint some labels?")
                mexBox.setInformativeText("Painted Labels %d \nNumber Active Labels Layers %d"%(nPaintedLabels,self.labelListModel.rowCount()))
                mexBox.exec_()
                return
            if (selectedFeatures==0).all():
                self.checkInteractive.setCheckState(0)
                mexBox=QMessageBox()
                mexBox.setText("The are no features selected ")
                mexBox.exec_()
                return
        else:
            self.g.stopGraph()
            self.g.resumeGraph()
                
        self.AddLabelButton.setEnabled(not checked)
        self.SelectFeaturesButton.setEnabled(not checked)
        for o in self.fixableOperators:
            o.inputs["fixAtCurrent"].setValue(not checked)
        self.labelListModel.allowRemove(not checked)
        
        self.editor.scheduleSlicesRedraw()

    def changeInteractionMode( self, index ):
        modes = {0: "navigation", 1: "brushing"}
        self.editor.setInteractionMode( modes[index] )
        self.interactionComboBox.setCurrentIndex(index)
        print "interaction mode switched to", modes[index]

    def switchLabel(self, row):
        print "switching to label=%r" % (self.labelListModel[row])
        #+1 because first is transparent
        #FIXME: shouldn't be just row+1 here
        self.editor.brushingModel.setDrawnNumber(row+1)
        self.editor.brushingModel.setBrushColor(self.labelListModel[row].color)
        
    def switchColor(self, row, color):
        print "label=%d changes color to %r" % (row, color)
        self.labellayer.colorTable[row]=color.rgba()
        self.editor.brushingModel.setBrushColor(color)
        self.editor.scheduleSlicesRedraw()
    
    def addLabel(self):
        color = QColor(numpy.random.randint(0,255), numpy.random.randint(0,255), numpy.random.randint(0,255))
        numLabels = len(self.labelListModel)
        if numLabels < len(self._colorTable16):
            color = self._colorTable16[numLabels]
        self.labellayer.colorTable.append(color.rgba())
        
        self.labelListModel.insertRow(self.labelListModel.rowCount(), Label("Label %d" % (self.labelListModel.rowCount() + 1), color))
        nlabels = self.labelListModel.rowCount()
        if self.opPredict is not None:
            print "Label added, changing predictions"
            #re-train the forest now that we have more labels
            self.opPredict.inputs['LabelsCount'].setValue(nlabels)
            self.addPredictionLayer(nlabels-1, self.labelListModel._labels[nlabels-1])
        
        #make the new label selected
        index = self.labelListModel.index(nlabels-1, 1)
        self.labelListModel._selectionModel.select(index, QItemSelectionModel.ClearAndSelect)
        
        #FIXME: this should watch for model changes   
        #drawing will be enabled when the first label is added  
        self.changeInteractionMode( 1 )
        self.interactionComboBox.setEnabled(True)
    
    def onLabelAboutToBeRemoved(self, parent, start, end):
        #the user deleted a label, reshape prediction and remove the layer
        #the interface only allows to remove one label at a time?
        
        nout = start-end+1
        ncurrent = self.labelListModel.rowCount()
        print "removing", nout, "out of ", ncurrent
        
        if self.opPredict is not None:
            self.opPredict.inputs['LabelsCount'].setValue(ncurrent-nout)
        for il in range(start, end+1):
            labelvalue = self.labelListModel._labels[il]
            self.removePredictionLayer(labelvalue)
            self.opLabels.inputs["deleteLabel"].setValue(il+1)
            self.editor.scheduleSlicesRedraw()
            
    
    def startClassification(self):
        if self.opTrain is None:
            #initialize all classification operators
            print "initializing classification..."
            opMultiL = Op5ToMulti(self.g)    
            opMultiL.inputs["Input0"].connect(self.opLabels.outputs["Output"])
            
            opMultiLblocks = Op5ToMulti(self.g)
            opMultiLblocks.inputs["Input0"].connect(self.opLabels.outputs["nonzeroBlocks"])
            self.opTrain = OpTrainRandomForestBlocked(self.g)
            self.opTrain.inputs['Labels'].connect(opMultiL.outputs["Outputs"])
            self.opTrain.inputs['Images'].connect(self.opFeatureCache.outputs["Output"])
            self.opTrain.inputs["nonzeroLabelBlocks"].connect(opMultiLblocks.outputs["Outputs"])
            self.opTrain.inputs['fixClassifier'].setValue(False)                
            
            opClassifierCache = OpArrayCache(self.g)
            opClassifierCache.inputs["Input"].connect(self.opTrain.outputs['Classifier'])
           
            ################## Prediction
            self.opPredict=OpPredictRandomForest(self.g)
            nclasses = self.labelListModel.rowCount()
            self.opPredict.inputs['LabelsCount'].setValue(nclasses)
            self.opPredict.inputs['Classifier'].connect(opClassifierCache.outputs['Output']) 
            self.opPredict.inputs['Image'].connect(self.opPF.outputs["Output"])

            pCache = OpSlicedBlockedArrayCache(self.g)
            pCache.inputs["fixAtCurrent"].setValue(False)
            pCache.inputs["innerBlockShape"].setValue(((1,256,256,1,2),(1,256,1,256,2),(1,1,256,256,2)))
            pCache.inputs["outerBlockShape"].setValue(((1,256,256,4,2),(1,256,4,256,2),(1,4,256,256,2)))
            pCache.inputs["Input"].connect(self.opPredict.outputs["PMaps"])
            self.pCache = pCache
  
            #add prediction results for all classes as separate channels
            for icl in range(nclasses):
                self.addPredictionLayer(icl, self.labelListModel._labels[icl])
        self.StartClassificationButton.setEnabled(False)
        self.checkInteractive.setEnabled(True)
        self.AddThresholdButton.setEnabled(True)
                                  
    def addPredictionLayer(self, icl, ref_label):
        
        selector=OpSingleChannelSelector(self.g)
        selector.inputs["Input"].connect(self.pCache.outputs['Output'])
        selector.inputs["Index"].setValue(icl)
                
        if self.checkInteractive.isChecked():
            self.pCache.inputs["fixAtCurrent"].setValue(False)
        else:
            self.pCache.inputs["fixAtCurrent"].setValue(True)
        
        predictsrc = LazyflowSource(selector.outputs["Output"][0])
        def srcName(newName):
            predictsrc.setObjectName("Prediction for %s" % ref_label.name)
        srcName("")
        
        predictLayer = AlphaModulatedLayer(predictsrc, tintColor=ref_label.color)
        predictLayer.nameChanged.connect(srcName)
        
        def setLayerColor(c):
            print "as the color of label '%s' has changed, setting layer's '%s' tint color to %r" % (ref_label.name, predictLayer.name, c)
            predictLayer.tintColor = c
        ref_label.colorChanged.connect(setLayerColor)
        def setLayerName(n):
            newName = "Prediction for %s" % ref_label.name
            print "as the name of label '%s' has changed, setting layer's '%s' name to '%s'" % (ref_label.name, predictLayer.name, newName)
            predictLayer.name = newName
        setLayerName(ref_label.name)
        ref_label.nameChanged.connect(setLayerName)
        
        predictLayer.ref_object = ref_label
        #make sure that labels (index = 0) stay on top!
        self.layerstack.insert(1, predictLayer )
        self.fixableOperators.append(self.pCache)
               
    def removePredictionLayer(self, ref_label):
        for il, layer in enumerate(self.layerstack):
            if layer.ref_object==ref_label:
                print "found the prediction", layer.ref_object, ref_label
                self.layerstack.removeRows(il, 1)
                break
    
    def addThresholdOperator(self):
        if self.opThreshold is None:
            self.opThreshold = OpThreshold(self.g)
            self.opThreshold.inputs["Input"].connect(self.pCache.outputs["Output"])
        #channel, value = ThresholdDlg(self.labelListModel._labels)
        channel = 0
        value = 0.5
        ref_label = self.labelListModel._labels[channel]
        self.opThreshold.inputs["Channel"].setValue(channel)
        self.opThreshold.inputs["Threshold"].setValue(value)
        threshsrc = LazyflowSource(self.opThreshold.outputs["Output"][0])
        
        threshsrc.setObjectName("Threshold for %s" % ref_label.name)
        transparent = QColor(0,0,0,0)
        white = QColor(255,255,255)
        colorTable = [transparent.rgba(), white.rgba()]
        threshLayer = ColortableLayer(threshsrc, colorTable = colorTable )
        threshLayer.name = "Threshold for %s" % ref_label.name
        self.layerstack.insert(1, threshLayer)
        self.CCButton.setEnabled(True)
        
    def addCCOperator(self):
        self.opCC = OpConnectedComponents(self.g)
        self.opCC.inputs["Input"].connect(self.opThreshold.outputs["Output"])
        #we shouldn't have to define these. But just in case...
        self.opCC.inputs["Neighborhood"].setValue(6)
        self.opCC.inputs["Background"].setValue(0)
        
        ccsrc = LazyflowSource(self.opCC.outputs["Output"][0])
        ccsrc.setObjectName("Connected Components")
        ctb = colortables.create_default_16bit()
        ctb.insert(0, QColor(0, 0, 0, 0).rgba()) # make background transparent
        ccLayer = ColortableLayer(ccsrc, ctb)
        ccLayer.name = "Connected Components"
        self.layerstack.insert(1, ccLayer)
        
            
    def openFile(self):
        fileNames = QFileDialog.getOpenFileNames(self, "Open Image", os.path.abspath(__file__), "Numpy and h5 files (*.npy *.h5)")
        if fileNames.count() == 0:
            return
        self._openFile(fileNames)
        
    def _openFile(self, fileNames):
        self.inputProvider = None
        fName, fExt = os.path.splitext(str(fileNames[0]))
        print "Opening Files %r" % fileNames
        if fExt=='.npy':
            fileName = fileNames[0]
            if len(fileNames)>1:
                print "WARNING: only the first file will be read, multiple file prediction not supported yet"
            fName, fExt = os.path.splitext(str(fileName))
            self.raw = numpy.load(str(fileName))
            self.min, self.max = numpy.min(self.raw), numpy.max(self.raw)
            self.inputProvider = OpArrayPiper(self.g)
            self.raw = self.raw.view(vigra.VigraArray)
            self.raw.axistags =  vigra.AxisTags(
                vigra.AxisInfo('t',vigra.AxisType.Time),
                vigra.AxisInfo('x',vigra.AxisType.Space),
                vigra.AxisInfo('y',vigra.AxisType.Space),
                vigra.AxisInfo('z',vigra.AxisType.Space),
                vigra.AxisInfo('c',vigra.AxisType.Channels))
            self.inputProvider.inputs["Input"].setValue(self.raw)
        elif fExt=='.h5':
            readerNew=OpH5ReaderBigDataset(self.g)
            
            
            readerNew.inputs["Filenames"].setValue(fileNames)
            readerNew.inputs["hdf5Path"].setValue("volume/data")

            readerCache =  OpSlicedBlockedArrayCache(self.g)
            readerCache.inputs["fixAtCurrent"].setValue(False)
            readerCache.inputs["innerBlockShape"].setValue(((1,256,256,1,2),(1,256,1,256,2),(1,1,256,256,2)))
            readerCache.inputs["outerBlockShape"].setValue(((1,256,256,4,2),(1,256,4,256,2),(1,4,256,256,2)))
            readerCache.inputs["Input"].connect(readerNew.outputs["Output"])

            self.inputProvider = OpArrayPiper(self.g)
            self.inputProvider.inputs["Input"].connect(readerCache.outputs["Output"])
        else:
            raise RuntimeError("opening filenames=%r not supported yet" % fileNames)
        
        self.haveData.emit()
       
    def initGraph(self):
        shape = self.inputProvider.outputs["Output"].shape
        srcs    = []
        minMax = []
        normalize = []
        
        print "* Data has shape=%r" % (shape,)
        
        #create a layer for each channel of the input:
        slicer=OpMultiArraySlicer2(self.g)
        slicer.inputs["Input"].connect(self.inputProvider.outputs["Output"])
        slicer.inputs["AxisFlag"].setValue('c')
       
        nchannels = shape[-1]
        for ich in xrange(nchannels):
            data=slicer.outputs['Slices'][ich][:].allocate().wait()
            #find the minimum and maximum value for normalization
            mm = (numpy.min(data), numpy.max(data))
            print "  - channel %d: min=%r, max=%r" % (ich, mm[0], mm[1])
            minMax.append(mm)
            if self._normalize_data:
                normalize.append(mm)
            else:
                normalize.append((0,255))
            layersrc = LazyflowSource(slicer.outputs['Slices'][ich], priority = 100)
            layersrc.setObjectName("raw data channel=%d" % ich)
            srcs.append(layersrc)
            
        #FIXME: we shouldn't merge channels automatically, but for now it's prettier
        layer1 = None
        if nchannels == 1:
            layer1 = GrayscaleLayer(srcs[0], range=minMax[0], normalize=normalize[0])
            print "  - showing raw data as grayscale"
        elif nchannels==2:
            layer1 = RGBALayer(red  = srcs[0], normalizeR=normalize[0],
                               green = srcs[1], normalizeG=normalize[1], range=minMax[0:2]+[(0,255), (0,255)])
            print "  - showing channel 1 as red, channel 2 as green"
        elif nchannels==3:
            layer1 = RGBALayer(red   = srcs[0], normalizeR=normalize[0],
                               green = srcs[1], normalizeG=normalize[1],
                               blue  = srcs[2], normalizeB=normalize[2],
                               range = minMax[0:3])
            print "  - showing channel 1 as red, channel 2 as green, channel 3 as blue"
        else:
            print "only 1,2 or 3 channels supported so far"
            return
        print
        
        layer1.name = "Input data"
        layer1.ref_object = None
        self.layerstack.append(layer1)
        
        opImageList = Op5ToMulti(self.g)    
        opImageList.inputs["Input0"].connect(self.inputProvider.outputs["Output"])
        
        #init the features operator
        opPF = OpPixelFeaturesPresmoothed(self.g)
        opPF.inputs["Input"].connect(opImageList.outputs["Outputs"])
        opPF.inputs["Scales"].setValue(self.featScalesList)
        self.opPF=opPF
        
        #Caches the features
        opFeatureCache = OpBlockedArrayCache(self.g)
        opFeatureCache.inputs["innerBlockShape"].setValue((1,32,32,32,16))
        opFeatureCache.inputs["outerBlockShape"].setValue((1,128,128,128,64))
        opFeatureCache.inputs["Input"].connect(opPF.outputs["Output"])
        opFeatureCache.inputs["fixAtCurrent"].setValue(False)  
        self.opFeatureCache=opFeatureCache
        
        
        self.initLabels()
        self.dataReadyToView.emit()
        
    def initLabels(self):
        #Add the layer to draw the labels, but don't add any labels
        shape=self.inputProvider.outputs["Output"].shape
        
        self.opLabels = OpBlockedSparseLabelArray(self.g)                                
        self.opLabels.inputs["shape"].setValue(shape[:-1] + (1,))
        self.opLabels.inputs["blockShape"].setValue((1, 32, 32, 32, 1))
        self.opLabels.inputs["eraser"].setValue(100)                
        
        self.labelsrc = LazyflowSinkSource(self.opLabels, self.opLabels.outputs["Output"], self.opLabels.inputs["Input"])
        self.labelsrc.setObjectName("labels")
        
        transparent = QColor(0,0,0,0)
        self.labellayer = ColortableLayer(self.labelsrc, colorTable = [transparent.rgba()] )
        self.labellayer.name = "Labels"
        self.labellayer.ref_object = None
        self.layerstack.append(self.labellayer)    
    
    def initEditor(self):
        shape=self.inputProvider.outputs["Output"].shape
        
        self.editor = VolumeEditor(self.layerstack, labelsink=self.labelsrc)
        self.editor.dataShape = shape

        self.editor.newImageView2DFocus.connect(self.setIconToViewMenu)
        #drawing will be enabled when the first label is added  
        self.editor.setInteractionMode( 'navigation' )
        self.volumeEditorWidget.init(self.editor)
        model = self.editor.layerStack
        self.layerWidget.init(model)
        self.UpButton.clicked.connect(model.moveSelectedUp)
        model.canMoveSelectedUp.connect(self.UpButton.setEnabled)
        self.DownButton.clicked.connect(model.moveSelectedDown)
        model.canMoveSelectedDown.connect(self.DownButton.setEnabled)
        self.DeleteButton.clicked.connect(model.deleteSelected)
        model.canDeleteSelected.connect(self.DeleteButton.setEnabled)     
        
        self.opLabels.inputs["eraser"].setValue(self.editor.brushingModel.erasingNumber)      
    
    def _createDefault16ColorColorTable(self):
        c = []
        c.append(QColor(0, 0, 255))
        c.append(QColor(255, 255, 0))
        c.append(QColor(255, 0, 0))
        c.append(QColor(0, 255, 0))
        c.append(QColor(0, 255, 255))
        c.append(QColor(255, 0, 255))
        c.append(QColor(255, 105, 180)) #hot pink
        c.append(QColor(102, 205, 170)) #dark aquamarine
        c.append(QColor(165,  42,  42)) #brown        
        c.append(QColor(0, 0, 128))     #navy
        c.append(QColor(255, 165, 0))   #orange
        c.append(QColor(173, 255,  47)) #green-yellow
        c.append(QColor(128,0, 128))    #purple
        c.append(QColor(192, 192, 192)) #silver
        c.append(QColor(240, 230, 140)) #khaki
        c.append(QColor(69, 69, 69))    # dark grey
        return c
    
    
    def onFeatureButtonClicked(self):
        self.featureDlg.show()
        def onDlgAccepted():
            self.StartClassificationButton.setEnabled(True)
        self.featureDlg.accepted.connect(onDlgAccepted)
    
    def _onFeaturesChosen(self):
        selectedFeatures = self.featureDlg.featureTableWidget.createSelectedFeaturesBoolMatrix()
        print "new feature set:", selectedFeatures
        self.opPF.inputs['Matrix'].setValue(numpy.asarray(selectedFeatures))
    
    def _initFeatureDlg(self):
        dlg = self.featureDlg = FeatureDlg()
        
        dlg.setWindowTitle("Features")
        dlg.createFeatureTable({"Features": [FeatureEntry("Gaussian smoothing"), \
                                             FeatureEntry("Laplacian of Gaussian"), \
                                             FeatureEntry("Structure Tensor Eigenvalues"), \
                                             FeatureEntry("Hessian of Gaussian EV"),  \
                                             FeatureEntry("Gaussian Gradient Magnitude"), \
                                             FeatureEntry("Difference Of Gaussian")]}, \
                               self.featScalesList)
        dlg.setImageToPreView(None)
        m = [[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[0,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0],[1,0,0,0,0,0,0]]
        dlg.featureTableWidget.setSelectedFeatureBoolMatrix(m)
        dlg.accepted.connect(self._onFeaturesChosen)
예제 #40
0
def testFullAllocate():

    nx = 5
    ny = 10
    nz = 2
    nc = 7
    stack = vigra.VigraArray((nx, ny, nz, nc), axistags=vigra.defaultAxistags('xyzc'))
    stack[...] = numpy.random.rand(nx, ny, nz, nc)

    g = Graph()

    #assume that the slicer works
    slicerX = OpMultiArraySlicer(graph=g)
    slicerX.inputs["Input"].setValue(stack)
    slicerX.inputs["AxisFlag"].setValue('x')

    #insert the x dimension
    stackerX = OpMultiArrayStacker(graph=g)
    stackerX.inputs["AxisFlag"].setValue('x')
    stackerX.inputs["AxisIndex"].setValue(0)
    stackerX.inputs["Images"].connect(slicerX.outputs["Slices"])

    newdata = stackerX.outputs["Output"][:].wait()
    assert_array_equal(newdata, stack.view(numpy.ndarray))

    print "1st part ok................."
    #merge stuff that already has an x dimension
    stack2 = vigra.VigraArray((nx-1, ny, nz, nc), axistags=vigra.defaultAxistags('xyzc'))
    stack2[...] = numpy.random.rand(nx-1, ny, nz, nc)

    opMulti = Op5ToMulti(graph=g)
    opMulti.inputs["Input0"].setValue(stack)
    opMulti.inputs["Input1"].setValue(stack2)

    #print "OPMULTI: ", len(opMulti.outputs["Outputs"])

    stackerX2 = OpMultiArrayStacker(graph=g)

    stackerX2.inputs["Images"].connect(opMulti.outputs["Outputs"])
    stackerX2.inputs["AxisFlag"].setValue('x')
    stackerX2.inputs["AxisIndex"].setValue(0)

    #print "STACKER: ", stackerX2.outputs["Output"].meta.shape

    newdata = stackerX2.outputs["Output"][:].wait()
    bothstacks = numpy.concatenate((stack, stack2), axis=0)
    assert_array_equal(newdata, bothstacks.view(numpy.ndarray))
    #print newdata.shape, bothstacks.shape

    print "2nd part ok................."
    #print "------------------------------------------------------------"
    #print "------------------------------------------------------------"
    #print "------------------------------------------------------------"
    ##### channel

    #assume that the slicer works
    slicerC = OpMultiArraySlicer(graph=g)
    slicerC.inputs["Input"].setValue(stack)
    slicerC.inputs["AxisFlag"].setValue('c')

    #insert the c dimension

    stackerC = OpMultiArrayStacker(graph=g)
    stackerC.inputs["AxisFlag"].setValue('c')
    stackerC.inputs["AxisIndex"].setValue(3)
    stackerC.inputs["Images"].connect(slicerC.outputs["Slices"])

    newdata = stackerC.outputs["Output"][:].wait()
    assert_array_equal(newdata, stack.view(numpy.ndarray))

    print "3rd part ok................."
    #print "STACKER: ", stackerC.outputs["Output"].meta.shape

    #merge stuff that already has an x dimension
    stack3 = vigra.VigraArray((nx, ny, nz, nc-1), axistags=vigra.defaultAxistags('xyzc'))
    stack3[...] = numpy.random.rand(nx, ny, nz, nc-1)

    opMulti = Op5ToMulti(graph=g)
    opMulti.inputs["Input0"].setValue(stack)
    opMulti.inputs["Input1"].setValue(stack3)

    stackerC2 = OpMultiArrayStacker(graph=g)
    stackerC2.inputs["AxisFlag"].setValue('c')
    stackerC2.inputs["AxisIndex"].setValue(3)
    stackerC2.inputs["Images"].connect(opMulti.outputs["Outputs"])

    newdata = stackerC2.outputs["Output"][:].wait()
    bothstacks = numpy.concatenate((stack, stack3), axis=3)
    assert_array_equal(newdata, bothstacks.view(numpy.ndarray))
    print "4th part ok................."

    g.finalize()
 def setUp(self):
     self.g = Graph()
     self.op = OpA(graph=self.g)
예제 #42
0
 def setUp(self):
     self.g = Graph()