class FastRadialFeatureFinder(EyeFeatureFinder): def __init__(self): # self.backend = VanillaBackend() self.backend = WovenBackend() # self.backend = OpenCLBackend() self.target_kpixels = 80.0 # 8.0 self.max_target_kpixels = 50.0 self.min_target_kpixels = 1. self.parameters_updated = 1 self.alpha = 10. self.min_radius_fraction = 0.0126 # 1./2000. self.max_radius_fraction = 0.12 # 1./8. self.min_fraction = 1. / 1000. self.max_fraction = 0.35 self.radius_steps = 6 self.radiuses_to_try = [1] self.ds_factor = 1 self.correct_downsampling = False self.do_refinement_phase = 0 self.return_sobel = 0 self.albino_mode = False self.albino_threshold = 10. self.cache_sobel = True self.cached_sobel = None self.compute_sobel_avg = True # for autofocus self.sobel_avg = None # Voting self.outlier_cutoff = 1. self.maxmin_consensus_votes = 1 self.image_contribution = 1 self.last_positions = [] self.available_filters = [u'sepfir', u'spline', u'fft', u'convolve2d'] self.result = None self.restrict_top = 0 self.restrict_bottom = 123 self.restrict_left = 0 self.restrict_right = 164 # analyze the image and return dictionary of features gleaned # from it # @clockit def analyze_image(self, image, guess=None, **kwargs): # print "fr" im_array = image # im_array = image.astype(double) im_array = im_array[::self.ds_factor, ::self.ds_factor] if guess != None: features = guess else: features = {'pupil_size': None, 'cr_size': None} if self.parameters_updated or self.backend.cached_shape \ != im_array.shape: print 'Recaching...' print 'Target kPixels: ', self.target_kpixels print 'Max Radius Fraction: ', self.max_radius_fraction print 'Radius steps: ', self.radius_steps im_pixels = image.shape[0] * image.shape[1] self.ds_factor = int(sqrt(im_pixels / int(self.target_kpixels * 1000))) if self.ds_factor <= 0: self.ds_factor = 1 im_array = image[::self.ds_factor, ::self.ds_factor] self.backend.autotune(im_array) self.parameters_updated = 0 self.radiuses_to_try = linspace(ceil(self.min_radius_fraction * im_array.shape[0]), ceil(self.max_radius_fraction * im_array.shape[0]), self.radius_steps) self.radiuses_to_try = unique(self.radiuses_to_try.astype(int)) print 'Radiuses to try: ', self.radiuses_to_try print 'Downsampling factor: ', self.ds_factor ds = self.ds_factor S = self.backend.fast_radial_transform(im_array, self.radiuses_to_try, self.alpha) S[:, 0:self.restrict_left] = -1. S[:, self.restrict_right:] = -1. S[0:self.restrict_top, :] = -1. S[self.restrict_bottom:, :] = -1. if self.albino_mode: (pupil_coords, cr_coords) = self.find_albino_features(S, im_array) else: (pupil_coords, cr_coords) = self.backend.find_minmax(S) if pupil_coords == None: pupil_coords = array([0., 0.]) if cr_coords == None: cr_coords = array([0., 0.]) if self.correct_downsampling: features['pupil_position'] = array([pupil_coords[0], pupil_coords[1]]) * ds features['cr_position'] = array([cr_coords[0], cr_coords[1]]) * ds features['dwnsmp_factor_coord'] = 1 else: features['pupil_position'] = array([pupil_coords[0], pupil_coords[1]]) features['cr_position'] = array([cr_coords[0], cr_coords[1]]) features['dwnsmp_factor_coord'] = ds features['transform'] = S features['im_array'] = im_array features['im_shape'] = im_array.shape features['restrict_top'] = self.restrict_top features['restrict_bottom'] = self.restrict_bottom features['restrict_left'] = self.restrict_left features['restrict_right'] = self.restrict_right if self.return_sobel: # this is very inefficient, and only for debugging (m, x, y) = self.backend.sobel3x3(im_array) features['sobel'] = m self.result = features def update_parameters(self): self.parameters_updated = 1 def get_result(self): return self.result def find_albino_features(self, T, im): import scipy.ndimage as ndi binarized = zeros_like(T) binarized[T > self.albino_threshold] = True (labels, nlabels) = ndi.label(binarized) slices = ndi.find_objects(labels) intensities = [] transform_means = [] if len(slices) < 2: return (None, None) for s in slices: transform_means.append(mean(T[s])) intensities.append(mean(im[s])) sorted_transform_means = argsort(transform_means) candidate1 = sorted_transform_means[-1] candidate2 = sorted_transform_means[-2] c1_center = array(ndi.center_of_mass(im, labels, candidate1 + 1)) c2_center = array(ndi.center_of_mass(im, labels, candidate2 + 1)) if intensities[candidate1] > intensities[candidate2]: return (c2_center, c1_center) else: return (c1_center, c2_center)
from pylab import * test_im = (rand(2250,2250)).astype(numpy.float32) #test_im = (rand(768,1024)).astype(numpy.float32) row = array([0.25, 0.3, 0.4]).astype(numpy.float32) #row = array([0.25, 0.3, 0.4, 0.6, 0.7, 0.6, 0.4, 0.3, 0.25]).astype(numpy.float32) #row = array([0.25, 0.4, 0.6, 0.4, 0.25]).astype(numpy.float32) row = row / sum(row) col = row cl_backend = OpenCLBackend() vanilla_backend = VanillaBackend() woven_backend = WovenBackend() woven_backend.autotune(test_im) cl_backend.autotune(test_im) print("CL Filtering...") #row_dev = cl.Buffer(cl_backend.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, 0, row.astype(float32)) #col_dev = cl.Buffer(cl_backend.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, 0, col.astype(float32)) row_dev = DeviceBuffer(cl_backend.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, row.astype(float32)) col_dev = DeviceBuffer(cl_backend.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, col.astype(float32)) #print cl_backend.device.name cl_filtered = cl_backend.separable_convolution2d(test_im.astype(float32), row_dev, col_dev, readback_from_device=False, im_shape=test_im.shape, row_shape=row.shape, col_shape=col.shape) for i in range(0,8): cl_filtered = cl_backend.separable_convolution2d(cl_filtered, row_dev, col_dev, readback_from_device=False, im_shape=test_im.shape, row_shape=row.shape, col_shape=col.shape) cl_filtered = cl_backend.separable_convolution2d(cl_filtered, row_dev, col_dev, readback_from_device=True, im_shape=test_im.shape, row_shape=row.shape, col_shape=col.shape)
class FastRadialFeatureFinder(EyeFeatureFinder): def __init__(self): # self.backend = VanillaBackend() self.backend = WovenBackend() # self.backend = OpenCLBackend() self.target_kpixels = 80.0 # 8.0 self.max_target_kpixels = 50.0 self.min_target_kpixels = 1. self.parameters_updated = 1 self.alpha = 10. self.min_radius_fraction = 0.0126 # 1./2000. self.max_radius_fraction = 0.12 # 1./8. self.min_fraction = 1. / 1000. self.max_fraction = 0.35 self.radius_steps = 6 self.radiuses_to_try = [1] self.ds_factor = 1 self.correct_downsampling = False self.do_refinement_phase = 0 self.return_sobel = 0 self.albino_mode = False self.albino_threshold = 10. self.cache_sobel = True self.cached_sobel = None self.compute_sobel_avg = True # for autofocus self.sobel_avg = None # Voting self.outlier_cutoff = 1. self.maxmin_consensus_votes = 1 self.image_contribution = 1 self.last_positions = [] self.available_filters = [u'sepfir', u'spline', u'fft', u'convolve2d'] self.result = None self.restrict_top = 0 self.restrict_bottom = 123 self.restrict_left = 0 self.restrict_right = 164 # analyze the image and return dictionary of features gleaned # from it # @clockit def analyze_image(self, image, guess=None, **kwargs): # print "fr" im_array = image # im_array = image.astype(double) im_array = im_array[::self.ds_factor, ::self.ds_factor] if guess != None: features = guess else: features = {'pupil_size': None, 'cr_size': None} if self.parameters_updated or self.backend.cached_shape \ != im_array.shape: logging.debug('Recaching...') logging.debug('Target kPixels: %s' % self.target_kpixels) logging.debug('Max Radius Fraction: %s' % self.max_radius_fraction) logging.debug('Radius steps: %s' % self.radius_steps) im_pixels = image.shape[0] * image.shape[1] self.ds_factor = int( sqrt(im_pixels / int(self.target_kpixels * 1000))) if self.ds_factor <= 0: self.ds_factor = 1 im_array = image[::self.ds_factor, ::self.ds_factor] self.backend.autotune(im_array) self.parameters_updated = 0 self.radiuses_to_try = linspace( ceil(self.min_radius_fraction * im_array.shape[0]), ceil(self.max_radius_fraction * im_array.shape[0]), self.radius_steps) self.radiuses_to_try = unique(self.radiuses_to_try.astype(int)) logging.debug('Radiuses to try: %s' % self.radiuses_to_try) logging.debug('Downsampling factor: %s' % self.ds_factor) ds = self.ds_factor S = self.backend.fast_radial_transform(im_array, self.radiuses_to_try, self.alpha) S[:, 0:self.restrict_left] = -1. S[:, self.restrict_right:] = -1. S[0:self.restrict_top, :] = -1. S[self.restrict_bottom:, :] = -1. if self.albino_mode: (pupil_coords, cr_coords) = self.find_albino_features(S, im_array) else: (pupil_coords, cr_coords) = self.backend.find_minmax(S) if pupil_coords == None: pupil_coords = array([0., 0.]) if cr_coords == None: cr_coords = array([0., 0.]) if self.correct_downsampling: features['pupil_position'] = array( [pupil_coords[0], pupil_coords[1]]) * ds features['cr_position'] = array([cr_coords[0], cr_coords[1]]) * ds features['dwnsmp_factor_coord'] = 1 else: features['pupil_position'] = array( [pupil_coords[0], pupil_coords[1]]) features['cr_position'] = array([cr_coords[0], cr_coords[1]]) features['dwnsmp_factor_coord'] = ds features['transform'] = S features['im_array'] = im_array features['im_shape'] = im_array.shape features['restrict_top'] = self.restrict_top features['restrict_bottom'] = self.restrict_bottom features['restrict_left'] = self.restrict_left features['restrict_right'] = self.restrict_right if self.return_sobel: # this is very inefficient, and only for debugging (m, x, y) = self.backend.sobel3x3(im_array) features['sobel'] = m self.result = features def update_parameters(self): self.parameters_updated = 1 def get_result(self): return self.result def find_albino_features(self, T, im): import scipy.ndimage as ndi binarized = zeros_like(T) binarized[T > self.albino_threshold] = True (labels, nlabels) = ndi.label(binarized) slices = ndi.find_objects(labels) intensities = [] transform_means = [] if len(slices) < 2: return (None, None) for s in slices: transform_means.append(mean(T[s])) intensities.append(mean(im[s])) sorted_transform_means = argsort(transform_means) candidate1 = sorted_transform_means[-1] candidate2 = sorted_transform_means[-2] c1_center = array(ndi.center_of_mass(im, labels, candidate1 + 1)) c2_center = array(ndi.center_of_mass(im, labels, candidate2 + 1)) if intensities[candidate1] > intensities[candidate2]: return (c2_center, c1_center) else: return (c1_center, c2_center)
class FastRadialFeatureFinder(EyeFeatureFinder): def __init__(self): self.backend = WovenBackend() #self.backend = OpenCLBackend() self.target_kpixels = 80.0 #8.0 self.max_target_kpixels = 50.0 self.min_target_kpixels = 1.0 self.parameters_updated = 1 self.alpha = 10. self.min_radius_fraction = 0.0226 #1./2000. self.max_radius_fraction = 0.0956 #1./8. self.min_fraction = 1. / 1000. self.max_fraction = 0.35 self.radius_steps = 6 self.radiuses_to_try = [1] self.ds_factor = 1 self.correct_downsampling = False self.do_refinement_phase = 0 self.shortcut_at_sobel = 0 self.cache_sobel = True self.cached_sobel = None self.compute_sobel_avg = True # for autofocus self.sobel_avg = None # Voting self.outlier_cutoff = 1. self.maxmin_consensus_votes = 1 self.image_contribution = 1 self.last_positions = [] self.available_filters = [u"sepfir", u"spline", u"fft", u"convolve2d"] self.result = None # analyze the image and return dictionary of features gleaned # from it ##@clockit def analyze_image(self, image, guess=None, **kwargs): #print "fr" im_array = image #im_array = image.astype(double) im_array = im_array[::self.ds_factor, ::self.ds_factor] if (guess != None): features = guess else: features = {'pupil_size': None, 'cr_size': None} if (self.parameters_updated or self.backend.cached_shape != im_array.shape): print "Recaching..." print "Target kPixels: ", self.target_kpixels print "Max Radius Fraction: ", self.max_radius_fraction print "Radius steps: ", self.radius_steps im_pixels = image.shape[0] * image.shape[1] self.ds_factor = int( sqrt(im_pixels / int(self.target_kpixels * 1000))) if (self.ds_factor <= 0): self.ds_factor = 1 im_array = image[::self.ds_factor, ::self.ds_factor] self.backend.autotune(im_array) self.parameters_updated = 0 self.radiuses_to_try = linspace( ceil(self.min_radius_fraction * im_array.shape[0]), ceil(self.max_radius_fraction * im_array.shape[0]), self.radius_steps) self.radiuses_to_try = unique(self.radiuses_to_try.astype(int)) print "Radiuses to try: ", self.radiuses_to_try print "Downsampling factor: ", self.ds_factor ds = self.ds_factor S = self.backend.fast_radial_transform(im_array, self.radiuses_to_try, self.alpha) (min_coords, max_coords) = self.backend.find_minmax(S) if (self.correct_downsampling): features['pupil_position'] = array([min_coords[0], min_coords[1] ]) * ds features['cr_position'] = array([max_coords[0], max_coords[1] ]) * ds features['dwnsmp_factor_coord'] = 1 else: features['pupil_position'] = array([min_coords[0], min_coords[1]]) features['cr_position'] = array([max_coords[0], max_coords[1]]) features['dwnsmp_factor_coord'] = ds features['transform'] = S features['im_array'] = im_array features['im_shape'] = im_array.shape self.result = features def update_parameters(self): self.parameters_updated = 1 def get_result(self): return self.result
class FastRadialFeatureFinder (EyeFeatureFinder): def __init__(self): self.backend = WovenBackend() #self.backend = OpenCLBackend() self.target_kpixels = 80.0 #8.0 self.max_target_kpixels = 50.0 self.min_target_kpixels = 1.0 self.parameters_updated = 1 self.alpha = 10. self.min_radius_fraction = 0.0226 #1./2000. self.max_radius_fraction = 0.0956 #1./8. self.min_fraction = 1./1000. self.max_fraction = 0.35 self.radius_steps = 6 self.radiuses_to_try = [1] self.ds_factor = 1 self.correct_downsampling = False self.do_refinement_phase = 0 self.shortcut_at_sobel = 0 self.cache_sobel = True self.cached_sobel = None self.compute_sobel_avg = True # for autofocus self.sobel_avg = None # Voting self.outlier_cutoff = 1. self.maxmin_consensus_votes = 1 self.image_contribution = 1 self.last_positions = [] self.available_filters = [u"sepfir", u"spline", u"fft", u"convolve2d"] self.result = None # analyze the image and return dictionary of features gleaned # from it ##@clockit def analyze_image(self, image, guess = None, **kwargs): #print "fr" im_array = image #im_array = image.astype(double) im_array = im_array[::self.ds_factor, ::self.ds_factor] if(guess != None): features = guess else: features = {'pupil_size' : None, 'cr_size' : None } if(self.parameters_updated or self.backend.cached_shape != im_array.shape): print "Recaching..." print "Target kPixels: ", self.target_kpixels print "Max Radius Fraction: ", self.max_radius_fraction print "Radius steps: ", self.radius_steps im_pixels = image.shape[0] * image.shape[1] self.ds_factor = int(sqrt(im_pixels / int(self.target_kpixels*1000))) if(self.ds_factor <= 0): self.ds_factor = 1 im_array = image[::self.ds_factor, ::self.ds_factor] self.backend.autotune(im_array) self.parameters_updated = 0 self.radiuses_to_try = linspace(ceil(self.min_radius_fraction*im_array.shape[0]), ceil(self.max_radius_fraction*im_array.shape[0]), self.radius_steps) self.radiuses_to_try = unique(self.radiuses_to_try.astype(int)) print "Radiuses to try: ", self.radiuses_to_try print "Downsampling factor: ", self.ds_factor ds = self.ds_factor; S = self.backend.fast_radial_transform(im_array, self.radiuses_to_try, self.alpha) (min_coords, max_coords) = self.backend.find_minmax(S) if(self.correct_downsampling): features['pupil_position'] = array([min_coords[0], min_coords[1]]) * ds features['cr_position'] = array([max_coords[0], max_coords[1]]) * ds features['dwnsmp_factor_coord'] = 1 else: features['pupil_position'] = array([min_coords[0], min_coords[1]]) features['cr_position'] = array([max_coords[0], max_coords[1]]) features['dwnsmp_factor_coord'] = ds features['transform'] = S features['im_array'] = im_array features['im_shape'] = im_array.shape self.result = features def update_parameters(self): self.parameters_updated = 1 def get_result(self): return self.result