def __init__(self,**params): """ Initialize this object as an EventProcessor, then also as a SheetCoordinateSystem with equal xdensity and ydensity. sheet_views is a dictionary that stores SheetViews, i.e. representations of the sheet for use by analysis or plotting code. """ EventProcessor.__init__(self,**params) # Initialize this object as a SheetCoordinateSystem, with # the same density along y as along x. SheetCoordinateSystem.__init__(self,self.nominal_bounds,self.nominal_density) n_units = round((self.lbrt[2]-self.lbrt[0])*self.xdensity,0) if n_units<1: raise ValueError( "Sheet bounds and density must be specified such that the "+ \ "sheet has at least one unit in each direction; " \ +self.name+ " does not.") # setup the activity matrix self.activity = zeros(self.shape,activity_type) # For non-plastic inputs self.__saved_activity = [] self._plasticity_setting_stack = [] self.sheet_views = {}
def __init__(self, **params): """ Initialize this object as an EventProcessor, then also as a SheetCoordinateSystem with equal xdensity and ydensity. sheet_views is a dictionary that stores SheetViews, i.e. representations of the sheet for use by analysis or plotting code. """ EventProcessor.__init__(self, **params) # Initialize this object as a SheetCoordinateSystem, with # the same density along y as along x. SheetCoordinateSystem.__init__(self, self.nominal_bounds, self.nominal_density) n_units = round((self.lbrt[2] - self.lbrt[0]) * self.xdensity, 0) if n_units < 1: raise ValueError( "Sheet bounds and density must be specified such that the "+ \ "sheet has at least one unit in each direction; " \ +self.name+ " does not.") # setup the activity matrix self.activity = zeros(self.shape, activity_type) # For non-plastic inputs self.__saved_activity = [] self._plasticity_setting_stack = [] self.sheet_views = {}
def __init__(self, bounds, shape, initial_items=None, **kwargs): (l, b, r, t) = bounds.lbrt() (dim1, dim2) = shape xdensity = dim1 / (r - l) ydensity = dim2 / (t - b) SheetCoordinateSystem.__init__(self, bounds, xdensity, ydensity) super(ProjectionGrid, self).__init__(initial_items, **kwargs)
def __init__(self, bounds, shape, initial_items=None, **kwargs): (l, b, r, t) = bounds.lbrt() (dim1, dim2) = shape xdensity = dim1 / (r-l) if (r-l) else 1 ydensity = dim2 / (t-b) if (t-b) else 1 self._style = None SheetCoordinateSystem.__init__(self, bounds, xdensity, ydensity) super(CoordinateGrid, self).__init__(initial_items, **kwargs)
def __init__(self, data, bounds=None, **kwargs): bounds = bounds if bounds else BoundingBox() data = np.array([[0]]) if data is None else data (l, b, r, t) = bounds.lbrt() (dim1, dim2) = data.shape[0], data.shape[1] xdensity = dim1/(r-l) ydensity = dim2/(t-b) SheetLayer.__init__(self, data, bounds, **kwargs) SheetCoordinateSystem.__init__(self, bounds, xdensity, ydensity)
def _set_image(self,image): # Stores a SheetCoordinateSystem with an activity matrix # representing the image if not isinstance(image,numpy.ndarray): image = array(image,Float) rows,cols = image.shape self.scs = SheetCoordinateSystem(xdensity=1.0,ydensity=1.0, bounds=BoundingBox(points=((-cols/2.0,-rows/2.0), ( cols/2.0, rows/2.0)))) self.scs.activity=image
def __call__(self, **params_to_override): p = ParamOverrides(self, params_to_override) xsize, ysize = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity).shape xsize, ysize = int(round(xsize)), int(round(ysize)) xdisparity = int(round(xsize * p.xdisparity)) ydisparity = int(round(xsize * p.ydisparity)) dotsize = int(round(xsize * p.dotsize)) bigxsize = 2 * xsize bigysize = 2 * ysize ndots = int( round(p.dotdensity * (bigxsize + 2 * dotsize) * (bigysize + 2 * dotsize) / min(dotsize, xsize) / min(dotsize, ysize))) halfdot = floor(dotsize / 2) # Choose random colors and locations of square dots random_seed = p.random_seed np.random.seed(random_seed * 12 + random_seed * 99) col = np.where(np.random.random((ndots)) >= 0.5, 1.0, -1.0) np.random.seed(random_seed * 122 + random_seed * 799) xpos = np.floor(np.random.random( (ndots)) * (bigxsize + 2 * dotsize)) - halfdot np.random.seed(random_seed * 1243 + random_seed * 9349) ypos = np.floor(np.random.random( (ndots)) * (bigysize + 2 * dotsize)) - halfdot # Construct arrays of points specifying the boundaries of each # dot, cropping them by the big image size (0,0) to (bigxsize,bigysize) x1 = xpos.astype(numpy.int) x1 = choose(less(x1, 0), (x1, 0)) y1 = ypos.astype(numpy.int) y1 = choose(less(y1, 0), (y1, 0)) x2 = (xpos + (dotsize - 1)).astype(numpy.int) x2 = choose(greater(x2, bigxsize), (x2, bigxsize)) y2 = (ypos + (dotsize - 1)).astype(numpy.int) y2 = choose(greater(y2, bigysize), (y2, bigysize)) # Draw each dot in the big image, on a blank background bigimage = zeros((bigysize, bigxsize)) for i in range(ndots): bigimage[y1[i]:y2[i] + 1, x1[i]:x2[i] + 1] = col[i] result = p.offset + p.scale * bigimage[ (ysize / 2) + ydisparity:(3 * ysize / 2) + ydisparity, (xsize / 2) + xdisparity:(3 * xsize / 2) + xdisparity] for of in p.output_fns: of(result) return result
def __call__(self,**params_to_override): p = ParamOverrides(self,params_to_override) shape = SheetCoordinateSystem(p.bounds,p.xdensity,p.ydensity).shape result = p.scale*ones(shape, Float)+p.offset self._apply_mask(p,result) for of in p.output_fns: of(result) return result
def __call__(self, **params_to_override): p = ParamOverrides(self, params_to_override) shape = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity).shape result = self._distrib(shape, p) self._apply_mask(p, result) for of in p.output_fns: of(result) return result
def _setup_xy(self,bounds,xdensity,ydensity,x,y,orientation): """ Produce pattern coordinate matrices from the bounds and density (or rows and cols), and transforms them according to x, y, and orientation. """ self.debug(lambda:"bounds=%s, xdensity=%s, ydensity=%s, x=%s, y=%s, orientation=%s"%(bounds,xdensity,ydensity,x,y,orientation)) # Generate vectors representing coordinates at which the pattern # will be sampled. # CB: note to myself - use slice_._scs if supplied? x_points,y_points = SheetCoordinateSystem(bounds,xdensity,ydensity).sheetcoordinates_of_matrixidx() # Generate matrices of x and y sheet coordinates at which to # sample pattern, at the correct orientation self.pattern_x, self.pattern_y = self._create_and_rotate_coordinate_arrays(x_points-x,y_points-y,orientation)
class PatternSampler(ImageSampler): """ When called, resamples - according to the size_normalization parameter - an image at the supplied (x,y) sheet coordinates. (x,y) coordinates outside the image are returned as the background value. """ whole_pattern_output_fns = param.HookList(class_=TransferFn,default=[],doc=""" Functions to apply to the whole image before any sampling is done.""") background_value_fn = param.Callable(default=None,doc=""" Function to compute an appropriate background value. Must accept an array and return a scalar.""") size_normalization = param.ObjectSelector(default='original', objects=['original','stretch_to_fit','fit_shortest','fit_longest'], doc=""" Determines how the pattern is scaled initially, relative to the default retinal dimension of 1.0 in sheet coordinates: 'stretch_to_fit': scale both dimensions of the pattern so they would fill a Sheet with bounds=BoundingBox(radius=0.5) (disregards the original's aspect ratio). 'fit_shortest': scale the pattern so that its shortest dimension is made to fill the corresponding dimension on a Sheet with bounds=BoundingBox(radius=0.5) (maintains the original's aspect ratio, filling the entire bounding box). 'fit_longest': scale the pattern so that its longest dimension is made to fill the corresponding dimension on a Sheet with bounds=BoundingBox(radius=0.5) (maintains the original's aspect ratio, fitting the image into the bounding box but not necessarily filling it). 'original': no scaling is applied; each pixel of the pattern corresponds to one matrix unit of the Sheet on which the pattern being displayed.""") def _get_image(self): return self.scs.activity def _set_image(self,image): # Stores a SheetCoordinateSystem with an activity matrix # representing the image if not isinstance(image,numpy.ndarray): image = array(image,Float) rows,cols = image.shape self.scs = SheetCoordinateSystem(xdensity=1.0,ydensity=1.0, bounds=BoundingBox(points=((-cols/2.0,-rows/2.0), ( cols/2.0, rows/2.0)))) self.scs.activity=image def _del_image(self): self.scs = None def __call__(self, image, x, y, sheet_xdensity, sheet_ydensity, width=1.0, height=1.0): """ Return pixels from the supplied image at the given Sheet (x,y) coordinates. The image is assumed to be a NumPy array or other object that exports the NumPy buffer interface (i.e. can be converted to a NumPy array by passing it to numpy.array(), e.g. Image.Image). The whole_pattern_output_fns are applied to the image before any sampling is done. To calculate the sample, the image is scaled according to the size_normalization parameter, and any supplied width and height. sheet_xdensity and sheet_ydensity are the xdensity and ydensity of the sheet on which the pattern is to be drawn. """ # CEB: could allow image=None in args and have 'if image is # not None: self.image=image' here to avoid re-initializing the # image. self.image=image for wpof in self.whole_pattern_output_fns: wpof(self.image) if not self.background_value_fn: self.background_value = 0.0 else: self.background_value = self.background_value_fn(self.image) pattern_rows,pattern_cols = self.image.shape if width==0 or height==0 or pattern_cols==0 or pattern_rows==0: return ones(x.shape, Float)*self.background_value # scale the supplied coordinates to match the pattern being at density=1 x=x*sheet_xdensity # deliberately don't operate in place (so as not to change supplied x & y) y=y*sheet_ydensity # scale according to initial pattern size_normalization selected (size_normalization) self.__apply_size_normalization(x,y,sheet_xdensity,sheet_ydensity,self.size_normalization) # scale according to user-specified width and height x/=width y/=height # now sample pattern at the (r,c) corresponding to the supplied (x,y) r,c = self.scs.sheet2matrixidx(x,y) # (where(cond,x,y) evaluates x whether cond is True or False) r.clip(0,pattern_rows-1,out=r) c.clip(0,pattern_cols-1,out=c) left,bottom,right,top = self.scs.bounds.lbrt() return numpy.where((x>=left) & (x<right) & (y>bottom) & (y<=top), self.image[r,c], self.background_value) def __apply_size_normalization(self,x,y,sheet_xdensity,sheet_ydensity,size_normalization): pattern_rows,pattern_cols = self.image.shape # Instead of an if-test, could have a class of this type of # function (c.f. OutputFunctions, etc)... if size_normalization=='original': return elif size_normalization=='stretch_to_fit': x_sf,y_sf = pattern_cols/sheet_xdensity, pattern_rows/sheet_ydensity x*=x_sf; y*=y_sf elif size_normalization=='fit_shortest': if pattern_rows<pattern_cols: sf = pattern_rows/sheet_ydensity else: sf = pattern_cols/sheet_xdensity x*=sf;y*=sf elif size_normalization=='fit_longest': if pattern_rows<pattern_cols: sf = pattern_cols/sheet_xdensity else: sf = pattern_rows/sheet_ydensity x*=sf;y*=sf
def _distrib(self, shape, p): assert ( p.grid_density <= p.xdensity ), 'grid density bigger than pixel density x' assert ( p.grid_density <= p.ydensity), 'grid density bigger than pixel density y' assert ( shape[1] > 0 ), 'Pixel matrix can not be zero' assert ( shape[0] > 0 ), 'Pixel matrix can not be zero' Nx = shape[1] Ny = shape[0] # Size of the pixel matrix SC = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity) unitary_distance_x = SC._SheetCoordinateSystem__xstep unitary_distance_y = SC._SheetCoordinateSystem__ystep sheet_x_size = unitary_distance_x * Nx sheet_y_size = unitary_distance_y * Ny # Sizes of the structure matrix nx = int(round(sheet_x_size * p.grid_density)) # Number of points in the x's ny = int(round(sheet_y_size * p.grid_density)) # Number of points in the y's assert ( nx > 0 ), 'Grid density or bound box in the x dimension too smal' assert ( ny > 0 ), 'Grid density or bound bonx in the y dimension too smal' ps_x = int(round(Nx / nx)) #Closest integer ps_y = int(round(Ny / ny)) # This is the actual matrix of the pixels A = np.ones(shape) * 0.5 if p.grid == False: #The centers of the spots are randomly distributed in space x = p.random_generator.randint(0, Nx - ps_x + 1) y = p.random_generator.randint(0, Ny - ps_y + 1) z = p.random_generator.randint(0,2) # Noise matrix is mapped to the pixel matrix A[x: (x + ps_y), y: (y + ps_x)] = z return A * p.scale + p.offset else: #In case you want the grid if ( Nx % nx == 0) and (Ny % ny == 0): #When the noise grid falls neatly into the the pixel grid x = p.random_generator.randint(0, nx) y = p.random_generator.randint(0, ny) z = p.random_generator.randint(0,2) # Noise matrix is mapped to the pixel matrix (faster method) A[x*ps_y: (x*ps_y + ps_y), y*ps_x: (y*ps_x + ps_x)] = z return A * p.scale + p.offset else: # If noise grid does not fit neatly in the pixel grid (slow method) x_points,y_points = SC.sheetcoordinates_of_matrixidx() # Obtain length of the side and length of the # division line between the grid division_x = 1.0 / p.grid_density division_y = 1.0 / p.grid_density size_of_block_x = Nx * 1.0 / nx size_of_block_y = Ny * 1.0 / ny # Construct the noise matrix Z = np.ones((nx,ny)) * 0.5 x = p.random_generator.randint(0, nx) y = p.random_generator.randint(0, ny) z = p.random_generator.randint(0,2) Z[x,y] = z # Noise matrix is mapped to the pixel matrix for i in range(Nx): for j in range(Ny): # Map along the x coordinates x_entry = int( i / size_of_block_x) y_entry = int( j / size_of_block_y) A[j][i] = Z[x_entry][y_entry] return A * p.scale + p.offset
def _distrib(self, shape, p): assert ( p.grid_density <= p.xdensity ), 'grid density bigger than pixel density x' assert ( p.grid_density <= p.ydensity), 'grid density bigger than pixel density y' assert ( shape[1] > 0 ), 'Pixel matrix can not be zero' assert ( shape[0] > 0 ), 'Pixel matrix can not be zero' Nx = shape[1] Ny = shape[0] # Size of the pixel matrix SC = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity) unitary_distance_x = SC._SheetCoordinateSystem__xstep unitary_distance_y = SC._SheetCoordinateSystem__ystep sheet_x_size = unitary_distance_x * Nx sheet_y_size = unitary_distance_y * Ny # Sizes of the structure matrix nx = int(round(sheet_x_size * p.grid_density)) # Number of points in the x's ny = int(round(sheet_y_size * p.grid_density)) # Number of points in the y's assert ( nx > 0 ), 'Grid density or bound box in the x dimension too smal' assert ( ny > 0 ), 'Grid density or bound bonx in the y dimension too smal' # If the noise grid is proportional to the pixel grid # and fits neatly into it then this method is faster (~100 times faster) if ( Nx % nx == 0) and (Ny % ny == 0): if (Nx == nx) and (Ny == ny): #This is faster to call the whole procedure result = 0.5 * (p.random_generator.randint(-1, 2, shape) + 1) return result * p.scale + p.offset else: # This is the actual matrix of the pixels A = np.zeros(shape) # Noise matrix that contains the structure of 0, 0.5 and 1's Z = 0.5 * (p.random_generator.randint(-1, 2, (nx, ny)) + 1 ) ps_x = int(round(Nx * 1.0/ nx)) #Closest integer ps_y = int(round(Ny * 1.0/ ny)) # Noise matrix is mapped to the pixel matrix for i in range(nx): for j in range(ny): A[i * ps_y: (i + 1) * ps_y, j * ps_x: (j + 1) * ps_x] = Z[i,j] return A * p.scale + p.offset # General method in case the noise grid does not # fall neatly in the pixels grid else: # Obtain length of the side and length of the # division line between the grid x_points,y_points = SC.sheetcoordinates_of_matrixidx() division_x = 1.0 / p.grid_density division_y = 1.0 / p.grid_density # This is the actual matrix of the pixels A = np.zeros(shape) # Noise matrix that contains the structure of 0, 0.5 and 1's Z = 0.5 * (p.random_generator.randint(-1, 2, (nx, ny)) + 1 ) size_of_block_x = Nx * 1.0 / nx size_of_block_y = Ny * 1.0 / ny # Noise matrix is mapped to the pixel matrix for i in range(Nx): for j in range(Ny): # Map along the x coordinates x_entry = int( i / size_of_block_x) y_entry = int( j / size_of_block_y) A[j][i] = Z[x_entry][y_entry] return A * p.scale + p.offset