def remove_abnormal_samples(seg, sigma=0.9): '''removes abnormal samples based on sig. deviation from mean centroid, then removes based on mean size''' # Get centroids of samples centroids = [] for idx, lab in enumerate(measure.regionprops(scipy.ndimage.label(seg)[0])): centroids.append(lab.centroid) row_vals = [x[0] for x in centroids] # Get relevant stats of row values mean = np.mean(row_vals) std = np.std(row_vals) hi = mean + sigma*std lo = mean - sigma*std # Eliminate sig. deviation from mean for idx, lab in enumerate(measure.regionprops(scipy.ndimage.label(seg)[0])): centroid = lab.centroid if centroid[0] < lo or centroid[0] > hi: seg = floodfill_fast( seg, x=int(centroid[0]), y=int(centroid[1]), value=0, border_color=0, dtype=np.uint8 )[0] # Get sizes of samples areas = [] for idx, lab in enumerate(measure.regionprops(scipy.ndimage.label(seg)[0])): areas.append(lab.filled_area) mean = np.mean(areas) std = np.std(areas) hi = mean + 3*sigma*std lo = mean - 3*sigma*std # Eliminate sig. deviation from mean for idx, lab in enumerate(measure.regionprops(scipy.ndimage.label(seg)[0])): area = lab.filled_area centroid = lab.centroid if area < lo or area > hi: seg = floodfill_fast( seg, x=int(centroid[0]), y=int(centroid[1]), value=0, border_color=0, dtype=np.uint8 )[0] return seg
def find_standards(seg, n_standards=6): '''finds standards based on regular proximity across row only actually requires seg returns new image with standards == 2, samples == 1 ''' best_std_candidate_row = -1 previous_dists = [] previous_mean = -1 previous_std = np.inf ####REWRITE TO REDUCE NSTDS-! BY ONE EACH TIME IF DOESNT FIND BESTSTDCANDIDATEROW cutoff = n_standards - 1 # ideally, want to find this many gaps while True: if cutoff == 0: raise ValueError('Error: Did not find any standards') break for i, row in enumerate(seg): dists = object_distances(row) if len(dists) >= cutoff and dists != previous_dists: mean = np.mean(dists) std = np.std(dists) if std < previous_std: previous_mean = mean previous_std = std best_std_candidate_row = i previous_dists = dists if best_std_candidate_row == -1: print('Failed to detect all 6 standards, will now try to find some') cutoff -= 1 else: break if best_std_candidate_row == -1: raise ValueError('unable to identify all 6 standards, take new image') #plot_row(seg, best_std_candidate_row) # Now, we have row with stds. Lets color the standards: best = best_std_candidate_row new = seg.copy() # get list of ys marking each standard lab = scipy.ndimage.label(seg[best])[0] ys = [] for i in range(1, lab.max()+1): for idx, item in enumerate(lab): if item == i: ys.append(idx) break print(ys) for y in ys: new = floodfill_fast(new, x=best, y=y, value=2, border_color=0, dtype=np.uint8)[0] return new