00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 from features import features
00031
00032 import laser_camera_segmentation.gaussian_curvature as gaussian_curvature
00033 import scipy.stats as stats
00034 import numpy as np
00035 import opencv as cv
00036 import scipy.spatial.kdtree as kdtree
00037 import hrl_lib.util as ut
00038 from hrl_lib.util import getTime
00039 import os
00040
00041 import laser_camera_segmentation.texture_features as texture_features
00042
00043 import processor
00044 import copy
00045
00046 class gaussian_histogram_features(features):
00047 '''
00048 classdocs
00049 '''
00050
00051
00052 def prepare(self, features_k_nearest_neighbors, nonzero_indices = None, all_save_load = False, regenerate_neightborhood_indices = False):
00053
00054
00055 imgTmp = cv.cvCloneImage(self.processor.img)
00056 self.imNP = ut.cv2np(imgTmp,format='BGR')
00057 self.processor.map2d = np.asarray(self.processor.map[0][0:2])
00058
00059 if features_k_nearest_neighbors == None or features_k_nearest_neighbors == False:
00060 self.kdtree2d = kdtree.KDTree(self.processor.pts3d_bound.T)
00061
00062
00063
00064
00065 if nonzero_indices != None:
00066 print getTime(), 'query ball tree for ', len(nonzero_indices), 'points'
00067 kdtree_query = kdtree.KDTree((self.processor.pts3d_bound.T)[nonzero_indices])
00068 else:
00069 print getTime(), 'query ball tree'
00070 kdtree_query = kdtree.KDTree(self.processor.pts3d_bound.T)
00071
00072 filename = self.processor.config.path+'/data/'+self.processor.scan_dataset.id+'_sphere_neighborhood_indices_'+str(self.processor.feature_radius)+'.pkl'
00073 if all_save_load == True and os.path.exists(filename) and regenerate_neightborhood_indices == False:
00074
00075 print getTime(), 'loading',filename
00076 self.kdtree_queried_indices = ut.load_pickle(filename)
00077 else:
00078 self.kdtree_queried_indices = kdtree_query.query_ball_tree(self.kdtree2d, self.processor.feature_radius, 2.0, 0.2)
00079 print getTime(), 'queried kdtree: ',len(self.kdtree_queried_indices),'points, radius:',self.processor.feature_radius
00080 if all_save_load == True:
00081 ut.save_pickle(self.kdtree_queried_indices, filename)
00082
00083
00084
00085
00086 else:
00087
00088
00089 self.kdtree2d = kdtree.KDTree(self.processor.pts3d_bound.T)
00090 self.kdtree_queried_indices = []
00091 print getTime(), 'kdtree single queries for kNN start, k=', features_k_nearest_neighbors
00092 count = 0
00093 for point in ((self.processor.pts3d_bound.T)[nonzero_indices]):
00094 count = count + 1
00095 result = self.kdtree2d.query(point, features_k_nearest_neighbors,0.2,2,self.processor.feature_radius)
00096
00097
00098
00099 self.kdtree_queried_indices += [result[1]]
00100 if count % 4096 == 0:
00101 print getTime(),count
00102 print getTime(), 'kdtree singe queries end'
00103
00104
00105 self.kdtree_queried_indices = np.asarray(self.kdtree_queried_indices)
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 image_size = cv.cvGetSize(self.processor.img)
00123 img_h = cv.cvCreateImage (image_size, 8, 1)
00124 img_s = cv.cvCreateImage (image_size, 8, 1)
00125 img_v = cv.cvCreateImage (image_size, 8, 1)
00126 img_hsv = cv.cvCreateImage (image_size, 8, 3)
00127
00128 cv.cvCvtColor (self.processor.img, img_hsv, cv.CV_BGR2HSV)
00129
00130 cv.cvSplit (img_hsv, img_h, img_s, img_v, None)
00131 self.imNP_h = ut.cv2np(img_h)
00132 self.imNP_s = ut.cv2np(img_s)
00133 self.imNP_v = ut.cv2np(img_v)
00134
00135 textures = texture_features.eigen_texture(self.processor.img)
00136 self.imNP_tex1 = textures[:,:,0]
00137 self.imNP_tex2 = textures[:,:,1]
00138
00139 self.debug_before_first_featurevector = True
00140
00141 self.generate_voi_histogram(self.processor.point_of_interest,self.processor.voi_width)
00142
00143
00144
00145
00146 def get_indexvector(self, type):
00147
00148 var_idx = []
00149
00150 rh1 = 0
00151 ch1 = rh1 + 6
00152 ci = ch1 + 25
00153 end = ci + 4
00154 if type=='range':
00155 for i in range(rh1, ch1):
00156 var_idx.append(i)
00157 elif type=='color':
00158 for i in range(ch1, end):
00159 var_idx.append(i)
00160
00161 elif type=='hsvi':
00162 for i in range(ci,end):
00163 var_idx.append(i)
00164 else:
00165 for i in range(rh1, end):
00166 var_idx.append(i)
00167
00168 return np.array(var_idx)
00169
00170
00171
00172
00173 def get_featurevector(self, index, count, pts = None):
00174 if pts == None:
00175 pts = self.processor.pts3d_bound
00176
00177
00178 fv = []
00179
00180 indices = np.asarray(self.kdtree_queried_indices[count])
00181 invalid_value = np.shape(pts)[1]
00182
00183
00184 indices = indices[indices != invalid_value]
00185
00186
00187
00188 a = pts[:,indices]
00189 view = processor.rotate_to_plane(self.processor.scan_dataset.ground_plane_normal, np.matrix([-1,0,0.]).T)
00190 normal, eigenvalues = gaussian_curvature.gaussian_curvature(a,view)
00191
00192
00193
00194
00195
00196
00197 point = pts[:,index]
00198
00199 ev1, ev2 = self.get_voi_histogram_spread(point)
00200
00201
00202 fv += [self.get_voi_histogram_value(point),normal[0,0],normal[1,0],normal[2,0], ev1, ev2]
00203
00204 h = self.imNP_h[self.processor.map2d[1,index],self.processor.map2d[0,index]]
00205 s = self.imNP_s[self.processor.map2d[1,index],self.processor.map2d[0,index]]
00206 i = self.processor.intensities_bound[index]
00207 hsi = self.get_voi_hsi_histogram_values(point,h,s,i)
00208 fv += [hsi[0],hsi[1],hsi[2]]
00209
00210
00211 tex1 = self.imNP_tex1[self.processor.map2d[1,index],self.processor.map2d[0,index]]
00212 tex2 = self.imNP_tex2[self.processor.map2d[1,index],self.processor.map2d[0,index]]
00213 fv += [tex1, tex2]
00214
00215
00216
00217
00218 colors_h = []
00219 colors_s = []
00220 colors_v = []
00221 for idx in indices:
00222 colors_h.append(float(self.imNP_h[self.processor.map2d[1,idx],self.processor.map2d[0,idx]]))
00223 colors_s.append(float(self.imNP_s[self.processor.map2d[1,idx],self.processor.map2d[0,idx]]))
00224 colors_v.append(float(self.imNP_v[self.processor.map2d[1,idx],self.processor.map2d[0,idx]]))
00225
00226 color_hist = stats.histogram2(np.array(colors_h), [0,51,102,153,204])
00227 color_hist = color_hist / float(np.sum(color_hist))
00228 color_hist = list(color_hist)
00229 fv += color_hist
00230 color_hist = stats.histogram2(np.array(colors_s), [0,51,102,153,204])
00231 color_hist = color_hist / float(np.sum(color_hist))
00232 color_hist = list(color_hist)
00233 fv += color_hist
00234 color_hist = stats.histogram2(np.array(colors_v), [0,51,102,153,204])
00235 color_hist = color_hist / float(np.sum(color_hist))
00236 color_hist = list(color_hist)
00237 fv += color_hist
00238
00239
00240 intensities = self.processor.intensities_bound[indices]
00241 intensities = np.asarray(intensities)
00242
00243 intensities = intensities / 10000 * 255
00244 intensity_hist = stats.histogram2(intensities, [0,51,102,153,204])
00245 intensity_hist = intensity_hist / float(np.sum(intensity_hist))
00246 intensity_hist = list(intensity_hist)
00247 fv += intensity_hist
00248
00249
00250 fv += [float(self.imNP_h[self.processor.map2d[1,index],self.processor.map2d[0,index]]) / 255.0]
00251 fv += [float(self.imNP_s[self.processor.map2d[1,index],self.processor.map2d[0,index]]) / 255.0]
00252 fv += [float(self.imNP_v[self.processor.map2d[1,index],self.processor.map2d[0,index]]) / 255.0]
00253
00254
00255 intensity = self.processor.intensities_bound[index]
00256
00257 intensity = intensity / 15000.0
00258 intensity = [intensity]
00259 fv += intensity
00260
00261
00262 if self.debug_before_first_featurevector == True:
00263 self.debug_before_first_featurevector = False
00264 print getTime(), 'feature vector sample(gaussian histograms):', fv
00265 return fv
00266
00267
00268
00269
00270 def generate_voi_histogram(self, poi, width):
00271 print 'poi',poi,'width',width
00272 pts_indices = self.get_voi_pts_indices(poi, width)
00273 self.voi_pts_indices = pts_indices
00274 pts = np.asarray(self.processor.pts3d_bound)
00275 pts = pts[:,pts_indices]
00276 self.voi_pts = pts
00277
00278
00279 min = 0.
00280 max = 2.
00281 self.voi_bincount = 80
00282 self.voi_interval_size = max - min
00283 bins = np.asarray(range(self.voi_bincount)) * self.voi_interval_size/float(self.voi_bincount)
00284
00285 hist = stats.histogram2(pts[2],bins) / float(len(pts[2]))
00286
00287
00288 self.z_hist = hist
00289 self.z_hist_bins = bins
00290
00291 slices = self.get_voi_slice_indices()
00292 self.z_hist_slices_indices = slices
00293
00294
00295 self.z_hist_spread = []
00296 for indices in self.z_hist_slices_indices:
00297 a = self.processor.pts3d_bound[:,indices]
00298 u, ev12 = gaussian_curvature.spread(a)
00299 self.z_hist_spread += [(ev12[0], ev12[1])]
00300
00301
00302 pts_h = []
00303 pts_s = []
00304
00305 n,m = np.shape(np.asarray(self.processor.pts3d_bound))
00306
00307 for index in range(m):
00308 pts_h.append(float(self.imNP_h[self.processor.map2d[1,index],self.processor.map2d[0,index]]))
00309 for index in range(m):
00310 pts_s.append(float(self.imNP_s[self.processor.map2d[1,index],self.processor.map2d[0,index]]))
00311 pts_i = np.asarray(self.processor.intensities_bound)
00312
00313 if np.max(pts_i) > 0:
00314 self.intensity_normalization_factor = 1.0 / float(np.max(pts_i)) * 255
00315 else:
00316 self.intensity_normalization_factor = 1.
00317
00318
00319 pts_i *= self.intensity_normalization_factor
00320 pts_h = np.asarray(pts_h)
00321 pts_s = np.asarray(pts_s)
00322 self.z_hist_h_hists = []
00323 self.z_hist_s_hists = []
00324 self.z_hist_i_hists = []
00325
00326
00327 max_count = 0
00328 max_count_index = 0
00329 for count_idx, indices in enumerate(slices):
00330 n = np.shape(indices)
00331 if n[0] > max_count:
00332 max_count = n[0]
00333 max_count_index = count_idx
00334 slize_height = (self.voi_interval_size / float(self.voi_bincount))
00335 self.z_hist_height_max = slize_height * (max_count_index + 0.5)
00336
00337
00338
00339 for indices in slices:
00340 pts_h_slice = pts_h[indices]
00341 pts_s_slice = pts_s[indices]
00342 pts_i_slice = pts_i[indices]
00343 self.hsi_hist_bincount = 5
00344 bins = np.asarray(range(0,self.hsi_hist_bincount))*float(255.0/float(self.hsi_hist_bincount))
00345
00346
00347 count = float(len(pts_h_slice))
00348 if count == 0:
00349 count = 1
00350 hist_h = stats.histogram2(pts_h_slice,bins) / count
00351 self.z_hist_h_hists.append(hist_h)
00352 hist_s = stats.histogram2(pts_s_slice,bins) / count
00353 self.z_hist_s_hists.append(hist_s)
00354 hist_i = stats.histogram2(pts_i_slice,bins) / count
00355
00356 self.z_hist_i_hists.append(hist_i)
00357
00358
00359
00360
00361
00362 def get_voi_pts_indices(self, poi, width):
00363 pts = np.asarray(self.processor.pts3d_bound)
00364
00365 conditions = np.multiply(np.multiply(np.multiply(np.multiply(np.multiply(pts[0] < poi[0]+width/2.0, pts[0] > poi[0]-width/2.0),
00366 pts[1] < poi[1]+width/2.0), pts[1] > poi[1]-width/2.0),
00367 pts[2] < poi[2]+width/2.0), pts[2] > poi[2]-width/2.0)
00368
00369 indices = np.where(conditions)[0]
00370 return indices
00371
00372 def get_voi_slice_indices(self):
00373
00374 slices = []
00375 last_z = -999999
00376
00377 for z in self.z_hist_bins:
00378 indices = copy.copy(self.voi_pts_indices)
00379 pts = self.voi_pts
00380 conditions = np.multiply(pts[2] < z, pts[2] > last_z)
00381 indices = indices[np.where(conditions)[0]]
00382 slices += [indices]
00383 last_z = z
00384 return slices
00385
00386 def get_voi_histogram_value(self, point):
00387 z = point[2]
00388 z = int(z*self.voi_bincount / float(self.voi_interval_size))
00389 if z >= 0 and z < self.voi_bincount:
00390
00391 return self.z_hist[z]
00392 else:
00393
00394 return 0
00395
00396 def get_voi_histogram_spread(self, point):
00397 z = point[2]
00398 z = int(z*self.voi_bincount / float(self.voi_interval_size))
00399 if z >= 0 and z < self.voi_bincount:
00400
00401
00402
00403
00404
00405
00406 return self.z_hist_spread[z]
00407 else:
00408
00409 return 0, 0
00410
00411
00412 def get_voi_hsi_histogram_values(self, point,h ,s, i):
00413 z = point[2]
00414 z = int(z*self.voi_bincount / float(self.voi_interval_size))
00415 if z >= 0 and z < self.voi_bincount:
00416 h_index = int(h * self.hsi_hist_bincount / 255.0)
00417 s_index = int(s * self.hsi_hist_bincount / 255.0)
00418 i *= self.intensity_normalization_factor
00419 i_index = int(i * self.hsi_hist_bincount / 255.0)
00420
00421 h_hist = self.z_hist_h_hists[z][h_index]
00422 s_hist = self.z_hist_s_hists[z][s_index]
00423
00424
00425 i_hist = self.z_hist_i_hists[z][i_index]
00426 return h_hist, s_hist, i_hist
00427 else:
00428
00429 return 0, 0, 0
00430
00431 def get_voi_maxcount_height(self):
00432 return self.z_hist_height_max
00433
00434