def __init__(self, src, field, env=None, wkrn=None, consts=None, neighsearch=None, name=None): #check for double names for name0 in field._varnames: for name1 in env._varnames: if name0 == name1: raise NameError('Double names in field and env: ' + name0 + ' - ' + name1 + '. The variable names used in ParticleField and SPHEnv instances must be unique, when used together in a SolverStep.') if name0 == 'neighbors' or name1 == 'neighbors': raise NameError('Use of reserved varibale name: "neigbors".') if name0 == 'wkrn_dcorr' or name1 == 'wkrn_dcorr': raise NameError('Use of reserved varibale name: "wkrn_dcorr".') pre = '' if consts: pre += consts if wkrn: pre += wkrn.src self.clkernel = CLTemplateKernel(pre=pre, src=src, name=name) for name in field._varnames: #get the variables from field's varnames list to preserve their order if isinstance(field.__getattribute__(name), CLVar): if re.search('(^|\W)\$' + name + '\$\W', src): self.clkernel.__setattr__(name, field.__getattribute__(name)) if re.search('(^|\W)\$' + 'neighbors' + '\$\W', src): if neighsearch: self.clkernel.__setattr__('neighbors', neighsearch.neighbors) else: raise NameError('Use of "$neighbors$" in source, but neighsearch not defined.') for name in env._varnames: if isinstance(env.__getattribute__(name), CLVar): if re.search('(^|\W)\$' + name + '\$\W', src): self.clkernel.__setattr__(name, env.__getattribute__(name)) if wkrn: if re.search('(^|\W)\$wkrn_dcorr\$\W', src): self.clkernel.__setattr__('wkrn_dcorr', wkrn.dcorr) self.clkernel.compile()
def __init__(self, posarg, group=None, h=1., maxneighs=100, index=None, indvec=None, neigharray=None): """Initialize fixed radius neighbor search. Neighbors are searched inside a fixed radius specified by h, which defines the cell size in which the spatial domain is divided during searching. The Algorithm uses Z-order indexing and parallel counting sort (see Syncgroup.sort() and ZIndex for details). Input: posarg -- the positional argument, must be a 3d vector, e.g. CLFloat4, CLDouble4 or CLReal4. group -- the Syncgroup posarg belongs to, if not provided an internal group is created (self._group). h -- cell size for the neighbor search. radius = h/2. maxneighs -- maximum neighbor count per item. index -- Z-order index. --> see ZIndex indvec -- spatial index --> see ZIndex neigharray -- array containing neigbors indices of shape( len(posarg), maxneighs). If not specified available as self.neighbors. """ if not group: group = Syncgroup(posarg) if not(posarg in group._vars): raise ValueError('posarg must be member of group.') self._posarg = posarg self._group = group self._maxneighs = CLScalar(maxneighs) self._indexkernel = ZIndex(posarg=posarg, h=h, index=index, indvec=indvec) self._group.add(self._indexkernel._indvec) self._group.setup_sort(index=self._indexkernel._index) self._neighbors = None if neigharray: neigharray.shape = (self._indexkernel._index._value.size, maxneighs) self._neighbors = neigharray else: self._neighbors = CLInt(self._indexkernel._index._value.size, maxneighs) self._grid_length = CLScalar(len(self._group._grid))#, name='__grid_length') self._posarg_length = CLScalar(len(self._posarg))#, name='__posarg_length') src = Neighsearch._find_kern_str src = src.replace('$posarg_length', self._posarg_length.name) src = src.replace('$grid_length', self._grid_length.name) src = src.replace('$posarg', self._posarg.name) src = src.replace('$neighbors', self._neighbors.name) src = src.replace('$ind4', self._indexkernel._indvec.name) src = src.replace('$grid', self._group._grid.name) src = src.replace('$maxneighs', self._maxneighs.name) src = src.replace('$h', self._indexkernel._h.name) varlist = [self._posarg_length, self._grid_length, self._posarg, self._neighbors, self._indexkernel._indvec, self._group._grid, self._maxneighs, self._indexkernel._h] self._findkern = CLKernel(pre=ZIndex._il3_16_src, varlist=varlist, src=src, name='find_neighbors') self._reset_kern = CLTemplateKernel(src=Neighsearch._reset_kern_str, name='reset_neighbors') self._reset_kern.neighbors = self._neighbors self._reset_kern.maxneighs = self._maxneighs self._reset_kern.compile()
def _prepare_nns_f4(self): #prepare for gpu nns dat = self.get_data(cl=True) self._tree_pt = dat[0] self._tree_val = dat[1] self._tree_points = CLReal4() self._tree_points.value = self.points self._query_points = CLReal4() self._neigh_i = CLInt() self._neigh_d = CLReal() self._get_nn_krn = CLTemplateKernel(pre=_PQUEUE_SRC, src=_GET_NN_SRC) self._get_nn_krn.query_points = self._query_points self._get_nn_krn.tree_pt = self._tree_pt self._get_nn_krn.tree_val = self._tree_val self._get_nn_krn.tree_points = self._tree_points self._get_nn_krn.neigh_i = self._neigh_i self._get_nn_krn.neigh_d = self._neigh_d self._get_nn_krn.compile()
def cleanup(self, del_code, ignore_code, part_dens): pos_cl = CLReal4() info_cl = CLInt() shp0_cl = CLScalar(0) shp1_cl = CLScalar(0) shp2_cl = CLScalar(0) minx_cl = CLScalar(0.) miny_cl = CLScalar(0.) minz_cl = CLScalar(0.) maxx_cl = CLScalar(0.) maxy_cl = CLScalar(0.) maxz_cl = CLScalar(0.) is_filled_domain_cl = CLScalar(0) del_code_cl = CLScalar(del_code) ignore_code_cl = CLScalar(ignore_code) vol_cl = CLReal() pos_cl.value = self.pos info_cl.value = self.info spc_cl = CLScalar(0.) offset_cl = CLScalar(0.) offset_inner_cl = CLScalar(0.) partrad_cl = CLScalar(math.pow((1./part_dens)*3./(4.*math.pi), 1./3.)) krn = CLTemplateKernel(pre=_GET_DIST_GRAD_SRC, src=_CLEANUP_SRC) krn.pos = pos_cl krn.info = info_cl krn.shp0 = shp0_cl krn.shp1 = shp1_cl krn.shp2 = shp2_cl krn.minx = minx_cl krn.miny = miny_cl krn.minz = minz_cl krn.maxx = maxx_cl krn.maxy = maxy_cl krn.maxz = maxz_cl krn.is_filled_domain = is_filled_domain_cl krn.del_code = del_code_cl krn.ignore_code = ignore_code_cl krn.vol = vol_cl krn.spc = spc_cl krn.offset = offset_cl krn.offset_inner = offset_inner_cl krn.partrad = partrad_cl krn.compile() for domain in self.domains: if domain.mat_type == del_code: continue if isinstance(domain, SolidBound): is_filled_domain_cl.value = 1 else: is_filled_domain_cl.value = 0 minx_cl.value = domain.voldat.orig[0] miny_cl.value = domain.voldat.orig[1] minz_cl.value = domain.voldat.orig[2] maxx_cl.value = domain.voldat.max[0] maxy_cl.value = domain.voldat.max[1] maxz_cl.value = domain.voldat.max[2] shp0_cl.value = domain.voldat._voxels.shape[2] shp1_cl.value = domain.voldat._voxels.shape[1] shp2_cl.value = domain.voldat._voxels.shape[0] vol_cl.value = domain.voldat._voxels.value spc_cl.value = domain.voldat.spc offset_cl.value = 0. offset_inner_cl.value = -pow(10., 38) if isinstance(domain, SolidBound): offset_cl.value = domain.offset + domain.thick offset_inner_cl.value = domain.offset if isinstance(domain, FluidDomain): offset_cl.value = domain.offset krn() self.pos = pos_cl.value self.info = info_cl.value
def setup_with_particles(particles_in, volume, count, h, spc=1., orig=(0.,0.,0.), offset=0., offset_inner=None, steps=100, fact=0.0001, maxneighs=300): max_x_cl = CLScalar(volume.shape[0]*spc + orig[0]) max_y_cl = CLScalar(volume.shape[1]*spc + orig[1]) max_z_cl = CLScalar(volume.shape[2]*spc + orig[2]) min_x_cl = CLScalar(orig[0]) min_y_cl = CLScalar(orig[1]) min_z_cl = CLScalar(orig[2]) maxneighs_cl = CLScalar(maxneighs) parts_new = rand_particles_in_volume(volume, count, spc=spc, orig=orig, offset=offset, offset_inner=offset_inner) particles_cl = CLReal4() particles_cl.value = np.vstack((parts_new, particles_in)) flag_cl = CLChar() flag_cl.value = np.vstack((np.zeros((len(parts_new),1)), np.ones((len(particles_in),1))))# 1->boundary particle, 0->movable particle grp = Syncgroup(particles_cl, flag_cl) neighsearch = Neighsearch(particles_cl, h=h, maxneighs=int(maxneighs_cl.value), group=grp) neighsearch.search() h_cl = CLScalar(h) fact_cl = CLScalar(fact) kern = CLTemplateKernel(src=_RELAXPART_WITH_PART_SRC) kern.pos = particles_cl kern.flag = flag_cl kern.h = h_cl kern.maxneighs = maxneighs_cl kern.neighbors = neighsearch.neighbors kern.fact = fact_cl kern.max_x = max_x_cl kern.max_y = max_y_cl kern.max_z = max_z_cl kern.min_x = min_x_cl kern.min_y = min_y_cl kern.min_z = min_z_cl kern.compile() print 'Particle initialization' for i in range(steps): neighsearch.search() kern() print 'Step', i+1, 'of', steps parts = particles_cl.value ret = [] flags = flag_cl.value for i in range(len(parts)): if flags[i,0] == 0: ret.append(parts[i]) return np.array(ret)
def setup_in_volume(volume, count, h, spc=1., orig=(0.,0.,0.), offset=0., offset_inner=None, steps=100, fact=0.0001, maxneighs=1000, radius=0.): max_x_cl = CLScalar(volume.shape[0]*spc) max_y_cl = CLScalar(volume.shape[1]*spc) max_z_cl = CLScalar(volume.shape[2]*spc) particles_cl = CLReal4() oi = None if not offset_inner == None: oi = offset_inner - radius particles_cl.value = rand_particles_in_volume(volume, count, spc=spc, orig=(0.,0.,0.), offset=offset + radius, offset_inner=oi) maxneighs_cl = CLScalar(maxneighs) volume.shape = (volume.shape[0],volume.shape[1],volume.shape[2],1) vol_cl = CLReal() vol_cl.value = volume neighsearch = Neighsearch(particles_cl, h=h, maxneighs=int(maxneighs_cl.value)) neighsearch.search() h_cl = CLScalar(h) fact_cl = CLScalar(fact) vol_shp0_cl = CLScalar(volume.shape[0]) vol_shp1_cl = CLScalar(volume.shape[1]) vol_shp2_cl = CLScalar(volume.shape[2]) offset_cl = CLScalar(offset) if offset_inner == None: offset_inner = -pow(10., 38) offset_inner_cl = CLScalar(offset_inner) print "offsets: ", offset_cl, offset_inner_cl gradient_cl = CLReal4() gradient_cl.value = gradient_field(volume) kern = CLTemplateKernel(src=_RELAXPART_SRC, pre=_GET_DIST_GRAD_SRC) kern.pos = particles_cl kern.h = h_cl kern.maxneighs = maxneighs_cl kern.neighbors = neighsearch.neighbors kern.fact = fact_cl kern.volume = vol_cl kern.spacing = CLScalar(spc) kern.vol_shp0 = vol_shp0_cl kern.vol_shp1 = vol_shp1_cl kern.vol_shp2 = vol_shp2_cl kern.offset = offset_cl kern.offset_inner = offset_inner_cl kern.gradient = gradient_cl kern.max_x = max_x_cl kern.max_y = max_y_cl kern.max_z = max_z_cl kern.compile() print 'Particle initialization' for i in range(steps): neighsearch.search() kern() kern.finish() print 'Step', i+1, 'of', steps ret = particles_cl.value ret[:,0] += orig[0] ret[:,1] += orig[1] ret[:,2] += orig[2] return ret
class Neighsearch(object): _find_kern_pre = """ int gid = get_global_id(0) + get_global_id(1)*get_global_size(0) + get_global_id(2)*get_global_size(0)*get_global_size(1); int gsz = get_global_size(0)*get_global_size(1)*get_global_size(2); int xind = $ind4[gid].s0; int yind = $ind4[gid].s1; int zind = $ind4[gid].s2; real4 this_pos = $posarg[gid]; int id, xc, yc, zc, start; start = 0; int counter = 0; """ _find_kern_body = """ id = interleave3_16(xind + xc, yind + yc, zind + zc); if ((id < $grid_length) && (id >= 0)){ start = $grid[id] - 1; int len_cell = 0; if (id == 0){ len_cell = start + 1; }else{ len_cell = (start + 1) - $grid[id - 1]; } if ((start >= 0) && (start < $posarg_length)){ for (int i = 0; i < len_cell; i++){ if (counter < $maxneighs){ int other_id = start - i; if (other_id != gid){ real dist = length(this_pos - $posarg[other_id]); if (dist < $h){ $neighbors[gid*$maxneighs + counter] = other_id; counter++; } } } } } } """ _find_kern_str = "" _find_kern_str += _find_kern_pre for i in range(3): for j in range(3): for k in range(3): _find_kern_str += 'xc = ' + str(i - 1) + ';\n' _find_kern_str += 'yc = ' + str(j - 1) + ';\n' _find_kern_str += 'zc = ' + str(k - 1) + ';\n\n' _find_kern_str += _find_kern_body _reset_kern_str = """ int gid = get_global_id(0) + get_global_id(1)*get_global_size(0) + get_global_id(2)*get_global_size(0)*get_global_size(1); $neighbors$[gid] = -1; """ def __init__(self, posarg, group=None, h=1., maxneighs=100, index=None, indvec=None, neigharray=None): """Initialize fixed radius neighbor search. Neighbors are searched inside a fixed radius specified by h, which defines the cell size in which the spatial domain is divided during searching. The Algorithm uses Z-order indexing and parallel counting sort (see Syncgroup.sort() and ZIndex for details). Input: posarg -- the positional argument, must be a 3d vector, e.g. CLFloat4, CLDouble4 or CLReal4. group -- the Syncgroup posarg belongs to, if not provided an internal group is created (self._group). h -- cell size for the neighbor search. radius = h/2. maxneighs -- maximum neighbor count per item. index -- Z-order index. --> see ZIndex indvec -- spatial index --> see ZIndex neigharray -- array containing neigbors indices of shape( len(posarg), maxneighs). If not specified available as self.neighbors. """ if not group: group = Syncgroup(posarg) if not(posarg in group._vars): raise ValueError('posarg must be member of group.') self._posarg = posarg self._group = group self._maxneighs = CLScalar(maxneighs) self._indexkernel = ZIndex(posarg=posarg, h=h, index=index, indvec=indvec) self._group.add(self._indexkernel._indvec) self._group.setup_sort(index=self._indexkernel._index) self._neighbors = None if neigharray: neigharray.shape = (self._indexkernel._index._value.size, maxneighs) self._neighbors = neigharray else: self._neighbors = CLInt(self._indexkernel._index._value.size, maxneighs) self._grid_length = CLScalar(len(self._group._grid))#, name='__grid_length') self._posarg_length = CLScalar(len(self._posarg))#, name='__posarg_length') src = Neighsearch._find_kern_str src = src.replace('$posarg_length', self._posarg_length.name) src = src.replace('$grid_length', self._grid_length.name) src = src.replace('$posarg', self._posarg.name) src = src.replace('$neighbors', self._neighbors.name) src = src.replace('$ind4', self._indexkernel._indvec.name) src = src.replace('$grid', self._group._grid.name) src = src.replace('$maxneighs', self._maxneighs.name) src = src.replace('$h', self._indexkernel._h.name) varlist = [self._posarg_length, self._grid_length, self._posarg, self._neighbors, self._indexkernel._indvec, self._group._grid, self._maxneighs, self._indexkernel._h] self._findkern = CLKernel(pre=ZIndex._il3_16_src, varlist=varlist, src=src, name='find_neighbors') self._reset_kern = CLTemplateKernel(src=Neighsearch._reset_kern_str, name='reset_neighbors') self._reset_kern.neighbors = self._neighbors self._reset_kern.maxneighs = self._maxneighs self._reset_kern.compile() @property def neighbors(self): return self._neighbors @timing def search(self, h=None, maxneighs=None): self._indexkernel(h=h) if maxneighs: self._maxneighs.value = maxneighs self._neighbors.set_shape_wo_read( (self._indexkernel._index._value.size, maxneighs) ) elif not(self._indexkernel._index._value.size == self._neighbors.shape[0]): self._neighbors.set_shape_wo_read( (self._indexkernel._index._value.size, self._maxneighs.value) ) self._reset_kern() self._group.sort() self._grid_length.value = len(self._group._grid) self._posarg_length.value = len(self._posarg) self._findkern() def info(self): return self._indexkernel.info()
class Kd_tree(KD_node): def __init__(self, pts, ndim=None): points = np.array(pts) self.points = pts self.node_count = 0 if len(points) < 2: raise ValueError('Length of array must be > 1.') else: if ndim==None: ndim = len(points[0]) indices = np.arange(len(points)) super(Kd_tree, self).__init__((points,indices), ndim, self, self) #print 'done' def _prepare_nns_f4(self): #prepare for gpu nns dat = self.get_data(cl=True) self._tree_pt = dat[0] self._tree_val = dat[1] self._tree_points = CLReal4() self._tree_points.value = self.points self._query_points = CLReal4() self._neigh_i = CLInt() self._neigh_d = CLReal() self._get_nn_krn = CLTemplateKernel(pre=_PQUEUE_SRC, src=_GET_NN_SRC) self._get_nn_krn.query_points = self._query_points self._get_nn_krn.tree_pt = self._tree_pt self._get_nn_krn.tree_val = self._tree_val self._get_nn_krn.tree_points = self._tree_points self._get_nn_krn.neigh_i = self._neigh_i self._get_nn_krn.neigh_d = self._neigh_d self._get_nn_krn.compile() def get_nn_r4(self, pts): self._prepare_nns_f4() neighs = np.zeros((len(pts),1), np.int32) dists = np.zeros((len(pts),1), np.float64) self._neigh_i.value = neighs self._neigh_d.value = dists self._query_points.value = pts self._get_nn_krn() return self._neigh_i.value, self._neigh_d.value def get_data(self, cl=False): pointer = np.zeros(self.node_count*8, np.int32) val = np.zeros(self.node_count*3, np.float64) super(Kd_tree, self).get_data(pointer, val) if cl: p = CLInt(len(pointer)) pointer.shape = (len(pointer),1) p.value = pointer v = CLReal(len(val)) val.shape = (len(val),1) v.value = val return p, v else: return pointer, val def get_nn_rec(self, qpts, ndim=None): if ndim==None: ndim = len(qpts[0]) nn = np.zeros(len(qpts), np.int32) i = 0 for q_pt in qpts: #print 'begin rec query for point', q_pt closest = -1 near_dist = np.array([1.01*10**37]) self.rec_search_nn(q_pt, i, near_dist, closest, self.points, nn, ndim) i += 1 return nn def iter_search_nn(self, qpts, ndim=None): if ndim==None: ndim = len(qpts[0]) nn = [] dists = [] for q_pt in qpts: near_dist = np.array([1.1*10**37]) closest = np.array([-1]) queue = Queue() queue.insert(self, 0.) #print 'starting priority kd nn query' while not queue.is_empty(): entr = queue.extr_min() cur_node = entr[0] the_dist = entr[1] #print '\nextracted node', cur_node.id, 'from queue' if the_dist >= near_dist[0]: #print 'the distance to this node is bigger or equal (', the_dist, ' >=', near_dist[0], ') than the current nearest...done!' break while not (cur_node == None): if cur_node.is_leaf: #print 'node', cur_node.id, 'is a leaf!' p = self.points[cur_node.pt] d = 0. for i in range(ndim): d += (q_pt[i] - p[i])**2 if d < near_dist[0]: #print 'd=', d, '<', near_dist[0], '(current)' near_dist[0] = d closest[0] = cur_node.pt else: #print 'd=', d, '>=', near_dist[0], '(current)' pass cur_node = None else: #print 'inspecting node', cur_node.id cdim = cur_node.cdim cval = cur_node.cval this_offset = q_pt[cdim] - cval #print 'point', q_pt, ', cdim', cdim, ', cval', cval, '--> offset=', this_offset if (this_offset <= 0.): #print 'going to lo child -> node', cur_node.lo.id #print 'inserting further child', cur_node.hi.id, 'into queue' queue.insert(cur_node.hi, this_offset*this_offset) cur_node = cur_node.lo else: #print 'going to hi child -> node', cur_node.hi.id #print 'inserting further child', cur_node.lo.id, 'into queue' queue.insert(cur_node.lo, this_offset*this_offset) cur_node = cur_node.hi nn.append(closest) dists.append(math.sqrt(near_dist[0])) return np.array(nn).flatten(), np.array(dists) def printout(self): super(Kd_tree, self).printout(space='', points=self.points)
def __init__(self, filename): self.filename = filename self.rgb_orig_np4 = None self.rgb = CLUChar4() self.lab = CLReal4() self.cluster_xy = CLInt2() self.cluster_lab = CLReal4() self.new_cluster_xy = CLInt2() self.new_cluster_lab = CLReal4() self.diff = CLUChar() self.label_map_np = None self.final_lbl_cnt = None rgb = io.imread(filename) rgb_shp = np.zeros((rgb.shape[0], rgb.shape[1], rgb.shape[2] + 1)) rgb_shp[:,:,0:3] = rgb self.rgb_orig_np4 = np.array(rgb_shp, dtype=np.uint8) lab = color.rgb2lab(rgb) lab_shp = np.zeros((lab.shape[0], lab.shape[1], lab.shape[2] + 1)) lab_shp[:,:,0:3] = lab self.img_shape = (rgb.shape[0], rgb.shape[1]) self.rgb.value = self.rgb_orig_np4 self.lab.value = lab_shp self.labels = CLInt(self.lab.shape[0], self.lab.shape[1]) self.k = CLScalar(0) self.m = CLScalar(0.) self.interval = CLScalar(0) self.frame = CLScalar(3) self.img_sz0 = CLScalar(self.lab.shape[1]) self.img_sz1 = CLScalar(self.lab.shape[0]) self.clus_sz0 = CLScalar(0) self.clus_sz1 = CLScalar(0) self.colors_cl = CLUChar4() self.len_colors = CLScalar(0) self.set_center = CLTemplateKernel(src=SET_CENTER_SRC) self.set_center.cluster_xy = self.cluster_xy self.set_center.cluster_lab = self.cluster_lab self.set_center.img = self.lab self.set_center.interval = self.interval self.set_center.frame = self.frame self.set_center.img_sz0 = self.img_sz0 self.set_center.img_sz1 = self.img_sz1 self.set_center.compile() self.label_px = CLTemplateKernel(src=LABEL_PIXELS) self.label_px.img = self.lab self.label_px.cluster_xy = self.cluster_xy self.label_px.cluster_lab = self.cluster_lab self.label_px.interval = self.interval self.label_px.clus_sz0 = self.clus_sz0 self.label_px.clus_sz1 = self.clus_sz1 self.label_px.m = self.m self.label_px.compile() self.mark_border_krn = CLTemplateKernel(src=MARK_BORDER_SRC) self.mark_border_krn.img = self.lab self.mark_border_krn.compile() self.sum_new_ctrs = CLTemplateKernel(src=SUM_NEW_CTRS_SRC) self.sum_new_ctrs.new_clus_lab = self.new_cluster_lab self.sum_new_ctrs.new_clus_xy = self.new_cluster_xy self.sum_new_ctrs.img = self.lab self.sum_new_ctrs.interval = self.interval self.sum_new_ctrs.img_sz0 = self.img_sz0 self.sum_new_ctrs.img_sz1 = self.img_sz1 self.sum_new_ctrs.compile() self.set_new_ctrs = CLTemplateKernel(src=SET_NEW_CTRS_SRC) self.set_new_ctrs.new_clus_lab = self.new_cluster_lab self.set_new_ctrs.new_clus_xy = self.new_cluster_xy self.set_new_ctrs.cluster_lab = self.cluster_lab self.set_new_ctrs.cluster_xy = self.cluster_xy self.set_new_ctrs.diff = self.diff self.set_new_ctrs.compile() self.make_mean_krn = CLTemplateKernel(src=MAKE_MEAN_SRC) self.make_mean_krn.cluster_lab = self.cluster_lab self.make_mean_krn.cluster_xy = self.cluster_xy self.make_mean_krn.img = self.lab self.make_mean_krn.interval = self.interval self.make_mean_krn.img_sz0 = self.img_sz0 self.make_mean_krn.img_sz1 = self.img_sz1 self.make_mean_krn.compile() self.colorize_krn = CLTemplateKernel(src=COLORIZE_SRC) self.colorize_krn.img = self.rgb self.colorize_krn.len_colors = self.len_colors self.colorize_krn.colors = self.colors_cl self.colorize_krn.compile()
class Slic(object): def __init__(self, filename): self.filename = filename self.rgb_orig_np4 = None self.rgb = CLUChar4() self.lab = CLReal4() self.cluster_xy = CLInt2() self.cluster_lab = CLReal4() self.new_cluster_xy = CLInt2() self.new_cluster_lab = CLReal4() self.diff = CLUChar() self.label_map_np = None self.final_lbl_cnt = None rgb = io.imread(filename) rgb_shp = np.zeros((rgb.shape[0], rgb.shape[1], rgb.shape[2] + 1)) rgb_shp[:,:,0:3] = rgb self.rgb_orig_np4 = np.array(rgb_shp, dtype=np.uint8) lab = color.rgb2lab(rgb) lab_shp = np.zeros((lab.shape[0], lab.shape[1], lab.shape[2] + 1)) lab_shp[:,:,0:3] = lab self.img_shape = (rgb.shape[0], rgb.shape[1]) self.rgb.value = self.rgb_orig_np4 self.lab.value = lab_shp self.labels = CLInt(self.lab.shape[0], self.lab.shape[1]) self.k = CLScalar(0) self.m = CLScalar(0.) self.interval = CLScalar(0) self.frame = CLScalar(3) self.img_sz0 = CLScalar(self.lab.shape[1]) self.img_sz1 = CLScalar(self.lab.shape[0]) self.clus_sz0 = CLScalar(0) self.clus_sz1 = CLScalar(0) self.colors_cl = CLUChar4() self.len_colors = CLScalar(0) self.set_center = CLTemplateKernel(src=SET_CENTER_SRC) self.set_center.cluster_xy = self.cluster_xy self.set_center.cluster_lab = self.cluster_lab self.set_center.img = self.lab self.set_center.interval = self.interval self.set_center.frame = self.frame self.set_center.img_sz0 = self.img_sz0 self.set_center.img_sz1 = self.img_sz1 self.set_center.compile() self.label_px = CLTemplateKernel(src=LABEL_PIXELS) self.label_px.img = self.lab self.label_px.cluster_xy = self.cluster_xy self.label_px.cluster_lab = self.cluster_lab self.label_px.interval = self.interval self.label_px.clus_sz0 = self.clus_sz0 self.label_px.clus_sz1 = self.clus_sz1 self.label_px.m = self.m self.label_px.compile() self.mark_border_krn = CLTemplateKernel(src=MARK_BORDER_SRC) self.mark_border_krn.img = self.lab self.mark_border_krn.compile() self.sum_new_ctrs = CLTemplateKernel(src=SUM_NEW_CTRS_SRC) self.sum_new_ctrs.new_clus_lab = self.new_cluster_lab self.sum_new_ctrs.new_clus_xy = self.new_cluster_xy self.sum_new_ctrs.img = self.lab self.sum_new_ctrs.interval = self.interval self.sum_new_ctrs.img_sz0 = self.img_sz0 self.sum_new_ctrs.img_sz1 = self.img_sz1 self.sum_new_ctrs.compile() self.set_new_ctrs = CLTemplateKernel(src=SET_NEW_CTRS_SRC) self.set_new_ctrs.new_clus_lab = self.new_cluster_lab self.set_new_ctrs.new_clus_xy = self.new_cluster_xy self.set_new_ctrs.cluster_lab = self.cluster_lab self.set_new_ctrs.cluster_xy = self.cluster_xy self.set_new_ctrs.diff = self.diff self.set_new_ctrs.compile() self.make_mean_krn = CLTemplateKernel(src=MAKE_MEAN_SRC) self.make_mean_krn.cluster_lab = self.cluster_lab self.make_mean_krn.cluster_xy = self.cluster_xy self.make_mean_krn.img = self.lab self.make_mean_krn.interval = self.interval self.make_mean_krn.img_sz0 = self.img_sz0 self.make_mean_krn.img_sz1 = self.img_sz1 self.make_mean_krn.compile() self.colorize_krn = CLTemplateKernel(src=COLORIZE_SRC) self.colorize_krn.img = self.rgb self.colorize_krn.len_colors = self.len_colors self.colorize_krn.colors = self.colors_cl self.colorize_krn.compile() def enf_conn_c(self): width = int(self.lab.shape[1]) height = int(self.lab.shape[0]) k = int(self.k.value) labels = np.zeros(self.lab.shape, np.int32) labval = self.lab.value labels[:,:] = labval[:,:,3] nlabels, numLabels = enf_conn.enforce_connectivity(labels.flatten(), width, height, k) nlabels.shape = self.lab.shape labval[:,:,3] = nlabels self.label_map_np = nlabels self.lab.value = labval self.final_lbl_cnt = numLabels def sync_buffers_from_lab(self): lab = self.lab.value rgb = color.lab2rgb(lab[:,:,:3]) rgb *= 255 rgb_ = np.zeros((rgb.shape[0], rgb.shape[1], 4), dtype=np.uint8) rgb_[:,:,:3] = rgb[:,:,:3] self.rgb.value = rgb_ def sync_buffers_from_rgb(self): rgb = self.rgb.value lab = color.rgb2lab(rgb[:,:,:3]) lab_ = np.zeros((lab.shape[0], lab.shape[1], 4), dtype=np.float64) lab_[:,:,:3] = lab[:,:,:3] if not self.label_map_np == None: lab_[:,:,3] = self.label_map_np[:,:] self.lab.value = lab_ def segment(self, k, m): self.k.value = k self.m.value = m self.interval.value = sqrt(self.lab.shape[0]*self.lab.shape[1]/k) self.frame.value = max(self.interval.value/2, 3) shp_cp = (((self.img_shape[0] - self.frame.value - 2)/self.interval.value + 1), ((self.img_shape[1] - self.frame.value - 2)/self.interval.value + 1)) #using 'self.img_shape[1] - self.frame.value - 2' to prevent centers beeing placed at image edges self.cluster_lab.value = np.zeros(shp_cp + (4,), np.float64) self.cluster_xy.value = np.zeros(shp_cp + (2,), np.int32) self.new_cluster_lab.value = np.zeros(shp_cp + (4,), np.float64) self.new_cluster_xy.value = np.zeros(shp_cp + (2,), np.int32) self.diff.value = np.zeros(shp_cp + (1,), np.uint8) self.clus_sz0.value = shp_cp[1] self.clus_sz1.value = shp_cp[0] #begin slic self.set_center() self.label_px() self.sum_new_ctrs() self.set_new_ctrs() #re-run until convergence cnt = 0 while not(max_reduce(self.diff) == 0): self.label_px() self.sum_new_ctrs() self.set_new_ctrs() cnt += 1 self.enf_conn_c() self.sync_buffers_from_lab() def make_mean(self): if self.final_lbl_cnt == None: print 'Image not segmented.' return mean_labs = np.zeros((self.final_lbl_cnt,4), np.float64) labval = self.lab.value for i in range(self.lab.shape[0]): for j in range(self.lab.shape[1]): theval = np.array(labval[i,j]) label = int(theval[3]) theval[3] = 1. mean_labs[label] += theval mean_labs[:,0] /= mean_labs[:,3] mean_labs[:,1] /= mean_labs[:,3] mean_labs[:,2] /= mean_labs[:,3] for i in range(self.lab.shape[0]): for j in range(self.lab.shape[1]): label = int(labval[i,j,3]) newval = np.array(mean_labs[label]) newval[3] = label labval[i,j] = newval self.lab.value = labval self.sync_buffers_from_lab() def colorize(self, colors): col_np = np.zeros((len(colors),4), np.uint8) i = 0 for col in colors: col_np[i,0] = col[0] col_np[i,1] = col[1] col_np[i,2] = col[2] i += 1 self.colors_cl.value = col_np self.len_colors.value = len(col_np) self.colorize_krn() self.sync_buffers_from_rgb() def get_mean_seg_img(self): mean_labs = np.zeros((self.final_lbl_cnt,4), np.float64) labval = self.lab.value for i in range(self.lab.shape[0]): for j in range(self.lab.shape[1]): theval = np.array(labval[i,j]) label = int(theval[3]) theval[3] = 1. mean_labs[label] += theval mean_labs[:,0] /= mean_labs[:,3] mean_labs[:,1] /= mean_labs[:,3] mean_labs[:,2] /= mean_labs[:,3] for i in range(self.lab.shape[0]): for j in range(self.lab.shape[1]): label = int(labval[i,j,3]) newval = np.array(mean_labs[label]) newval[3] = label labval[i,j] = newval return labval def get_labels(self): return np.array(self.label_map_np) def mark_border(self): self.mark_border_krn() self.sync_buffers_from_lab() def reload_rgb_orig(self): rgb = self.rgb.value rgb[:,:,:] = self.rgb_orig_np4[:,:,:] self.rgb.value = rgb self.sync_buffers_from_rgb() def show(self): img_val = self.rgb.value img = np.zeros((img_val.shape[0], img_val.shape[1], 3)) img[:,:,:] = img_val[:,:,0:3] plt.imshow(self.rgb.value[:,:,0:3]) def save(self, fn=None): img_val = self.rgb.value img = np.zeros((img_val.shape[0], img_val.shape[1], 3)) img[:,:,:] = img_val[:,:,0:3] img[:,:,0] /= np.amax(img[:,:,0]) img[:,:,1] /= np.amax(img[:,:,1]) img[:,:,2] /= np.amax(img[:,:,2]) if fn == None: fn = self.filename[:-4] + '_slic.png' io.imsave(fn, img) def get_img_rgb(self): return self.rgb.value[:,:,:3]
def __init__(self): self._voxels = CLReal(1,1,1) self._vpoints = CLReal4(1,1,1) self._minx = CLScalar(0.) self._miny = CLScalar(0.) self._minz = CLScalar(0.) self._spacing = CLScalar(0.) self._delta = CLScalar(0.001) self._vert = CLReal4() self._tri = CLUInt4() self._vert_length = CLScalar(0) self._tri_length = CLScalar(0) self._trinorm = CLReal4() self._enorm = CLReal4() self._awp = CLReal4() self._points_df = CLReal4() self._norm_df = CLReal4() self._points_inner = CLReal4() self._points_outer = CLReal4() self._points_length = CLScalar(0) self._epsilon = CLScalar(0.01) self._n_points = CLUInt() # nb of generated points for each triangle self._n_side = CLUInt() # nb of divisions per edge for each triangle self._dist_inner = CLReal() self._dist_outer = CLReal() # init trinorm_kernel self._trinorm_kern = CLTemplateKernel(src=_TRINORM_KRN) self._trinorm_kern.tri = self._tri self._trinorm_kern.trinorm = self._trinorm self._trinorm_kern.vert = self._vert self._trinorm_kern.vert_length = self._vert_length self._trinorm_kern.tri_length = self._tri_length self._trinorm_kern.compile() # init enorm_kernel self._enorm_kern = CLTemplateKernel(src=_ENORM_KRN) self._enorm_kern.tri = self._tri self._enorm_kern.tri_length = self._tri_length self._enorm_kern.trinorm = self._trinorm self._enorm_kern.enorm = self._enorm self._enorm_kern.compile() # init awp_kernel self._awp_kern = CLTemplateKernel(src=_AWP_KRN) self._awp_kern.awp = self._awp self._awp_kern.tri = self._tri self._awp_kern.tri_length = self._tri_length self._awp_kern.vert = self._vert self._awp_kern.vert_length = self._vert_length self._awp_kern.trinorm = self._trinorm self._awp_kern.enorm = self._enorm self._awp_kern.compile() # init _prec_arlen_kern self._prec_arlen_kern = CLTemplateKernel(src=_PREC_ARLEN_SRC) self._prec_arlen_kern.tri = self._tri self._prec_arlen_kern.vert = self._vert self._prec_arlen_kern.epsilon = self._epsilon self._prec_arlen_kern.n_points = self._n_points self._prec_arlen_kern.n_side = self._n_side self._prec_arlen_kern.tri_length = self._tri_length self._prec_arlen_kern.compile() # init _cmp_layers_kern self._cmp_layers_kern = CLTemplateKernel(src=_COMP_LAYERS_SRC) self._cmp_layers_kern.tri = self._tri self._cmp_layers_kern.vert = self._vert self._cmp_layers_kern.trinorm = self._trinorm self._cmp_layers_kern.n_side = self._n_side self._cmp_layers_kern.n_points_scan = self._n_points self._cmp_layers_kern.outer_layer = self._points_outer self._cmp_layers_kern.inner_layer = self._points_inner self._cmp_layers_kern.delta = self._delta self._cmp_layers_kern.tri_length = self._tri_length self._cmp_layers_kern.vert_length = self._vert_length self._cmp_layers_kern.compile() # init cmp_pts kernel self._cmp_pts_kern = CLTemplateKernel(src=_CMP_PTS_SRC) self._cmp_pts_kern.vpoints = self._vpoints self._cmp_pts_kern.minx = self._minx self._cmp_pts_kern.miny = self._miny self._cmp_pts_kern.minz = self._minz self._cmp_pts_kern.spacing = self._spacing self._cmp_pts_kern.compile() # cmp df self._cmp_df_kern = CLTemplateKernel(src=_CMP_DF_SRC) self._cmp_df_kern.dist_inner = self._dist_inner self._cmp_df_kern.dist_outer = self._dist_outer self._cmp_df_kern.delta = self._delta self._cmp_df_kern.voxels = self._voxels self._cmp_df_kern.compile()
class TrimeshVoxelizer(object): def __init__(self): self._voxels = CLReal(1,1,1) self._vpoints = CLReal4(1,1,1) self._minx = CLScalar(0.) self._miny = CLScalar(0.) self._minz = CLScalar(0.) self._spacing = CLScalar(0.) self._delta = CLScalar(0.001) self._vert = CLReal4() self._tri = CLUInt4() self._vert_length = CLScalar(0) self._tri_length = CLScalar(0) self._trinorm = CLReal4() self._enorm = CLReal4() self._awp = CLReal4() self._points_df = CLReal4() self._norm_df = CLReal4() self._points_inner = CLReal4() self._points_outer = CLReal4() self._points_length = CLScalar(0) self._epsilon = CLScalar(0.01) self._n_points = CLUInt() # nb of generated points for each triangle self._n_side = CLUInt() # nb of divisions per edge for each triangle self._dist_inner = CLReal() self._dist_outer = CLReal() # init trinorm_kernel self._trinorm_kern = CLTemplateKernel(src=_TRINORM_KRN) self._trinorm_kern.tri = self._tri self._trinorm_kern.trinorm = self._trinorm self._trinorm_kern.vert = self._vert self._trinorm_kern.vert_length = self._vert_length self._trinorm_kern.tri_length = self._tri_length self._trinorm_kern.compile() # init enorm_kernel self._enorm_kern = CLTemplateKernel(src=_ENORM_KRN) self._enorm_kern.tri = self._tri self._enorm_kern.tri_length = self._tri_length self._enorm_kern.trinorm = self._trinorm self._enorm_kern.enorm = self._enorm self._enorm_kern.compile() # init awp_kernel self._awp_kern = CLTemplateKernel(src=_AWP_KRN) self._awp_kern.awp = self._awp self._awp_kern.tri = self._tri self._awp_kern.tri_length = self._tri_length self._awp_kern.vert = self._vert self._awp_kern.vert_length = self._vert_length self._awp_kern.trinorm = self._trinorm self._awp_kern.enorm = self._enorm self._awp_kern.compile() # init _prec_arlen_kern self._prec_arlen_kern = CLTemplateKernel(src=_PREC_ARLEN_SRC) self._prec_arlen_kern.tri = self._tri self._prec_arlen_kern.vert = self._vert self._prec_arlen_kern.epsilon = self._epsilon self._prec_arlen_kern.n_points = self._n_points self._prec_arlen_kern.n_side = self._n_side self._prec_arlen_kern.tri_length = self._tri_length self._prec_arlen_kern.compile() # init _cmp_layers_kern self._cmp_layers_kern = CLTemplateKernel(src=_COMP_LAYERS_SRC) self._cmp_layers_kern.tri = self._tri self._cmp_layers_kern.vert = self._vert self._cmp_layers_kern.trinorm = self._trinorm self._cmp_layers_kern.n_side = self._n_side self._cmp_layers_kern.n_points_scan = self._n_points self._cmp_layers_kern.outer_layer = self._points_outer self._cmp_layers_kern.inner_layer = self._points_inner self._cmp_layers_kern.delta = self._delta self._cmp_layers_kern.tri_length = self._tri_length self._cmp_layers_kern.vert_length = self._vert_length self._cmp_layers_kern.compile() # init cmp_pts kernel self._cmp_pts_kern = CLTemplateKernel(src=_CMP_PTS_SRC) self._cmp_pts_kern.vpoints = self._vpoints self._cmp_pts_kern.minx = self._minx self._cmp_pts_kern.miny = self._miny self._cmp_pts_kern.minz = self._minz self._cmp_pts_kern.spacing = self._spacing self._cmp_pts_kern.compile() # cmp df self._cmp_df_kern = CLTemplateKernel(src=_CMP_DF_SRC) self._cmp_df_kern.dist_inner = self._dist_inner self._cmp_df_kern.dist_outer = self._dist_outer self._cmp_df_kern.delta = self._delta self._cmp_df_kern.voxels = self._voxels self._cmp_df_kern.compile() @property def minx(self): return self._minx.value @minx.setter def minx(self, val): self._minx.value = val @property def miny(self): return self._miny.value @miny.setter def miny(self, val): self._miny.value = val @property def minz(self): return self._minz.value @minz.setter def minz(self, val): self._minz.value = val @property def spacing(self): return self._spacing.value @spacing.setter def spacing(self, val): self._spacing.value = val @property def voxels(self): return self._voxels.value @voxels.setter def voxels(self, val): self._voxels.value = val @property def vert(self): return self._vert.value @vert.setter def vert(self, val): self._vert.value = val self._vert_length.value = len(val) self._awp.shape = (len(val),) @property def tri(self): return self._tri.value @tri.setter def tri(self, val): self._tri.value = val self._tri_length.value = len(val) self._trinorm.shape = (len(val),) self._enorm.shape = (len(val)*3,) self._n_points.shape = (len(val),) self._n_side.shape = (len(val),) @property def trinorm(self): return self._trinorm.value @trinorm.setter def trinorm(self, val): self._trinorm.value = val @property def enorm(self): return self._enorm.value @enorm.setter def enorm(self, val): self._enorm.value = val @property def awp(self): return self._awp.value @awp.setter def awp(self, val): self._awp.value = val def _compute_normals(self): self._trinorm_kern() self._enorm_kern() self._awp_kern() def _compute_pointlayers(self, epsilon, delta): self._compute_normals() self._epsilon.value = epsilon self._delta.value = delta self._prec_arlen_kern() lenlay = np.sum(self._n_points.value) self._points_inner.shape = (lenlay,) self._points_outer.shape = (lenlay,) self._points_length.value = lenlay scan_uint(self._n_points) self._cmp_layers_kern() def compute_volume(self, epsilon, delta, res=1, framewidth=0.): # compute layers self._compute_pointlayers(epsilon, delta) #gather geometry information and init voxels minx = np.amin(self.vert[:,0]) miny = np.amin(self.vert[:,1]) minz = np.amin(self.vert[:,2]) maxx = np.amax(self.vert[:,0]) maxy = np.amax(self.vert[:,1]) maxz = np.amax(self.vert[:,2]) width = maxx - minx height = maxy - miny depth = maxz - minz dims = 0, 0, 0 if (width <= height) and (width <= depth): dims = res, int(ceil(res*(height/width))), int(ceil(res*(depth/width))) self._spacing.value = width/dims[0] if (height <= width) and (height <= depth): dims = int(ceil(res*(width/height))), res, int(ceil(res*(depth/height))) self._spacing.value = height/dims[1] if (depth <= width) and (depth <= height): dims = int(ceil(res*(width/depth))), int(ceil(res*(height/depth))), res self._spacing.value = depth/dims[2] addcells = int(res*framewidth) dims = dims[0] + 2*addcells, dims[1] + 2*addcells, dims[2] + 2*addcells self._minx.value = minx - addcells*self._spacing.value self._miny.value = miny - addcells*self._spacing.value self._minz.value = minz - addcells*self._spacing.value self._voxels.shape = dims[::-1] self._vpoints.shape = dims[::-1] self._df_tree(delta) def _df_tree(self, delta): print 'constructing tree1' tree_inner = KD_tree(self._points_inner.value) print 'constructing tree2' tree_outer = KD_tree(self._points_outer.value) self._cmp_pts_kern() vox_pts = np.zeros((self._voxels._value.size,4)) vox_pts = self._vpoints.value vox_pts.shape = (vox_pts.shape[0]*vox_pts.shape[1]*vox_pts.shape[2], 4) print 'getting nn from tree1' nn_dat_inner = tree_inner.get_nn(vox_pts) print 'getting nn from tree2' nn_dat_outer = tree_outer.get_nn(vox_pts) self._dist_inner.value = nn_dat_inner[1] self._dist_outer.value = nn_dat_outer[1] self._cmp_df_kern() def get_df_as_points(self, offset=0.): voxels = self.voxels pointlist = [] distlist = [] for x in range(voxels.shape[2]): for y in range(voxels.shape[1]): for z in range(voxels.shape[0]): dist = voxels[z,y,x][0] #numpy order is z,y,x !!! if dist < offset: pointlist.append([x*self._spacing.value, y*self._spacing.value, z*self._spacing.value, 0.]) distlist.append(dist) points = np.array(pointlist) points.shape = (len(points),4) dists = np.array(distlist) dists.shape = (len(dists),1) return points, dists def get_voxels(self, refine=1): scaler = Scaler(self._voxels) dims = (self._voxels.shape[0]*refine,self._voxels.shape[1]*refine,self._voxels.shape[2]*refine) return scaler.scale(*dims).value def get_pointlayers(self): return self._points_inner.value, self._points_outer.value