Exp_ID + '.h5') # The path of the file of the input video. # The entire process of SUNS online Masks, Masks_2, time_total, time_frame, list_time_per = suns_online( filename_video, filename_CNN, Params_pre, Params_post, \ dims, frames_init, merge_every, batch_size_init, \ useSF=useSF, useTF=useTF, useSNR=useSNR, med_subtract=med_subtract, \ update_baseline=update_baseline, useWT=useWT, \ show_intermediate=show_intermediate, prealloc=prealloc, display=display, p=p) # %% Evaluation of the segmentation accuracy compared to manual ground truth filename_GT = dir_GTMasks + Exp_ID + '_sparse.mat' data_GT = loadmat(filename_GT) GTMasks_2 = data_GT['GTMasks_2'].transpose() (Recall, Precision, F1) = GetPerformance_Jaccard_2(GTMasks_2, Masks_2, ThreshJ=0.5) print({'Recall': Recall, 'Precision': Precision, 'F1': F1}) savemat(os.path.join(dir_output, 'Output_Masks_CV{}_{}.mat'.format(CV, Exp_ID)), \ {'Masks':Masks, 'list_time_per':list_time_per}, do_compression=True) # %% Save recall, precision, F1, total processing time, and average processing time per frame list_Recall[CV, eid] = Recall list_Precision[CV, eid] = Precision list_F1[CV, eid] = F1 list_time[CV, eid] = time_total list_time_frame[CV, eid] = time_frame Info_dict = { 'list_Recall': list_Recall, 'list_Precision': list_Precision,
def refine_seperate_multi(GTMasks_2, masks_final_2, times_final, list_cons, thresh_mask=0.5, ThreshJ=0.5, display=False): '''Refine segmented neurons by requiring them to be active for "cons" consecutive frames. The outputs are the recall, precision, and F1 calculated using all values in "list_cons". Used to search the optimal "cons". Inputs: GTMasks_2 (sparse.csr_matrix): Ground truth masks. masks_final_2 (sparse.csr_matrix of float32): the segmented neuron masks. times_final (list of 1D numpy.array): indices of frames when the neuron is active. list_cons (list of int): A list of minimum number of consecutive frames that a neuron should be active for. thresh_mask (float between 0 and 1, default to 0.5): Threashold to binarize the real-number mask. values higher than "thresh_mask" times the maximum value are set to be True. ThreshJ (float, default to 0.5): Threshold Jaccard distance for two neurons to match. display (bool, default to False): Indicator of whether to show the optimal "cons" Outputs: Recall_k (1D numpy.array of float): Percentage of matched neurons over all GT neurons. Precision_k (1D numpy.array of float): Percentage of matched neurons over all segmented neurons. F1_k (1D numpy.array of float): Harmonic mean of Recall and Precision. ''' L_cons = len(list_cons) # number of "cons" to optimize over num_masks = len(times_final) # Number of segmented neurons Precision_k = np.zeros(L_cons) Recall_k = np.zeros(L_cons) F1_k = np.zeros(L_cons) for (k1, cons) in enumerate(list_cons): if cons > 1: have_cons = np.zeros(num_masks, dtype='bool') for kk in range(num_masks): times_diff1 = times_final[kk][cons - 1:] - times_final[kk][:1 - cons] # indicators of whether the neuron was active for "cons" frames have_cons[kk] = np.any(times_diff1 == cons - 1) if np.any(have_cons): masks_select_2 = masks_final_2[have_cons] Masks_2 = sparse.vstack( [x >= x.max() * thresh_mask for x in masks_select_2]) # Evalueate the accuracy of the result using recall, precision, and F1 (Recall_k[k1], Precision_k[k1], F1_k[k1]) = GetPerformance_Jaccard_2(GTMasks_2, Masks_2, ThreshJ) else: (Recall_k[k1], Precision_k[k1], F1_k[k1]) = (0, 0, 0) else: masks_select_2 = masks_final_2 Masks_2 = sparse.vstack( [x >= x.max() * thresh_mask for x in masks_select_2]) (Recall_k[k1], Precision_k[k1], F1_k[k1]) = GetPerformance_Jaccard_2(GTMasks_2, Masks_2, ThreshJ) if display: ind = F1_k.argmax() print('Recall={:0.6f}, Precision={:0.6f}, F1={:0.6f}, cons={}.'.format( Recall_k[ind], Precision_k[ind], F1_k[ind], list_cons[ind])) return Recall_k, Precision_k, F1_k