"""
"""
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