def _resolveMergers(self, hypothesesGraph, model): ''' run merger resolution on the hypotheses graph which contains the current solution ''' logger.info("Resolving mergers.") parameters = self.Parameters.value withTracklets = parameters['withTracklets'] originalGraph = hypothesesGraph.referenceTraxelGraph if withTracklets else hypothesesGraph resolvedMergersDict = {} # Enable full graph computation for animal tracking workflow withFullGraph = False if 'withAnimalTracking' in parameters and parameters['withAnimalTracking']: # TODO: Setting this parameter outside of the track() function (on AnimalConservationTrackingWorkflow) is not desirable withFullGraph = True logger.info("Computing full graph on merger resolver (Only enabled on animal tracking workflow)") mergerResolver = IlastikMergerResolver(originalGraph, pluginPaths=self.pluginPaths, withFullGraph=withFullGraph) # Check if graph contains mergers, otherwise skip merger resolving if not mergerResolver.mergerNum: logger.info("Graph contains no mergers. Skipping merger resolving.") else: # Fit and refine merger nodes using a GMM # It has to be done per time-step in order to aviod loading the whole video on RAM traxelIdPerTimestepToUniqueIdMap, uuidToTraxelMap = getMappingsBetweenUUIDsAndTraxels(model) timesteps = [int(t) for t in traxelIdPerTimestepToUniqueIdMap.keys()] timesteps.sort() timeIndex = self.LabelImage.meta.axistags.index('t') for timestep in timesteps: roi = [slice(None) for i in range(len(self.LabelImage.meta.shape))] roi[timeIndex] = slice(timestep, timestep+1) roi = tuple(roi) labelImage = self.LabelImage[roi].wait() # Get coordinates for object IDs in label image. Used by GMM merger fit. objectIds = vigra.analysis.unique(labelImage[0,...,0]) maxObjectId = max(objectIds) coordinatesForIds = {} pool = RequestPool() for objectId in objectIds: pool.add(Request(partial(mergerResolver.getCoordinatesForObjectId, coordinatesForIds, labelImage[0, ..., 0], timestep, objectId))) # Run requests to get object ID coordinates pool.wait() # Fit mergers and store fit info in nodes if coordinatesForIds: mergerResolver.fitAndRefineNodesForTimestep(coordinatesForIds, maxObjectId, timestep) # Compute object features, re-run flow solver, update model and result, and get merger dictionary resolvedMergersDict = mergerResolver.run() return resolvedMergersDict