Source code for asterism.core.clustering.cluster_tools

"""

"""
from __future__ import division, absolute_import, print_function

from skimage import measure
import numpy as np
#import cv2
#import time
from ...core.geometry.distance import dist_eval
from ..image_manager.image import Image

__author__ = 'andrea tramacere'





[docs]def cluster_border(x,y,img_buffer=5): x_min=x.min() y_min=y.min() x_max=x.max() y_max=y.max() x_size=int(x_max-x_min)+2*img_buffer y_size=int(y_max-y_min)+2*img_buffer image=np.zeros((y_size,x_size),dtype=np.float) for ph_id in xrange(x.size): x_id=int(x[ph_id]-x_min+img_buffer) y_id=int(y[ph_id]-y_min+img_buffer) image[y_id,x_id]=10 #t = time.time() #contours, hierarchy=cv2.findContours(image,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE) #print('cv2',time.time() - t) #t = time.time() contours = measure.find_contours(image, 5.0,fully_connected='low') #print('skimage',time.time() - t) if contours!=[]: size = 0 for n, contour in enumerate(contours): size += contour.shape[0] #print (size) cont_array = np.zeros((size, 2), dtype=np.double) n_0=0 for n, contour in enumerate(contours): #print(n_0,n_0+contour.shape[0],contour.shape) #we must swap x,y in contour cont_array[n_0: n_0+ contour.shape[0]] = contour[:,[1, 0]] n_0+=contour.shape[0] #import pylab as plt #fig, ax = plt.subplots() #ax.imshow(image, interpolation='nearest', cmap=plt.cm.gray) #ax.plot(cont_array[:, 0], cont_array[:, 1], linewidth=2) #plt.show() cont_array[:, 1] = cont_array[:, 1] + y_min - img_buffer cont_array[:, 0] = cont_array[:, 0] + x_min - img_buffer # cont_array=contours[0][:,0] # if len(contours)>1: # for contour in contours[1:]: # cont_array=np.row_stack((cont_array,contour[:,0])) # # # # cont_array[:,1]=cont_array[:,1]+y_min-img_buffer # # cont_array[:,0]=cont_array[:,0]+x_min-img_buffer # # cont_array=np.double(cont_array) return cont_array else: return None
[docs]def check_is_in_cluster(x_test,y_test,x,y): """ Parameters ---------- x_test y_test x y Returns ------- """ c1=np.in1d(x_test,x) c2=np.in1d(y_test,y) return c1*c2
[docs]def check_is_within_r_from_center(x_c,y_c,R,x_test,y_test,metric): """ Parameters ---------- x_c y_c R x_test y_test metric Returns ------- """ xy=np.column_stack((x_test,y_test)) dist=dist_eval(xy,x_c=x_c,y_c=y_c,metric=metric) return dist<R
[docs]def get_clusters_within_circle(clusters_list,R,centre,metric='euclidean'): """ Parameters ---------- clusters_list R centre metric Returns ------- """ dist_array=np.zeros((len(clusters_list)),dtype=([('cl_id',np.int16),('dist_min',np.float64),('all_in',np.bool)])) #print("R",R," centre",centre) for ID,cl in enumerate(clusters_list): if hasattr(cl,'cartesian'): coords=cl.cartesian.coords elif hasattr(cl,'coords'): coords=cl.coords else: raise RuntimeError('cluser has neither cartesian nor coords attribute') d=dist_eval(coords,x_c=centre[0],y_c=centre[1],metric=metric) if d.max()<R: all_in=True else: all_in=False dist_array[ID]=(ID,d.min(),all_in) within_dist_array=dist_array[dist_array['all_in']==True] selected=[clusters_list[ID] for ID in within_dist_array['cl_id']] return selected,within_dist_array
[docs]def get_closest_cluster(cluster,clusters_list): """ Parameters ---------- cluster clusters_list Returns ------- """ center_pos_array=np.zeros((len(clusters_list),2)) for ID,cl in enumerate(clusters_list): center_pos_array[ID]=(cl.x_c,cl.y_c) d=dist_eval(center_pos_array,x_c=cluster.x_c,y_c=cluster.y_c,metric=cluster._metric) if d.size>0: min_dist_id=d.argmin() cl=clusters_list[min_dist_id] else: min_dist_id=None cl=None return cl
[docs]def get_cluster_closest_to_position(cluster_list,x_c,y_c,metric='euclidean'): """ Parameters ---------- cluster_list x_c y_c metric Returns ------- """ dist=np.zeros(len(cluster_list),dtype=np.float64) for ID,cl in enumerate(cluster_list): if hasattr(cl,'cartesian'): coords=cl.cartesian.coords elif hasattr(cl,'coords'): coords=cl.coords else: raise RuntimeError('cluser has neither cartesian nor coords attribute') dist[ID]=dist_eval(coords,x_c=x_c,y_c=y_c,metric=metric).min() if dist.size>0: min_dist_id=dist.argmin() cl=cluster_list[min_dist_id] else: min_dist_id=None cl=None return cl
[docs]def get_cluster_Image(xy,border,pixel_values=None,bkg=None): """ Parameters ---------- xy border pixel_values bkg Returns ------- """ image,off_set_x,off_set_y,masked_pixels=get_cluster_image_array(xy,\ border,\ pixel_values=pixel_values, bkg=bkg) return Image.from_array(image),off_set_x,off_set_y,masked_pixels
[docs]def get_cluster_image_array(xy,border,pixel_values=None,bkg=None): """ Function to build an image from a cluster. The pixels values are provided by the parameter `pixel_values`. * If `pixel_values` is not provided each pixel with at least one point will have a value of 1, 0 or bkg if bkg = None or !=None, respectively * If `pixel_values` is provided, and bkg is None, then the bkg is fixed to 0.1 the min of `pixel_values` Parameters ---------- xy border pixel_values bkg Returns ------- image : off_set_x : off_set_y : masked_pixels : """ image_rows=int(xy[:,1].max()-xy[:,1].min())+1+2*np.int(border) image_cols=int(xy[:,0].max()-xy[:,0].min())+1+2*np.int(border) if pixel_values is None: pixel_values=np.ones(xy.shape[0]) if bkg is None: bkg=0 else: if bkg is None: bkg=pixel_values.min()-np.fabs(pixel_values.min())*0.1 off_set_x=np.int(xy[:,0].min()-border) off_set_y=np.int(xy[:,1].min()-border) image=np.ones((image_rows,image_cols))*bkg masked_pixels=np.ones(image.shape,dtype=np.bool) xy=xy.astype(np.int32) for IDs in xrange(xy.shape[0]): image[xy[IDs][1] - off_set_y, xy[IDs][0] - off_set_x] = pixel_values[IDs] masked_pixels[xy[IDs][1] - off_set_y, xy[IDs][0] - off_set_x] = False return image,off_set_x,off_set_y,masked_pixels
[docs]def eval_cluster_bary(xy,metric,weight=None): """ Parameters ---------- xy metric weight Returns ------- """ x=xy[:,0] y=xy[:,1] if xy.shape[0]==1: x_c =xy[:,0][0] y_c =xy[:,1][0] sig_x = 0 sig_y = 0 r_cluster = 0 semi_major_angle = 0 pos_err = 0 r_max = 0 r_mean = 0 return x_c,y_c,sig_x,sig_y,r_cluster,semi_major_angle,pos_err,r_max ,r_mean else: y_c_ave= y.mean() x_c_ave= x.mean() cdist= dist_eval(xy,x_c=x_c_ave,y_c=y_c_ave,metric=metric) cdist[cdist==0]=1 wdist_pos= 1.0/(cdist) if weight is not None: wdist_pos=wdist_pos* weight #wdist_pos=weight y_c_w=np.average( y,weights=wdist_pos) x_c_w=np.average( x,weights=wdist_pos) pos_err=1.0/np.sqrt(wdist_pos.sum()) cova= np.cov(xy,rowvar=0) eigvec, eigval, V = np.linalg.svd(cova, full_matrices=True) ind=np.argsort(eigval)[::-1] eigval=eigval[ind] eigvec=eigvec[:,ind] sd=[np.sqrt(eigval[0]),np.sqrt(eigval[1])] semi_major_angle=np.rad2deg(np.arctan2(eigvec[0][1],eigvec[0][0])) sig_x= sd[0] sig_y= sd[1] r_cluster= np.sqrt(sig_x*sig_x+sig_y*sig_y) x_c=x_c_w y_c=y_c_w r_max=cdist.max() r_mean=cdist.mean() return x_c,y_c,sig_x,sig_y,r_cluster,semi_major_angle,pos_err,r_max ,r_mean