class TestPlugins(unittest.TestCase): def setUp(self): g = Graph() self.op = OpObjectExtraction(graph=g) # Raw image is arbitrary for our purposes. Just re-use the # label image rm = rawImage() rm = rm[:, :, :, 0:1, :] self.op.RawImage.setValue(rm) self.Features_standard = FEATURES self.Features_convex_hull = { "2D Convex Hull Features": { "HullVolume": {}, "DefectVolumeKurtosis": {} } } self.Features_skeleton = { "2D Skeleton Features": { "Diameter": {}, "Total Length": {} } } # self.op.Features.setValue(FEATURES) bm = binaryImage() bm = bm[:, :, :, 0:1, :] self.op.BinaryImage.setValue(bm) def test_plugins(self): self.op.Features.setValue(self.Features_standard) feats = self.op.RegionFeatures([0]).wait() self.op.Features.setValue(self.Features_convex_hull) feats = self.op.RegionFeatures([0]).wait() self.op.Features.setValue(self.Features_skeleton) feats = self.op.RegionFeatures([0]).wait()
class TestFeatureSelection(unittest.TestCase): 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<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() feats = self.extrOp.RegionFeatures([0, 1]).wait() assert len(feats) == rawimg.shape[0] for key in features["Standard Object Features"]: assert key in feats[0]["Standard Object Features"].keys() 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() def test_predict(self): rf = self.trainop.Classifier.value #pass a vector of 4 random features. vigra shouldn't complain #even though we computed more than 4 dummy_feats = np.zeros((1, 4), dtype=np.float32) dummy_feats[:] = 42 pred = rf.predict_probabilities(dummy_feats)
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)