epicure.laptrack_overlaps
Tracking with laptrack package
Inspired from example https://github.com/yfukai/laptrack/blob/main/docs/examples/cell_segmentation.ipynb
1""" 2Tracking with laptrack package 3 4Inspired from example https://github.com/yfukai/laptrack/blob/main/docs/examples/cell_segmentation.ipynb 5""" 6 7import numpy as np 8import pandas as pd 9from skimage.measure import regionprops_table 10import laptrack 11from laptrack import OverLapTrack 12#from laptrack import datasets 13import epicure.Utils as ut 14from packaging.version import Version 15 16 17class LaptrackOverlaps(): 18 19 def __init__(self, track, epic): 20 self.splitting_cost = 1 21 self.cost_cutoff = 0.9 22 self.merging_cost = 1 23 self.track = track 24 self.epicure = epic 25 self.inspecting = False 26 self.suggesting = False 27 ## to handle difference in laptrack versions 28 self.version_over = Version(laptrack.__version__) >= Version("0.17.0") 29 30 31 def twoframes_track(self, img_labels, labels): 32 """ Do track between two frames, only track label """ 33 #start_time = time.time() 34 track_df, split_df, merge_df = self.perform_track( img_labels ) 35 #show_info("Performed in "+"{:.3f}".format((time.time()-start_time)/60)+" min") 36 37 track_ids = [None]*len(labels) 38 ## look for track id associated with label 39 for i, row in track_df.iterrows(): 40 frame = int(row["frame"]) 41 if frame == 1: 42 tid = int(row["track_id"]) 43 curlabel = int(row["label"]) 44 ind = labels.index(curlabel) 45 track_ids[ind] = tid 46 47 tracklabels = [None]*len(labels) 48 ## look for cell label associated with track_id in the first frame, if any 49 for i, row in track_df.iterrows(): 50 frame = int(row["frame"]) 51 tid = int(row["track_id"]) 52 if (tid in track_ids) and (frame==0): 53 ind = track_ids.index(tid) 54 label = int(row["label"]) 55 tracklabels[ind] = label 56 #show_info("Finished in "+"{:.3f}".format((time.time()-start_time)/60)+" min") 57 return tracklabels 58 59 60 def perform_track(self, labels): 61 """ Do tracking with laptrack module """ 62 63 ## handling eventual missing (empty) frame: 64 ind = [] 65 for i, lab in enumerate(labels): 66 if len(np.unique(lab)) == 1: 67 ind.append(i) 68 labels = [ lab for i, lab in enumerate(labels) if i not in ind] 69 70 if self.version_over: 71 ol = OverLapTrack( 72 cutoff=self.cost_cutoff, 73 metric_coefs=(1.0, 0.0, -1.0, 0.0, 0.0), 74 #gap_closing_metric_coefs=(1.0, -1.0, 0.0, 0.0, 0.0), 75 #gap_closing_max_frame_count=1, 76 gap_closing_cutoff=False, 77 merging_cutoff=self.merging_cost, 78 merging_metric_coefs=(1.0, 0.0, 0.0, -1.0, 0.0), 79 splitting_cutoff=self.splitting_cost, 80 splitting_metric_coefs=(1.0, 0.0, 0.0, 0.0, -1.0), 81 ) 82 else: 83 ol = OverLapTrack( 84 track_cost_cutoff=self.cost_cutoff, 85 track_dist_metric_coefs=(1.0, 0.0, -1.0, 0.0, 0.0), 86 #gap_closing_dist_metric_coefs=(1.0, -1.0, 0.0, 0.0, 0.0), 87 #gap_closing_max_frame_count=1, 88 gap_closing_cost_cutoff=False, 89 merging_cost_cutoff=self.merging_cost, 90 merging_dist_metric_coefs=(1.0, 0.0, 0.0, -1.0, 0.0), 91 splitting_cost_cutoff=self.splitting_cost, 92 splitting_dist_metric_coefs=(1.0, 0.0, 0.0, 0.0, -1.0), 93 ) 94 95 track_df, split_df, merge_df = ol.predict_overlap_dataframe(labels) 96 ## handle eventual missing frames 97 track_df = track_df.reset_index() 98 track_df["frame"] += np.searchsorted(sorted(ind), track_df["frame"], side='right') 99 100 track_df = track_df.reset_index() 101 return track_df, split_df, merge_df 102 103 def track_overlaps(self, labels): 104 """ Track all movie with laptrack overlap method """ 105 ut.napari_info("Starting tracking with laptrack Overlap...") 106 return self.perform_track( labels ) 107 108 109 def inspect_oneframe(self, graph, trackdf): 110 for track in np.unique(trackdf["track_id"]): 111 tr = trackdf[trackdf["track_id"] == track] 112 ## track is only on one frame, suspect 113 if len(np.unique(tr["frame"])) == 1: 114 # trackid + 1 as trackid starts as 0 115 pos = (tr.iloc[0]["frame"], int(tr.iloc[0]["centroid-0"]), int(tr.iloc[0]["centroid-1"])) 116 self.epicure.inspecting.add_event( pos, track+1, "tracking" ) 117 if self.track.suggesting: 118 if track in graph.keys(): 119 sisters = [] 120 refval = graph[track][0] 121 for key, val in graph.items(): 122 if val[0] == refval: 123 sisters.append( key ) 124 if len(sisters) == 2: 125 for sis in sisters: 126 self.epicure.add_suggestion( sis+1, refval+1 )
class
LaptrackOverlaps:
18class LaptrackOverlaps(): 19 20 def __init__(self, track, epic): 21 self.splitting_cost = 1 22 self.cost_cutoff = 0.9 23 self.merging_cost = 1 24 self.track = track 25 self.epicure = epic 26 self.inspecting = False 27 self.suggesting = False 28 ## to handle difference in laptrack versions 29 self.version_over = Version(laptrack.__version__) >= Version("0.17.0") 30 31 32 def twoframes_track(self, img_labels, labels): 33 """ Do track between two frames, only track label """ 34 #start_time = time.time() 35 track_df, split_df, merge_df = self.perform_track( img_labels ) 36 #show_info("Performed in "+"{:.3f}".format((time.time()-start_time)/60)+" min") 37 38 track_ids = [None]*len(labels) 39 ## look for track id associated with label 40 for i, row in track_df.iterrows(): 41 frame = int(row["frame"]) 42 if frame == 1: 43 tid = int(row["track_id"]) 44 curlabel = int(row["label"]) 45 ind = labels.index(curlabel) 46 track_ids[ind] = tid 47 48 tracklabels = [None]*len(labels) 49 ## look for cell label associated with track_id in the first frame, if any 50 for i, row in track_df.iterrows(): 51 frame = int(row["frame"]) 52 tid = int(row["track_id"]) 53 if (tid in track_ids) and (frame==0): 54 ind = track_ids.index(tid) 55 label = int(row["label"]) 56 tracklabels[ind] = label 57 #show_info("Finished in "+"{:.3f}".format((time.time()-start_time)/60)+" min") 58 return tracklabels 59 60 61 def perform_track(self, labels): 62 """ Do tracking with laptrack module """ 63 64 ## handling eventual missing (empty) frame: 65 ind = [] 66 for i, lab in enumerate(labels): 67 if len(np.unique(lab)) == 1: 68 ind.append(i) 69 labels = [ lab for i, lab in enumerate(labels) if i not in ind] 70 71 if self.version_over: 72 ol = OverLapTrack( 73 cutoff=self.cost_cutoff, 74 metric_coefs=(1.0, 0.0, -1.0, 0.0, 0.0), 75 #gap_closing_metric_coefs=(1.0, -1.0, 0.0, 0.0, 0.0), 76 #gap_closing_max_frame_count=1, 77 gap_closing_cutoff=False, 78 merging_cutoff=self.merging_cost, 79 merging_metric_coefs=(1.0, 0.0, 0.0, -1.0, 0.0), 80 splitting_cutoff=self.splitting_cost, 81 splitting_metric_coefs=(1.0, 0.0, 0.0, 0.0, -1.0), 82 ) 83 else: 84 ol = OverLapTrack( 85 track_cost_cutoff=self.cost_cutoff, 86 track_dist_metric_coefs=(1.0, 0.0, -1.0, 0.0, 0.0), 87 #gap_closing_dist_metric_coefs=(1.0, -1.0, 0.0, 0.0, 0.0), 88 #gap_closing_max_frame_count=1, 89 gap_closing_cost_cutoff=False, 90 merging_cost_cutoff=self.merging_cost, 91 merging_dist_metric_coefs=(1.0, 0.0, 0.0, -1.0, 0.0), 92 splitting_cost_cutoff=self.splitting_cost, 93 splitting_dist_metric_coefs=(1.0, 0.0, 0.0, 0.0, -1.0), 94 ) 95 96 track_df, split_df, merge_df = ol.predict_overlap_dataframe(labels) 97 ## handle eventual missing frames 98 track_df = track_df.reset_index() 99 track_df["frame"] += np.searchsorted(sorted(ind), track_df["frame"], side='right') 100 101 track_df = track_df.reset_index() 102 return track_df, split_df, merge_df 103 104 def track_overlaps(self, labels): 105 """ Track all movie with laptrack overlap method """ 106 ut.napari_info("Starting tracking with laptrack Overlap...") 107 return self.perform_track( labels ) 108 109 110 def inspect_oneframe(self, graph, trackdf): 111 for track in np.unique(trackdf["track_id"]): 112 tr = trackdf[trackdf["track_id"] == track] 113 ## track is only on one frame, suspect 114 if len(np.unique(tr["frame"])) == 1: 115 # trackid + 1 as trackid starts as 0 116 pos = (tr.iloc[0]["frame"], int(tr.iloc[0]["centroid-0"]), int(tr.iloc[0]["centroid-1"])) 117 self.epicure.inspecting.add_event( pos, track+1, "tracking" ) 118 if self.track.suggesting: 119 if track in graph.keys(): 120 sisters = [] 121 refval = graph[track][0] 122 for key, val in graph.items(): 123 if val[0] == refval: 124 sisters.append( key ) 125 if len(sisters) == 2: 126 for sis in sisters: 127 self.epicure.add_suggestion( sis+1, refval+1 )
LaptrackOverlaps(track, epic)
20 def __init__(self, track, epic): 21 self.splitting_cost = 1 22 self.cost_cutoff = 0.9 23 self.merging_cost = 1 24 self.track = track 25 self.epicure = epic 26 self.inspecting = False 27 self.suggesting = False 28 ## to handle difference in laptrack versions 29 self.version_over = Version(laptrack.__version__) >= Version("0.17.0")
def
twoframes_track(self, img_labels, labels):
32 def twoframes_track(self, img_labels, labels): 33 """ Do track between two frames, only track label """ 34 #start_time = time.time() 35 track_df, split_df, merge_df = self.perform_track( img_labels ) 36 #show_info("Performed in "+"{:.3f}".format((time.time()-start_time)/60)+" min") 37 38 track_ids = [None]*len(labels) 39 ## look for track id associated with label 40 for i, row in track_df.iterrows(): 41 frame = int(row["frame"]) 42 if frame == 1: 43 tid = int(row["track_id"]) 44 curlabel = int(row["label"]) 45 ind = labels.index(curlabel) 46 track_ids[ind] = tid 47 48 tracklabels = [None]*len(labels) 49 ## look for cell label associated with track_id in the first frame, if any 50 for i, row in track_df.iterrows(): 51 frame = int(row["frame"]) 52 tid = int(row["track_id"]) 53 if (tid in track_ids) and (frame==0): 54 ind = track_ids.index(tid) 55 label = int(row["label"]) 56 tracklabels[ind] = label 57 #show_info("Finished in "+"{:.3f}".format((time.time()-start_time)/60)+" min") 58 return tracklabels
Do track between two frames, only track label
def
perform_track(self, labels):
61 def perform_track(self, labels): 62 """ Do tracking with laptrack module """ 63 64 ## handling eventual missing (empty) frame: 65 ind = [] 66 for i, lab in enumerate(labels): 67 if len(np.unique(lab)) == 1: 68 ind.append(i) 69 labels = [ lab for i, lab in enumerate(labels) if i not in ind] 70 71 if self.version_over: 72 ol = OverLapTrack( 73 cutoff=self.cost_cutoff, 74 metric_coefs=(1.0, 0.0, -1.0, 0.0, 0.0), 75 #gap_closing_metric_coefs=(1.0, -1.0, 0.0, 0.0, 0.0), 76 #gap_closing_max_frame_count=1, 77 gap_closing_cutoff=False, 78 merging_cutoff=self.merging_cost, 79 merging_metric_coefs=(1.0, 0.0, 0.0, -1.0, 0.0), 80 splitting_cutoff=self.splitting_cost, 81 splitting_metric_coefs=(1.0, 0.0, 0.0, 0.0, -1.0), 82 ) 83 else: 84 ol = OverLapTrack( 85 track_cost_cutoff=self.cost_cutoff, 86 track_dist_metric_coefs=(1.0, 0.0, -1.0, 0.0, 0.0), 87 #gap_closing_dist_metric_coefs=(1.0, -1.0, 0.0, 0.0, 0.0), 88 #gap_closing_max_frame_count=1, 89 gap_closing_cost_cutoff=False, 90 merging_cost_cutoff=self.merging_cost, 91 merging_dist_metric_coefs=(1.0, 0.0, 0.0, -1.0, 0.0), 92 splitting_cost_cutoff=self.splitting_cost, 93 splitting_dist_metric_coefs=(1.0, 0.0, 0.0, 0.0, -1.0), 94 ) 95 96 track_df, split_df, merge_df = ol.predict_overlap_dataframe(labels) 97 ## handle eventual missing frames 98 track_df = track_df.reset_index() 99 track_df["frame"] += np.searchsorted(sorted(ind), track_df["frame"], side='right') 100 101 track_df = track_df.reset_index() 102 return track_df, split_df, merge_df
Do tracking with laptrack module
def
track_overlaps(self, labels):
104 def track_overlaps(self, labels): 105 """ Track all movie with laptrack overlap method """ 106 ut.napari_info("Starting tracking with laptrack Overlap...") 107 return self.perform_track( labels )
Track all movie with laptrack overlap method
def
inspect_oneframe(self, graph, trackdf):
110 def inspect_oneframe(self, graph, trackdf): 111 for track in np.unique(trackdf["track_id"]): 112 tr = trackdf[trackdf["track_id"] == track] 113 ## track is only on one frame, suspect 114 if len(np.unique(tr["frame"])) == 1: 115 # trackid + 1 as trackid starts as 0 116 pos = (tr.iloc[0]["frame"], int(tr.iloc[0]["centroid-0"]), int(tr.iloc[0]["centroid-1"])) 117 self.epicure.inspecting.add_event( pos, track+1, "tracking" ) 118 if self.track.suggesting: 119 if track in graph.keys(): 120 sisters = [] 121 refval = graph[track][0] 122 for key, val in graph.items(): 123 if val[0] == refval: 124 sisters.append( key ) 125 if len(sisters) == 2: 126 for sis in sisters: 127 self.epicure.add_suggestion( sis+1, refval+1 )