def feature_detection(S_ana_log): indices = np.argwhere( ~np.isnan(S_ana_log)) # Find all non-NaN indices in S_ana_log #print(np.shape(indices)) Features_list = [] # initialize Features_list for [x_ind, y_ind] in indices: # For each pair of indices (pixel) if len(Features_list) == 0: # if len of feature_list is 0 newFeature = Feature(x_ind, y_ind) # create a new feature Features_list.append(newFeature) # add new feature to feature_list else: border_list = [ ] # initialize list of logicals on where a Feature borders current pixel sublist = [ ] # initialize list of neighboring Features that boarder current pixel for currentFeature in Features_list: # for each feature in list border_list.append(currentFeature.borders( x_ind, y_ind)) # find all features that boarders the pixel indslist = np.where(border_list)[0] if len(indslist ) == 1: # if current pixel boarders the exactly 1 Feature hunterFeature = Features_list[indslist[0]] # find that Feature hunterFeature.add(x_ind, y_ind) # add current pixel to that Feature if len(indslist ) > 1: # if the current pixel boarders more than 1 Feature for ind in indslist: sublist.append( Features_list[ind]) # add those Features to a list for s in sublist: Features_list.remove( s) # remove those Features from Features_list hunterFeature = conjoin( sublist) # conjoin all Features in sublist hunterFeature.add( x_ind, y_ind) # add current pixel to conjoined Feature Features_list.append( hunterFeature) # add conjoined Feature to Feature_list else: # if current pixel does not boarder any existing features newFeature = Feature(x_ind, y_ind) # create a new feature Features_list.append( newFeature) # add new feature to feature_list return (Features_list, indices)
def h_clustering(Features_list,area_thres,prox_thres): if len(Features_list) == 0: return(Features_list) exit = False while exit == False: rmp = [] # initialize Feature removal list # re-order Features list by largest area to smallest Features_list = np.array(Features_list) f_areas = [] for f in Features_list: f_areas.append(f.area) so = np.flipud(np.argsort(f_areas)) Features_list = Features_list[so] Features_list = Features_list.tolist() # Begin clustering for ff in range(len(Features_list)): f1 = Features_list[ff] if f1.parent == f1 and f1.area > area_thres: # if f1 has not been hunted and is large enough dist_list = [] for f2 in Features_list: if f2 == f1: # if f2 is f1 or has beent hunted already, set dist to large value dist_list.append(1000) elif f2 in rmp: dist_list.append(1000) else: dist_list.append(dist_metric(f1,f2)) #dist_list.append(proximity(f1,f2)) #use proximity instead of custom dist metric dist = np.min(dist_list) # f1 hunts f2 thats closest to it if dist <= prox_thres: prey = Features_list[np.argmin(dist_list)] Features_list[ff] = copy.deepcopy(conjoin([f1,prey])) f1 = Features_list[ff] # reset f1 in features list prey.parent = f1 rmp.append(prey) if not rmp: #if there are no Features to remove exit = True # exit for pp in rmp: #remove each hunted feature in rmp from Features_list Features_list.remove(pp) print('Number of clusters: ', len(Features_list)) return(Features_list)
def feature_clustering(Features_list): opt = False J = [] if len(Features_list) < 10: klist = np.arange(len(Features_list)) + 1 else: klist = np.arange(10) + 1 clustered_list = [] for k in klist: unclustered_list = copy.deepcopy(Features_list.tolist()) unassigned_list = unclustered_list.copy() clustered_list = [] f_areas = [] for f in Features_list: f_areas.append(f.area) rep_list = [] cluster_list = [] # for ii in range(k): # if len(rep_list) == 0: # rep_list = random.sample(unclustered_list,1) # cluster_list.append(Cluster(rep_list[0])) # unclustered_list.remove(rep_list[0]) # unassigned_list.remove(rep_list[0]) # else: # unassigned_list = [ff for ff in unassigned_list if dist_metric(ff,rep_list[-1])>10] # if len(unassigned_list) == 0: # break # else: # addf = random.sample(unassigned_list,1) # rep_list.append(addf[0]) # cluster_list.append(Cluster(rep_list[-1])) # unclustered_list.remove(rep_list[-1]) # unassigned_list.remove(rep_list[-1]) # rep_list = random.sample(unclustered_list,k) # for ii in range(k): # cluster_list.append(Cluster(rep_list[ii])) # unclustered_list.remove(rep_list[ii]) for ii in range(k): if len(rep_list) == 0: ind = np.argmax(f_areas) #unclustered_list.append(Features_list[ind]) rep_list.append(unclustered_list[ind]) cluster_list.append(Cluster(unclustered_list[ind])) f_areas.remove(f_areas[ind]) unassigned_list.remove(unclustered_list[ind]) unclustered_list.remove(unclustered_list[ind]) else: f_areas = [] unassigned_list = [ ff for ff in unassigned_list if proximity(ff, rep_list[-1]) > 0 ] for ff in unassigned_list: f_areas.append(ff.area) if len(f_areas) == 0: break else: ind = np.argmax(f_areas) #unclustered_list.append(Features_list[ind]) rep_list.append(unassigned_list[ind]) cluster_list.append(Cluster(unassigned_list[ind])) unclustered_list.remove(unassigned_list[ind]) unassigned_list.remove(unassigned_list[ind]) print('Trying ', len(rep_list), ' Clusters...') #print(len(unclustered_list)) cost_dist_list = [] it = 0 lim = 5 epi = 0 while it < lim: #print(it) cost_dist = 0 for f1 in unclustered_list: dist_list = [] for f2 in rep_list: dist = dist_metric(f1, f2) dist_list.append(dist) minind = np.argmin(dist_list) cluster_list[minind].add(f1) cost_dist = cost_dist + dist_list[minind] if it < lim - 1: # for ff in rep_list: # unclustered_list.append(ff) for cc in range(len(cluster_list)): prev_rep = rep_list[cc] unclustered_list.append(prev_rep) new_rep = cluster_list[cc].setrep(epi) rep_list[cc] = new_rep unclustered_list.remove(new_rep) cluster_list[cc].clear() cluster_list[cc].rep = rep_list[cc] cluster_list[cc].add(rep_list[cc]) #print(rep_list) cost_dist_list.append(cost_dist) it = it + 1 #epi = 0.75*epi for cc in range(len(cluster_list)): clustered_list.append(conjoin(cluster_list[cc].content)) print(cost_dist) J.append(cost_dist) # if len(J)>1 and 0<=J[-2]-J[-1]<20: # k_opt = k-1 # opt = True # break if opt == False: if len(J) < 2: k_opt = 1 print(J) print('number of clusters: ', k_opt) else: # Jgrad = np.gradient(J) # k_opt = np.argmin(np.abs(Jgrad[np.abs(Jgrad)>0]))+1 # if k_opt == 0: # k_opt = 1 k_opt = KneeLocator(np.arange(len(J)) + 1, J, curve='convex', direction='decreasing') if k_opt.knee == None: k_opt = k else: k_opt = k_opt.knee + 1 if J == 0: k_opt = k_opt - 1 print(J) print('number of clusters: ', k_opt) clustered_list = [] k = k_opt unclustered_list = copy.deepcopy(Features_list.tolist()) unassigned_list = unclustered_list.copy() clustered_list = [] f_areas = [] for f in Features_list: f_areas.append(f.area) rep_list = [] cluster_list = [] # for ii in range(k): # if len(rep_list) == 0: # rep_list = random.sample(unclustered_list,1) # cluster_list.append(Cluster(rep_list[0])) # unclustered_list.remove(rep_list[0]) # unassigned_list.remove(rep_list[0]) # else: # unassigned_list = [ff for ff in unassigned_list if dist_metric(ff,rep_list[-1])>10] # if len(unassigned_list) == 0: # break # else: # addf = random.sample(unassigned_list,1) # rep_list.append(addf[0]) # cluster_list.append(Cluster(rep_list[-1])) # unclustered_list.remove(rep_list[-1]) # unassigned_list.remove(rep_list[-1]) # rep_list = random.sample(unclustered_list,k) # for ii in range(k): # cluster_list.append(Cluster(rep_list[ii])) # unclustered_list.remove(rep_list[ii]) for ii in range(k): if len(rep_list) == 0: ind = np.argmax(f_areas) #unclustered_list.append(Features_list[ind]) rep_list.append(unclustered_list[ind]) cluster_list.append(Cluster(unclustered_list[ind])) f_areas.remove(f_areas[ind]) unassigned_list.remove(unclustered_list[ind]) unclustered_list.remove(unclustered_list[ind]) else: f_areas = [] unassigned_list = [ ff for ff in unassigned_list if proximity(ff, rep_list[-1]) > 0 ] for ff in unassigned_list: f_areas.append(ff.area) if len(f_areas) == 0: break else: ind = np.argmax(f_areas) #unclustered_list.append(Features_list[ind]) rep_list.append(unassigned_list[ind]) cluster_list.append(Cluster(unassigned_list[ind])) unclustered_list.remove(unassigned_list[ind]) unassigned_list.remove(unassigned_list[ind]) cost_dist_list = [] it = 0 lim = 5 epi = 0 while it < lim: #print(it) cost_dist = 0 for f1 in unclustered_list: dist_list = [] for f2 in rep_list: dist = dist_metric(f1, f2) dist_list.append(dist) minind = np.argmin(dist_list) cluster_list[minind].add(f1) cost_dist = cost_dist + dist_list[minind] if it < lim - 1: for cc in range(len(cluster_list)): prev_rep = rep_list[cc] unclustered_list.append(prev_rep) new_rep = cluster_list[cc].setrep(epi) rep_list[cc] = new_rep unclustered_list.remove(new_rep) cluster_list[cc].clear() cluster_list[cc].rep = rep_list[cc] cluster_list[cc].add(rep_list[cc]) #print(rep_list) #print(rep_list) cost_dist_list.append(cost_dist) it = it + 1 #epi = 0.75*epi for cc in range(len(cluster_list)): clustered_list.append(conjoin(cluster_list[cc].content)) return (clustered_list)
################################### Get Saved Feature Stats and Plot ############################################ print('Generating/Saving Plot ... ') S_noise_cur = copy.deepcopy(S) Features_list_copy = copy.deepcopy( Features_list) # get a copy of Features_list S_g_log_test = copy.deepcopy(S_ana_log) # get a copy of S_ana_log filtered_Features_list = [ ] # initialize a list to hold all Features to be saved Features_stats = [] # initialize matrix to record stats of saved Features hull_list = [] # initilized list to record hull of saved Features # remove all non-Features from plot if (np.any(Features_list_copy)): big_Feature = conjoin(Features_list_copy) for [x_ind, y_ind] in indices: if (x_ind, y_ind) not in big_Feature.pixels: S_g_log_test[(x_ind, y_ind)] = np.float('nan') for ent in Features_list: # For each Feature ent.stats(flist, tcoords) # print(ent.area) # print((ent.end_f-ent.start_f)/(ent.end_t-ent.start_t)) if ( ent.area <= area_thres ): # or ((ent.end_f-ent.start_f)/(ent.end_t-ent.start_t)>=100)): # if Feature area <= area_thres or if feature is stbb, set Feature pixels to NaN for p in ent.pixels: S_g_log_test[p] = np.float('nan') else: # else, keep the Feature, add to fFlist, determine its stats, calculate the hull of the Feature
if len(indslist ) == 1: # if current pixel boarders the exactly 1 Feature hunterFeature = Features_list[indslist[0]] # find that Feature hunterFeature.add(x_ind, y_ind) # add current pixel to that Feature if len(indslist ) > 1: # if the current pixel boarders more than 1 Feature for ind in indslist: sublist.append( Features_list[ind]) # add those Features to a list for s in sublist: Features_list.remove( s) # remove those Features from Features_list hunterFeature = conjoin( sublist) # conjoin all Features in sublist hunterFeature.add( x_ind, y_ind) # add current pixel to conjoined Feature Features_list.append( hunterFeature) # add conjoined Feature to Feature_list else: # if current pixel does not boarder any existing features newFeature = Feature(x_ind, y_ind) # create a new feature Features_list.append( newFeature) # add new feature to feature_list ############################### Group Features ############################################### print('Grouping Features ... ') exit = False while exit == False: