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
17 h,w,c = cvmat.shape
18
19
20 nx = w/S
21 ny = h/S
22
23
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
28 label_map = nx*ygrid + xgrid
29
30
31 tmp = np.arange(nx)
32 tmp = np.resize(tmp,(w,))
33 xgroups = tmp[tmp.argsort()]
34
35
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
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
57 centroids[i,:] = mat[:,mask.flatten()].mean(axis=1)
58
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
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
105 label_map,xgroups,ygroups,labels = _assignInitialPoints(cvmat,S)
106 print label_map
107
108
109 mat = cv2.cvtColor(cvmat,cv2.cv.CV_BGR2Lab)
110 h,w,c = cvmat.shape
111
112
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
117 mat = mat
118
119
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
136 features = np.array([x,y, mat[:,:,0],mat[:,:,1],mat[:,:,2],])
137
138
139 for i in range(10):
140
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
153
154
155
156
157
158
159 for im in images:
160
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