"""
"""
from __future__ import division, absolute_import, print_function
from scipy.ndimage import gaussian_laplace
from skimage.feature.peak import peak_local_max
from skimage.feature import blob_log
from skimage.feature.blob import _prune_blobs
import numpy as np
from math import sqrt, hypot, log
__author__ = 'andrea tramacere'
[docs]class ImageFeature(object):
"""
Class to handle image fitering
"""
def __init__(self,func):
self._func=func
[docs] def apply(self,image_array,**kw):
return self._func(image_array,**kw)
[docs]class PeakLocalMaxima(ImageFeature):
"""
wrapper around scikit-image
"""
def __init__(self, min_distance=1,
threshold_abs=None,
threshold_rel=None,
exclude_border=True,
indices=True,
num_peaks=None,
footprint=None,
labels=None):
super(PeakLocalMaxima,self).__init__(func=self.func)
self.min_distance=min_distance
self.threshold_abs=threshold_abs
self.threshold_rel=threshold_rel
self.exclude_border=exclude_border
self.indices=indices
self.num_peaks=num_peaks
self.footprint=footprint
self.labels=labels
[docs] def func(self,image_array,coords_in_xy=False,verbose=False):
"""
Args:
image_array: image array or image cube
get_xy:
Returns:
"""
local_maxima=peak_local_max(image_array,
min_distance=self.min_distance,
threshold_abs=self.threshold_abs,
threshold_rel=self.threshold_rel,
exclude_border=self.exclude_border,
indices=self.indices,
num_peaks=self.num_peaks,
footprint=self.footprint,
labels=self.labels)
lm_maxima_flux=np.zeros(local_maxima.shape[0])
for ID in xrange(lm_maxima_flux.size):
lm_maxima_flux[ID]=image_array[local_maxima[ID][0],local_maxima[ID][1]]
if coords_in_xy:
x_local_maxima=local_maxima[:,1]
y_local_maxima=local_maxima[:,0]
local_maxima=np.column_stack((x_local_maxima,y_local_maxima))
if verbose==True:
print("|PeakLocalMaxima",)
print("| found maxima",lm_maxima_flux.size)
return local_maxima,lm_maxima_flux
[docs]class BlobDetectionGaussLaplace(ImageFeature):
def __init__(self,
min_sigma,
max_sigma,
num_sigma=10,
threshold_rel=0.05,
overlap=0.5,
indices=True,
log_scale=False):
super(BlobDetectionGaussLaplace,self).__init__(func=self.func)
self.min_sigma=min_sigma
self.max_sigma=max_sigma
self.num_sigma=num_sigma
self.threshold_rel=threshold_rel
self.overlap=overlap
self.log_scale=log_scale
self.indices=indices
[docs] def func(self,image_array,coords_in_xy=False,verbose=False):
if self.log_scale:
start, stop = log(self.min_sigma, 10), log(self.max_sigma, 10)
sigma_list = np.logspace(start, stop, self.num_sigma)
else:
sigma_list = np.linspace(self.min_sigma, self.max_sigma, self.num_sigma)
empty=True
local_maxima=None
if verbose==True:
print("|GaussLaplace blob detection")
print("|sigma list",sigma_list)
for s in sigma_list:
gl_image= -gaussian_laplace(image_array, s)
local_maxima_s = peak_local_max(gl_image,
min_distance=np.int32(s),
footprint=None,
threshold_abs=None,
threshold_rel=self.threshold_rel,
indices=self.indices,
num_peaks=None,
exclude_border=True)
if local_maxima_s.shape[0]>0:
if empty == True:
local_maxima=np.zeros((local_maxima_s.shape[0],3), dtype=np.float64)
local_maxima[:,0]=local_maxima_s[:,0]
local_maxima[:,1]=local_maxima_s[:,1]
local_maxima[:,2]=s
empty=False
else:
local_maxima_n=np.zeros((local_maxima_s.shape[0],3), dtype=np.float64)
local_maxima_n[:,0]=local_maxima_s[:,0]
local_maxima_n[:,1]=local_maxima_s[:,1]
local_maxima_n[:,2]=s
local_maxima=np.row_stack((local_maxima,local_maxima_n))
#print('GaussLaplace blob detection', local_maxima)
if local_maxima is not None:
if verbose==True:
print("|local maxima found" ,local_maxima.shape[0])
local_maxima=local_maxima[local_maxima[:,2]>0]
blobs=np.int32(_prune_blobs(local_maxima, self.overlap))
lm_maxima_flux=np.zeros(blobs.shape[0])
for ID in xrange(lm_maxima_flux.size):
lm_maxima_flux[ID]=image_array[blobs[ID][0],blobs[ID][1]]
#print('Pruned blobs', blobs)
#print('coords_in_xy', coords_in_xy,type(coords_in_xy))
if coords_in_xy:
x_local_maxima=blobs[:,1]
y_local_maxima=blobs[:,0]
else:
x_local_maxima=blobs[:,0]
y_local_maxima=blobs[:,1]
local_maxima=np.column_stack((x_local_maxima,y_local_maxima))
if verbose==True:
print("|local maxima found, after pruning" ,local_maxima.shape[0])
else:
local_maxima=None
lm_maxima_flux=None
return local_maxima,lm_maxima_flux