def disp_orig_grid_lines(self,level,color=None,lw=1): # return try: self.hlines self.vlines except AttributeError: raise Exception("You need to call create_grid_lines first") if self.hlines is None: raise ValueError if self.vlines is None: self.vlines = self.hlines hlines,vlines=self.hlines,self.vlines s = hlines.shape if s[2]<=1: raise ValueError p = 0 L = 50000 if color is None: colors=['r','b'] else: colors=[color,color] if L >=s[2]: while p < np.ceil(s[2]): hlines=self.hlines[:,:,p:p+L] vlines=self.vlines[:,:,p:p+L] p+=L-1 for lines,c in zip([hlines,vlines],colors): pts_at_0=np.asarray([lines[:,0,:].flatten(), lines[:,1,:].flatten()]).T if pts_at_0.size==0: break # print _pts_at_0.shape pts_at_0 = CpuGpuArray(pts_at_0.copy()) if self.nCols != self.nCols: raise NotImplementedError pts_at_0.gpu2cpu() lines_new_x=pts_at_0.cpu[:,0].reshape(lines[:,0,:].shape).copy() lines_new_y=pts_at_0.cpu[:,1].reshape(lines[:,0,:].shape).copy() for line_new_x,line_new_y in zip(lines_new_x,lines_new_y): plt.plot(line_new_x,line_new_y,c,lw=lw) else: hlines=self.hlines vlines=self.vlines for lines,c in zip([hlines,vlines],colors): pts_at_0=np.asarray([lines[:,0,:].flatten(), lines[:,1,:].flatten()]).T if pts_at_0.size==0: break # print _pts_at_0.shape pts_at_0 = CpuGpuArray(pts_at_0.copy()) if self.nCols != self.nCols: raise NotImplementedError pts_at_0.gpu2cpu() lines_new_x=pts_at_0.cpu[:,0].reshape(lines[:,0,:].shape).copy() lines_new_y=pts_at_0.cpu[:,1].reshape(lines[:,0,:].shape).copy() for line_new_x,line_new_y in zip(lines_new_x,lines_new_y): plt.plot(line_new_x,line_new_y,c,lw=lw)
def disp_orig_grid_lines(self, level, color=None, lw=1): # return try: self.hlines self.vlines except AttributeError: raise Exception("You need to call create_grid_lines first") if self.hlines is None: raise ValueError if self.vlines is None: self.vlines = self.hlines hlines, vlines = self.hlines, self.vlines s = hlines.shape if s[2] <= 1: raise ValueError p = 0 L = 50000 if color is None: colors = ['r', 'b'] else: colors = [color, color] if L >= s[2]: while p < np.ceil(s[2]): hlines = self.hlines[:, :, p:p + L] vlines = self.vlines[:, :, p:p + L] p += L - 1 for lines, c in zip([hlines, vlines], colors): pts_at_0 = np.asarray( [lines[:, 0, :].flatten(), lines[:, 1, :].flatten()]).T if pts_at_0.size == 0: break # print _pts_at_0.shape pts_at_0 = CpuGpuArray(pts_at_0.copy()) if self.nCols != self.nCols: raise NotImplementedError pts_at_0.gpu2cpu() lines_new_x = pts_at_0.cpu[:, 0].reshape( lines[:, 0, :].shape).copy() lines_new_y = pts_at_0.cpu[:, 1].reshape( lines[:, 0, :].shape).copy() for line_new_x, line_new_y in zip(lines_new_x, lines_new_y): plt.plot(line_new_x, line_new_y, c, lw=lw) else: hlines = self.hlines vlines = self.vlines for lines, c in zip([hlines, vlines], colors): pts_at_0 = np.asarray( [lines[:, 0, :].flatten(), lines[:, 1, :].flatten()]).T if pts_at_0.size == 0: break # print _pts_at_0.shape pts_at_0 = CpuGpuArray(pts_at_0.copy()) if self.nCols != self.nCols: raise NotImplementedError pts_at_0.gpu2cpu() lines_new_x = pts_at_0.cpu[:, 0].reshape( lines[:, 0, :].shape).copy() lines_new_y = pts_at_0.cpu[:, 1].reshape( lines[:, 0, :].shape).copy() for line_new_x, line_new_y in zip(lines_new_x, lines_new_y): plt.plot(line_new_x, line_new_y, c, lw=lw)
class SuperpixelsWrapper(object): _calc_seg = _update_seg_iter _calc_param = _update_param_iter def __init__(self, dimy, dimx, nPixels_in_square_side=None, permute_seg=False, s_std=20, i_std=20, prior_count=1, calc_s_cov=True, use_hex=False): """ arguments: nPixels_in_square_side: number of the pixels on the side of a superpixels permute_seg: only for display purpose, whether to permute the superpixels labling, s_std: fixed as nPixels_on_side i_std: control the relative importance between RGB and location. The smaller it is, bigger the RGB effect is / more irregular the superpixels are. prior_count: determines the weight of Inverse-Wishart prior of space covariance(ex:1,5,10) calc_s_cov: whether or not to update the covariance of color component of Gaussians use_hex: initialize the superpixels as hexagons or squares """ # init the field "nPixels_in_square_side" if nPixels_in_square_side is None: raise NotImplementedError self.nPixels_in_square_side = nPixels_in_square_side if not (3 < nPixels_in_square_side < min(dimx, dimy)): msg = """ Expected 3<nPixels_in_square_side<min(dimx,dimy)={1} but nPixels_in_square_side={0} """.format(nPixels_in_square_side, min(dimx, dimy)) raise ValueError(msg) self.dimx = dimx self.dimy = dimy self.nChannels = 3 # RGB/LAB #init the field "seg" self.use_hex = use_hex self.permute_seg = permute_seg seg = get_init_seg(dimy=dimy, dimx=dimx, nPixels_in_square_side=nPixels_in_square_side, use_hex=use_hex) if permute_seg: seg = random_permute_seg(seg) self.seg = CpuGpuArray(arr=seg) # keep the initial segmentation for use in images of the same size # so that we won't re-calculate the initial segmenation self.seg_ini = self.seg.cpu.copy() #init the field nSuperpixels self.nSuperpixels = self.seg.cpu.max() + 1 if self.nSuperpixels <= 1: raise ValueError(self.nSuperpixels) #init the field "superpixels" self.superpixels = Superpixels(self.nSuperpixels, s_std=s_std, i_std=i_std, prior_count=prior_count, nChannels=self.nChannels) #init the field "border"(bool array, true for pixels on the superpixel boundary) border = gpuarray.zeros((dimy, dimx), dtype=np.bool) self.border = CpuGpuArray(arr=border) find_border_pixels(seg_gpu=self.seg.gpu, border_gpu=self.border.gpu) self.border.gpu2cpu() self.border_ini = self.border.cpu.copy() print('dimy,dimx=', dimy, dimx) print('nSuperpixels =', self.nSuperpixels) def set_img(self, img): """ read an rgb image, set the gpu copy to be the lab image """ if img.shape[0] != self.dimy or img.shape[1] != self.dimx: raise ValueError(img.shape, self.dimy, self.dimx) if img.ndim == 2: nChannels = 1 elif img.ndim == 3: nChannels = 3 else: raise NotImplementedError(nChannels) self.img = CpuGpuArray(arr=img.astype(np.float)) if nChannels == 3: rgb_to_lab(img_gpu=self.img.gpu) def initialize_seg(self): """ set the self.seg/border to the initial segmentation/border """ np.copyto(dst=self.seg.cpu, src=self.seg_ini) np.copyto(dst=self.border.cpu, src=self.border_ini) self.seg.cpu2gpu() self.border.cpu2gpu() def set_superpixels(self, s_std, i_std, prior_count): """ set the self.superpixels """ self.superpixels = Superpixels(self.nSuperpixels, s_std=s_std, i_std=i_std, prior_count=prior_count, nChannels=self.nChannels) def calc_seg(self, nEMIters, nItersInner=10, calc_s_cov=True, prior_weight=0.5, verbose=False): """ Inference: hard-EM (Expectation & Maximization) Alternate between the E step (update superpixel assignments) and the M step (update parameters) Arguments: calc_s_cov: whether or not to update the covariance of color component of Gaussians prior_weight: the weight placed on the prior probability of a superpixel """ if verbose: print('start') for i in range(nEMIters): if verbose: print('iteration', i) "M step" self._calc_param(img_gpu=self.img.gpu, seg_gpu=self.seg.gpu, sp=self.superpixels, calculate_s_cov=calc_s_cov) "(Hard) E step" self._calc_seg( img_gpu=self.img.gpu, seg_gpu=self.seg.gpu, border_gpu=self.border.gpu, counts_gpu=self.superpixels.params.counts.gpu, log_count_gpu=self.superpixels.gpu_helper.log_count_helper, superpixels=self.superpixels, nIters=nItersInner, calculate_cov=calc_s_cov, prior_prob_weight=prior_weight) # update the border for display the single border image find_border_pixels(seg_gpu=self.seg.gpu, border_gpu=self.border.gpu, single_border=1) def gpu2cpu(self): """ Transfer the needed parameters from gpu to cpu. Note this is usually slow (when the image and/or nSuperpixels is large) """ if self.img.ndim == 3: lab_to_rgb(self.superpixels.params.mu_i.gpu ) #convert mu_i.gpu from lab to rgb lab_to_rgb(self.img.gpu) # convert img.gpu from lab to rgb params = self.superpixels.params for arg in [ self.seg, self.border, self.img, params.counts, params.mu_s, params.mu_i, params.Sigma_s ]: arg.gpu2cpu() def get_img_overlaid(self): """ Set the pixels on the superpixel boundary to red """ img = self.img.cpu border = self.border.cpu nChannels = self.nChannels if nChannels == 1: img_disp = np.zeros((img.shape[0], img.shape[1], 3), np.uint8) img_disp[:, :, 0] = img_disp[:, :, 1] = img_disp[:, :, 2] = img elif nChannels == 3: img_disp = img.copy().astype(np.uint8) img_disp[:, :, 0][border] = 255 img_disp[:, :, 1][border] = 0 img_disp[:, :, 2][border] = 0 return img_disp def get_cartoon(self): """ Replace pixels with superpixels means. """ img = self.img.cpu nChannels = self.nChannels img_disp = CpuGpuArray.zeros((img.shape[0], img.shape[1], 3), dtype=np.int32) get_cartoon(seg_gpu=self.seg.gpu, mu_i_gpu=self.superpixels.params.mu_i.gpu, img_gpu=img_disp.gpu, nChannels=nChannels) img_disp.gpu2cpu() return img_disp.cpu
class SuperpixelsWrapper(object): _calc_seg = _update_seg_iter _calc_param = _update_param_iter def __init__(self, dimy, dimx, nPixels_in_square_side=None, permute_seg=False, s_std = 20, i_std=20, prior_count = 1, calc_s_cov=True, use_hex=False): """ arguments: nPixels_in_square_side: number of the pixels on the side of a superpixels permute_seg: only for display purpose, whether to permute the superpixels labling, s_std: fixed as nPixels_on_side i_std: control the relative importance between RGB and location. The smaller it is, bigger the RGB effect is / more irregular the superpixels are. prior_count: determines the weight of Inverse-Wishart prior of space covariance(ex:1,5,10) calc_s_cov: whether or not to update the covariance of color component of Gaussians use_hex: initialize the superpixels as hexagons or squares """ # init the field "nPixels_in_square_side" if nPixels_in_square_side is None: raise NotImplementedError self.nPixels_in_square_side=nPixels_in_square_side if not (3<nPixels_in_square_side<min(dimx,dimy)): msg = """ Expected 3<nPixels_in_square_side<min(dimx,dimy)={1} but nPixels_in_square_side={0} """.format(nPixels_in_square_side,min(dimx,dimy)) raise ValueError(msg) self.dimx=dimx self.dimy=dimy self.nChannels = 3 # RGB/LAB #init the field "seg" self.use_hex = use_hex self.permute_seg = permute_seg seg = get_init_seg(dimy=dimy,dimx=dimx, nPixels_in_square_side=nPixels_in_square_side, use_hex = use_hex) if permute_seg: seg = random_permute_seg(seg) self.seg = CpuGpuArray(arr=seg) # keep the initial segmentation for use in images of the same size # so that we won't re-calculate the initial segmenation self.seg_ini = self.seg.cpu.copy() #init the field nSuperpixels self.nSuperpixels = self.seg.cpu.max()+1 if self.nSuperpixels <= 1: raise ValueError(self.nSuperpixels) #init the field "superpixels" self.superpixels = Superpixels(self.nSuperpixels, s_std=s_std, i_std=i_std, prior_count = prior_count, nChannels=self.nChannels) #init the field "border"(bool array, true for pixels on the superpixel boundary) border = gpuarray.zeros((dimy,dimx),dtype=np.bool) self.border = CpuGpuArray(arr=border) find_border_pixels(seg_gpu=self.seg.gpu, border_gpu=self.border.gpu) self.border.gpu2cpu() self.border_ini = self.border.cpu.copy() print 'dimy,dimx=',dimy,dimx print 'nSuperpixels =',self.nSuperpixels def set_img(self,img): """ read an rgb image, set the gpu copy to be the lab image """ if img.shape[0] != self.dimy or img.shape[1] != self.dimx: raise ValueError(img.shape,self.dimy,self.dimx) if img.ndim == 1: nChannels = 1 isNaN = np.isnan( img) elif img.ndim == 3: nChannels = 3 img_isNaN_r = np.isnan( img[:,:,0] ) img_isNaN_g = np.isnan( img[:,:,1] ) img_isNaN_b = np.isnan( img[:,:,2] ) isNaN = np.logical_or(img_isNaN_r, np.logical_or(img_isNaN_g,img_isNaN_b)) else: raise NotImplementedError(nChannels) self.img = CpuGpuArray(arr=img) self.img_isNaN = CpuGpuArray(arr=isNaN) print 'self.img',self.img print 'self.img_isNaN',self.img_isNaN if nChannels==3: rgb_to_lab(img_gpu=self.img.gpu) def initialize_seg(self): """ set the self.seg/border to the initial segmentation/border """ np.copyto(dst=self.seg.cpu,src=self.seg_ini) np.copyto(dst=self.border.cpu,src=self.border_ini) self.seg.cpu2gpu() self.border.cpu2gpu() def set_superpixels(self, s_std, i_std, prior_count): """ set the self.superpixels """ self.superpixels = Superpixels(self.nSuperpixels, s_std=s_std, i_std=i_std, prior_count = prior_count, nChannels=self.nChannels) def calc_seg(self, nEMIters, nItersInner=10, calc_s_cov=True, prior_weight=0.5, verbose=False): """ Inference: hard-EM (Expectation & Maximization) Alternate between the E step (update superpixel assignments) and the M step (update parameters) Arguments: calc_s_cov: whether or not to update the covariance of color component of Gaussians prior_weight: the weight placed on the prior probability of a superpixel """ if verbose: print 'start' for i in range(nEMIters): if verbose: print 'iteration',i "M step" self._calc_param(img_gpu=self.img.gpu, img_isNaN_gpu =self.img_isNaN.gpu, seg_gpu=self.seg.gpu, sp=self.superpixels, calculate_s_cov=calc_s_cov) "(Hard) E step" self._calc_seg(img_gpu=self.img.gpu, img_isNaN_gpu =self.img_isNaN.gpu, seg_gpu=self.seg.gpu, border_gpu=self.border.gpu, counts_gpu=self.superpixels.params.counts.gpu, log_count_gpu = self.superpixels.gpu_helper.log_count_helper, superpixels=self.superpixels, nIters=nItersInner, calculate_cov=calc_s_cov, prior_prob_weight = prior_weight) # update the border for display the single border image find_border_pixels(seg_gpu=self.seg.gpu, border_gpu=self.border.gpu, single_border=1) def gpu2cpu(self): """ Transfer the needed parameters from gpu to cpu. Note this is usually slow (when the image and/or nSuperpixels is large) """ if self.img.ndim == 3: lab_to_rgb(self.superpixels.params.mu_i.gpu) #convert mu_i.gpu from lab to rgb lab_to_rgb(self.img.gpu) # convert img.gpu from lab to rgb params = self.superpixels.params for arg in [self.seg, self.border, self.img, params.counts, params.mu_s, params.mu_i, params.Sigma_s]: arg.gpu2cpu() def get_img_overlaid(self): """ Set the pixels on the superpixel boundary to red """ img = self.img.cpu border = self.border.cpu nChannels = self.nChannels if nChannels==1: img_disp = np.zeros((img.shape[0],img.shape[1],3),np.uint8) img_disp[:,:,0]=img_disp[:,:,1]=img_disp[:,:,2]=img elif nChannels==3: img_disp = img.copy().astype(np.uint8) img_disp[:,:,0][border] = 255 img_disp[:,:,1][border] = 0 img_disp[:,:,2][border] = 0 return img_disp def get_cartoon(self): """ Replace pixels with superpixels means. """ img = self.img.cpu nChannels = self.nChannels img_disp = CpuGpuArray.zeros((img.shape[0],img.shape[1],3),dtype=np.int32) get_cartoon(seg_gpu = self.seg.gpu, mu_i_gpu = self.superpixels.params.mu_i.gpu, img_gpu= img_disp.gpu, nChannels=nChannels) img_disp.gpu2cpu() return img_disp.cpu