Package pyvision :: Package segment :: Module superpixel
[hide private]
[frames] | no frames]

Source Code for Module pyvision.segment.superpixel

  1  ''' 
  2  Created on May 24, 2013 
  3   
  4  @author: bolme 
  5  ''' 
  6  import cv2 
  7  import scipy.cluster.vq as vq 
  8  import scipy as sp 
  9  import scipy.ndimage as ndi 
 10  import pyvision as pv 
 11  import numpy as np 
 12  from skimage.segmentation import felzenszwalb, slic, quickshift 
 13  from skimage.data import lena 
 14   
 15   
16 -def _assignInitialPoints(cvmat,S):
17 h,w,c = cvmat.shape 18 19 # Compute the max grid assignment 20 nx = w/S 21 ny = h/S 22 23 # Compute the super pixel x,y grid 24 xgrid = np.arange(nx).reshape(1,nx)*np.ones(ny,dtype=np.int).reshape(ny,1) 25 ygrid = np.arange(ny).reshape(ny,1)*np.ones(nx,dtype=np.int).reshape(1,nx) 26 27 # compute an x,y lookup to a label look up 28 label_map = nx*ygrid + xgrid 29 30 # Compute the x groups in pixel space 31 tmp = np.arange(nx) 32 tmp = np.resize(tmp,(w,)) 33 xgroups = tmp[tmp.argsort()] 34 35 # Compute the y groups in pixel space 36 tmp = np.arange(ny) 37 tmp = np.resize(tmp,(h,)) 38 ygroups = tmp[tmp.argsort()] 39 40 labels = np.zeros((h,w),dtype=np.int) 41 42 for x in xrange(w): 43 for y in xrange(h): 44 labels[y,x] = label_map[ygroups[y],xgroups[x]] 45 46 return label_map,xgroups,ygroups,labels
47
48 -def _computeCentriods(mat,labels,label_map):
49 c,h,w = mat.shape 50 mat = mat.reshape(c,h*w) 51 centroids = np.zeros((label_map.max()+1,c)) 52 counts = np.zeros((label_map.max()+1,1)) 53 for i in xrange(label_map.max()+1): 54 pass 55 mask = (labels == i) 56 #print mask.flatten() 57 centroids[i,:] = mat[:,mask.flatten()].mean(axis=1) 58 #pv.Image(1.0*mask).show() 59 return centroids 60 for x in xrange(w): 61 for y in xrange(h): 62 lab = labels[y,x] 63 centroids[lab] += mat[:,y,x] 64 counts[lab] += 1.0 65 centroids = centroids / counts 66 return centroids
67 68
69 -def _computeLabels(mat,label_map,centroids,xgroups,ygroups,S,m):
70 c,h,w = mat.shape 71 labels = np.zeros((h,w),dtype=np.int) 72 dists = np.zeros((h,w),dtype=np.float32) 73 dists[:,:] = np.inf 74 for lab in xrange(len(centroids)): 75 centroid = centroids[lab] 76 x,y = centroid[:2] 77 centroid = centroid.reshape(c,1,1) 78 minx = max(0,int(x-S)) 79 maxx = min(w,int(x+S)) 80 miny = max(0,int(y-S)) 81 maxy = min(h,int(y+S)) 82 tile = mat[:,miny:maxy,minx:maxx] 83 ds2 = ((tile[:2,:,:] - centroid[:2,:,:])**2).sum(axis=0) 84 dc2 = ((tile[2:,:,:] - centroid[2:,:,:])**2).sum(axis=0) 85 86 D = np.sqrt(dc2 + (m*m)*(ds2/(S*S))) 87 dist_tile = dists[miny:maxy,minx:maxx] 88 labels_tile = labels[miny:maxy,minx:maxx] 89 90 mask = (dist_tile > D) 91 dist_tile[mask] = D[mask] 92 labels_tile[mask] = lab 93 return labels
94 95
96 -def slic2(im,S,m=20,L_scale=0.5,mean_scale=1.0,std_scale=3.0):
97 ''' 98 This is a k-means based super pixel algorithm inspired by slic. 99 100 http://ivrg.epfl.ch/supplementary_material/RK_SLICSuperpixels/index.html 101 ''' 102 cvmat = im.asOpenCV2() 103 104 # Compute a label map and assign initial labels 105 label_map,xgroups,ygroups,labels = _assignInitialPoints(cvmat,S) 106 print label_map 107 108 # Compute color features 109 mat = cv2.cvtColor(cvmat,cv2.cv.CV_BGR2Lab) 110 h,w,c = cvmat.shape 111 112 # Compute location features 113 x = np.arange(w).reshape(1,w)*np.ones(h,dtype=np.int).reshape(h,1) 114 y = np.arange(h).reshape(h,1)*np.ones(w,dtype=np.int).reshape(1,w) 115 116 # Scale the features 117 mat = mat 118 119 # Compute local statistics 120 mean_L = mat[:,:,0].copy() 121 mean_L = ndi.gaussian_filter(mean_L,0.5*S) 122 std_L = (mat[:,:,0].copy() - mean_L)**2 123 std_L = np.sqrt(ndi.gaussian_filter(std_L,0.5*S)) 124 125 mean_a = mat[:,:,1].copy() 126 mean_a = ndi.gaussian_filter(mean_a,0.5*S) 127 std_a = (mat[:,:,1].copy() - mean_a)**2 128 std_a = np.sqrt(ndi.gaussian_filter(std_a,0.5*S)) 129 130 mean_b = mat[:,:,2].copy() 131 mean_b = ndi.gaussian_filter(mean_b,0.5*S) 132 std_b = (mat[:,:,2].copy() - mean_b)**2 133 std_b = np.sqrt(ndi.gaussian_filter(std_b,0.5*S)) 134 135 # Create a feature vector matrix 136 features = np.array([x,y, mat[:,:,0],mat[:,:,1],mat[:,:,2],]) 137 #features = np.array([x,y, L_scale*mat[:,:,0],mat[:,:,1],mat[:,:,2],mean_scale*mean_L,std_scale*std_L,mean_scale*mean_a,std_scale*std_a,mean_scale*mean_b,std_scale*std_b]) 138 139 for i in range(10): 140 # Compute centriods 141 timer = pv.Timer() 142 centroids = _computeCentriods(features,labels,label_map) 143 timer.mark('centroids') 144 labels = _computeLabels(features,label_map,centroids,xgroups,ygroups,S,m) 145 timer.mark('labels') 146 mask = 9*labels != ndi.correlate(labels, [[1,1,1],[1,1,1],[1,1,1]]) 147 return labels.T,centroids,mask.T
148 149 if __name__ == '__main__': 150 ilog = pv.ImageLog() 151 152 #im = pv.Image(np.array(lena(),dtype=np.float32)) 153 #print lena() 154 #im.show() 155 #assert 0 156 #im = im.resize((256,256)) 157 #labels,centroids,mask = slic(im,10,50.0) 158 #segments = felzenszwalb(im.asOpenCV2(),scale=100, sigma=0.5, min_size=50) 159 for im in images: 160 #im = im.resize((256,256)) 161 segments = slic(im.asOpenCV2(),ratio=80, n_segments=16, sigma=2) 162 mask = 9*segments != ndi.correlate(segments, [[1,1,1],[1,1,1],[1,1,1]]) 163 im.annotateMask(mask.T) 164 im.show() 165