def test_match_sources(self): """ (SourceModelComparison) matching sources """ s1 = Source([[10, 10], [10, 20]]) s2 = Source([[20, 20], [20, 30]]) s3 = Source([[20, 20], [20, 30]]) s4 = Source([[10, 10], [10, 20]]) s5 = Source([[15, 15], [15, 20]]) sm1 = SourceModel([s1, s2]) sm2 = SourceModel([s3, s4, s5]) assert (sm1.match(sm2) == [1, 0]) assert (sm2.match(sm1) == [1, 0, 0])
def merge(self, blocks, keys): """ Parameters ---------- blocks : list of lists of sources List of the sources found for each block; every block should be represented, with an empty list for blocks without any identified sources keys : List of BlockGroupingKeys or PaddedBlockGroupingKeys The keys for each of the blocks assocaited with the sources Returns ------- SourceModel containing the combined list of sources """ import itertools from thunder.rdds.imgblocks.blocks import PaddedBlockGroupingKey # recenter coordinates using the spatial key from each block # also subtract off initial padding if blocks were padded for ib, blk in enumerate(blocks): for source in blk: source.coordinates += keys[ib].spatialKey if isinstance(keys[0], PaddedBlockGroupingKey): for source in blk: source.coordinates -= keys[ib].padding[0] # flatten list of sources chain = itertools.chain.from_iterable(blocks) sources = list(chain) return SourceModel(sources)
def extract(self, im): from numpy import ones, concatenate from skimage.feature import peak_local_max from skimage.draw import circle # extract local peaks if im.ndim == 2: peaks = peak_local_max(im, min_distance=self.minDistance, num_peaks=self.maxSources).tolist() else: peaks = [] for i in range(0, im.shape[2]): tmp = peak_local_max(im[:, :, i], min_distance=self.minDistance, num_peaks=self.maxSources) peaks = peaks.append( concatenate((tmp, ones((len(tmp), 1)) * i), axis=1)) # construct circular regions from peak points def pointToCircle(center, radius): rr, cc = circle(center[0], center[1], radius) return array(zip(rr, cc)) # return circles as sources circles = [pointToCircle(p, self.radius) for p in peaks] return SourceModel([Source(c) for c in circles])
def generate(self, dims=(100, 200), centers=5, t=100, margin=35, sd=3, noise=0.1, npartitions=1, seed=None): from scipy.ndimage.filters import gaussian_filter, gaussian_filter1d from skimage.draw import circle from thunder.rdds.fileio.imagesloader import ImagesLoader from thunder.extraction.source import SourceModel random.seed(seed) if len(dims) != 2: raise Exception("Can only generate for two-dimensional sources.") if size(centers) == 1: n = centers xcenters = (dims[1] - margin) * random.random_sample(n) + margin / 2 ycenters = (dims[0] - margin) * random.random_sample(n) + margin / 2 centers = zip(xcenters, ycenters) else: centers = asarray(centers) n = len(centers) ts = [random.randn(t) for i in range(0, n)] ts = clip(asarray([gaussian_filter1d(vec, 5) for vec in ts]), 0, 1) for ii, tt in enumerate(ts): ts[ii] = (tt / tt.max()) * 2 allframes = [] for tt in range(0, t): frame = zeros(dims) for nn in range(0, n): base = zeros(dims) base[centers[nn][0], centers[nn][1]] = 1 img = gaussian_filter(base, sd) img = img / max(img) frame += img * ts[nn][tt] frame += clip(random.randn(dims[0], dims[1]) * noise, 0, inf) allframes.append(frame) def pointToCircle(center, radius): rr, cc = circle(center[0], center[1], radius) return array(zip(rr, cc)) r = round(sd * 1.5) sources = SourceModel([pointToCircle(c[::-1], r) for c in centers]) data = ImagesLoader(self.sc).fromArrays(allframes, npartitions).astype('float') if self.returnParams is True: return data, ts, sources else: return data
def merge(self, blocks, keys): """ Parameters ---------- blocks : list of lists of sources List of the sources found for each block; every block should be represented, with an empty list for blocks without any identified sources keys : List of PaddedBlockGroupingKeys The keys for each of the blocks assocaited with the sources Returns ------- SourceModel containing the combined list of merged sources """ import itertools import copy from thunder.rdds.imgblocks.blocks import PaddedBlockGroupingKey # check that keys are from padded blocks if not all(isinstance(k, PaddedBlockGroupingKey) for k in keys): raise ValueError( "All keys must correspond to padded blocks for this merger") blocks = copy.deepcopy(blocks) # re-center coordinates for ib, blk in enumerate(blocks): for source in blk: source.coordinates += keys[ib].spatialKey source.coordinates -= keys[ib].padding[0] # create lookup table from spatial keys -> block indices d = {} for i, k in enumerate(keys): d[k.spatialKey] = i # for all the sources in each block, # merge and delete its neighbors if # - they exceed an overlap threshold, and # - they are smaller than the current source for ib, blk in enumerate(blocks): neighbors = keys[ib].neighbors() for source in blk: for key in neighbors: ind = d[key] for other in blocks[ind][:]: if source.overlap( other ) > self.overlap and other.area < source.area: source.merge(other) blocks[ind].remove(other) chain = itertools.chain.from_iterable(blocks) sources = list(chain) return SourceModel(sources)
def merge(self, sources, keys, data=None): import itertools # recenter coordinates using the spatial key from each block for (i, sourceBlock) in enumerate(sources): for source in sourceBlock: source.coordinates += keys[i].spatialKey # flatten list of sources chain = itertools.chain.from_iterable(sources) sources = list(chain) return SourceModel(sources)
def clean(self, model): if not isinstance(model, SourceModel): raise Exception("Input must be Source Model, got %s" % type(model)) crit = lambda s: (s.area > self.minArea) and (s.area < self.maxArea) new = filter(crit, model.sources) if len(new) < 1: raise Exception( "Filtering removed all sources, try different parameters?") return SourceModel(new)
def test_min(self): """ (BasicCleaner) min area """ list1 = [Source(random.randn(20, 2)) for _ in range(10)] list2 = [Source(random.randn(5, 2)) for _ in range(20)] sources = list1 + list2 model = SourceModel(sources) c = BasicCleaner(minArea=10) newmodel = model.clean(c) assert (len(newmodel.sources) == 10)
def test_min_max(self): """ (BasicCleaner) min and max area """ list1 = [Source(random.randn(20, 2)) for _ in range(10)] list2 = [Source(random.randn(10, 2)) for _ in range(20)] list3 = [Source(random.randn(15, 2)) for _ in range(5)] sources = list1 + list2 + list3 model = SourceModel(sources) c = BasicCleaner(minArea=11, maxArea=19) newmodel = model.clean(c) assert (len(newmodel.sources) == 5)
def merge(self, blocks, keys, data=None): import itertools from thunder.rdds.imgblocks.blocks import PaddedBlockGroupingKey # recenter coordinates using the spatial key from each block # also subtract off initial padding if blocks were padded for i, blk in enumerate(blocks): for source in blk: source.coordinates += keys[i].spatialKey if isinstance(keys[0], PaddedBlockGroupingKey): for source in blk: source.coordinates -= keys[i].padding[0] # flatten list of sources chain = itertools.chain.from_iterable(blocks) sources = list(chain) return SourceModel(sources)