recognize_3d.py
Go to the documentation of this file.
00001 #
00002 # Copyright (c) 2010, Georgia Tech Research Corporation
00003 # All rights reserved.
00004 # 
00005 # Redistribution and use in source and binary forms, with or without
00006 # modification, are permitted provided that the following conditions are met:
00007 #     * Redistributions of source code must retain the above copyright
00008 #       notice, this list of conditions and the following disclaimer.
00009 #     * Redistributions in binary form must reproduce the above copyright
00010 #       notice, this list of conditions and the following disclaimer in the
00011 #       documentation and/or other materials provided with the distribution.
00012 #     * Neither the name of the Georgia Tech Research Corporation nor the
00013 #       names of its contributors may be used to endorse or promote products
00014 #       derived from this software without specific prior written permission.
00015 # 
00016 # THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS'' AND
00017 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 # DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH BE LIABLE FOR ANY DIRECT, INDIRECT,
00020 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00021 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00022 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00023 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00024 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 #
00027 import roslib; roslib.load_manifest('trf_learn')
00028 import cv
00029 import rospy
00030 import sensor_msgs.msg as sm
00031 #import visualization_msgs.msg as vm
00032 
00033 import numpy as np
00034 import scipy.spatial as sp
00035 import threading
00036 import Queue as qu
00037 import os.path as pt
00038 import glob
00039 
00040 import pdb
00041 #pdb.set_trace()
00042 #import libsvm.svm as svm
00043 import libsvm.svmutil as su
00044 
00045 import copy
00046 import os
00047 
00048 import ml_lib.dataset as ds
00049 import ml_lib.dimreduce as dr
00050 
00051 #import hrl_opencv.blob as blob
00052 import hrl_opencv.image3d as i3d
00053 import hrl_lib.util as ut
00054 #import hrl_lib.viz as viz
00055 import hrl_lib.rutils as ru
00056 import hrl_lib.tf_utils as tfu
00057 #import hrl_lib.prob as pr
00058 import trf_learn.intensity_feature as infea
00059 
00060 
00061 #import message_filters
00062 #import feature_extractor_fpfh.msg as fmsg
00063 import time
00064 import pdb
00065 
00066 UNLABELED = 2.0
00067 POSITIVE = 1.0
00068 NEGATIVE = 0.
00069 
00070 def separate_by_labels(points, labels):
00071     pidx = np.where(labels == POSITIVE)[1].A1.tolist()
00072     nidx = np.where(labels == NEGATIVE)[1].A1.tolist()
00073     uidx = np.where(labels == UNLABELED)[1].A1.tolist()
00074     return points[:, uidx], points[:, pidx], points[:, nidx]
00075 
00076 def confusion_matrix(true_labels, predicted):
00077     posidx = np.where(true_labels == POSITIVE)[1].A1
00078     negidx = np.where(true_labels == NEGATIVE)[1].A1
00079     m00 = m01 = m10 = m11 = 0
00080     nm00 = nm01 = nm10 = nm11 = 0
00081 
00082     if len(negidx) > 0:
00083         nm00 = float(np.sum(NEGATIVE == predicted[:, negidx]))
00084         nm01 = float(np.sum(POSITIVE == predicted[:, negidx]))
00085         m00 =  nm00 / len(negidx)
00086         m01 =  nm01 / len(negidx)
00087 
00088     if len(posidx) > 0:
00089         nm10 = float(np.sum(NEGATIVE == predicted[:, posidx]))
00090         nm11 = float(np.sum(POSITIVE == predicted[:, posidx]))
00091         m10 =  nm10 / len(posidx)
00092         m11 =  nm11 / len(posidx)
00093 
00094     return np.matrix([[m00, m01], [m10, m11]], 'float')
00095     #if verbose:
00096     #    print 'Confusion matrix:'
00097     #    print '-   %5.2f, %5.2f' % (100.* m00, 100.* m01)
00098     #    print '+  %5.2f, %5.2f' % (100.* m10, 100.* m11)
00099     #    print '   Total %5.2f' % (100.* (float(np.sum(true_labels == predicted)) / true_labels.shape[1]))
00100     #return {'mat': np.matrix([[nm00, nm01], [nm10, nm11]], 'float'), 
00101     #        'neg': len(negidx), 
00102     #        'pos': len(posidx)}
00103 
00104 
00105 def instances_to_image(win_size, instances, min_val, max_val):
00106     img_arrs = []
00107     for i in range(instances.shape[1]):
00108         img_arrs.append(instance_to_image(win_size, instances[:,i], min_val, max_val).copy())
00109     return cv.fromarray(np.concatenate(img_arrs, 0).copy())
00110 
00111 def instance_to_image(win_size, instance, min_val, max_val):
00112     winside = win_size*2+1
00113     patch_size = winside*winside*3
00114     #multipliers = [1,2,4,8,16,32]
00115     srange = max_val - min_val
00116 
00117     offset = 0
00118     patches = []
00119     num_patches = instance.shape[0] / patch_size
00120     #pdb.set_trace()
00121     #for i in range(len(multipliers)):
00122     for i in range(num_patches):
00123         s = instance[offset:offset+patch_size, 0]
00124         s = np.array(np.abs(np.round(((s-min_val)/srange) * 255.)), 'uint8')
00125         patches.append(np.reshape(s, (winside, winside, 3)))
00126         offset+=patch_size
00127     #pdb.set_trace()
00128     return np.concatenate(patches, 1)
00129 
00130 def insert_folder_name(apath, folder_name):
00131     path, filename = pt.split(apath)
00132     return pt.join(pt.join(path, folder_name), filename)
00133 
00134 def load_data_from_file2(fname, rec_param):
00135     data_pkl = ut.load_pickle(fname)
00136     image_fname = pt.join(pt.split(fname)[0], data_pkl['image'])
00137     intensity_image = cv.LoadImageM(image_fname)
00138     center_point_bl = data_pkl['touch_point']
00139 
00140     print 'Robot touched point cloud at point', center_point_bl.T
00141     distance_feature_points = None
00142     syn_locs_fname = pt.splitext(fname)[0] + '_synthetic_locs3d.pkl'
00143     if pt.isfile(syn_locs_fname):
00144         print 'found synthetic locations file', syn_locs_fname
00145         distance_feature_points = ut.load_pickle(syn_locs_fname)
00146         data_pkl['synthetic_locs3d'] = distance_feature_points
00147     else:
00148         print 'synthetic loc file not found', syn_locs_fname
00149 
00150     #return IntensityCloudData(data_pkl['points3d'], intensity_image,
00151     #        data_pkl['k_T_bl'], data_pkl['cal'], center_point_bl, center_point_bl, 
00152     #        distance_feature_points, rec_param), data_pkl
00153     return infea.IntensityCloudFeatureExtractor(data_pkl['points3d'], intensity_image, center_point_bl,
00154                                             distance_feature_points, data_pkl['k_T_bl'], 
00155                                             data_pkl['cal'], rec_param), data_pkl
00156 
00157 def dataset_to_libsvm(dataset, filename):
00158     f = open(filename, 'w')
00159 
00160     for i in range(dataset.outputs.shape[1]):
00161         if dataset.outputs[0,i] == POSITIVE:
00162             f.write('+1 ')
00163         else:
00164             f.write('-1 ')
00165         #instance
00166         for j in range(dataset.inputs.shape[0]):
00167             f.write('%d:%f ' % (j, dataset.inputs[j, i]))
00168         f.write('\n')
00169 
00170     f.close()
00171 
00172 def draw_labeled_points(image, dataset, pos_color=[255,102,55], neg_color=[0,184,245], scale=1.):
00173     #pt2d = np.column_stack(dataset.pt2d)
00174     pt2d = dataset.pt2d 
00175     for l, color in [(POSITIVE, pos_color), (NEGATIVE, neg_color)]:
00176         cols = np.where(l == dataset.outputs)[1]
00177         locs2d = np.matrix(np.round(pt2d[:, cols.A1]/scale), 'int')
00178         draw_points(image, locs2d, color)
00179 
00180 def draw_points(img, img_pts, color, size=1, thickness=-1):
00181     for i in range(img_pts.shape[1]):
00182         center = tuple(np.matrix(np.round(img_pts[:,i]),'int').T.A1.tolist())
00183         cv.Circle(img, center, size, color, thickness)
00184 
00185 def draw_dataset(dataset, img, scale=1., size=2, scan_id=None):
00186     npt2d = []
00187     ppt2d = []
00188     for i in range(dataset.inputs.shape[1]):
00189         if dataset.pt2d != None and dataset.pt2d[0,i] != None:
00190             if scan_id != None and dataset.scan_ids != None:
00191                 if scan_id != dataset.scan_ids[0,i]:
00192                     continue
00193             if POSITIVE == dataset.outputs[0,i]:
00194                 ppt2d.append(dataset.pt2d[:,i]/scale)
00195             if NEGATIVE == dataset.outputs[0,i]:
00196                 npt2d.append(dataset.pt2d[:,i]/scale)
00197     if len(ppt2d) > 0:
00198         draw_points(img, np.column_stack(ppt2d), [0,255,0], size)
00199     if len(npt2d) > 0:
00200         draw_points(img, np.column_stack(npt2d), [0,0,255], size)
00201 
00202 def inverse_indices(indices_exclude, num_elements):
00203     temp_arr = np.zeros(num_elements)+1
00204     temp_arr[indices_exclude] = 0
00205     return np.where(temp_arr)[0]
00206 
00207 #'_features_dict.pkl'
00208 def preprocess_scan_extract_features(raw_data_fname, ext):
00209     rec_params = Recognize3DParam()
00210     #if not kinect:
00211     #    feature_extractor, data_pkl = load_data_from_file(raw_data_fname, rec_params)
00212     #    image_fname = pt.join(pt.split(raw_data_fname)[0], data_pkl['high_res'])
00213     #else:
00214     feature_extractor, data_pkl = load_data_from_file2(raw_data_fname, rec_params)
00215     image_fname = pt.join(pt.split(raw_data_fname)[0], data_pkl['image'])
00216     print 'Image name is', image_fname
00217     img = cv.LoadImageM(image_fname)
00218     feature_cache_fname = pt.splitext(raw_data_fname)[0] + ext
00219     instances, points2d, points3d = feature_extractor.extract_features()
00220     labels = np.matrix([UNLABELED] * instances.shape[1])
00221 
00222     #pdb.set_trace()
00223     #cv.SaveImage('DATASET_IMAGES.png', instances_to_image(rec_params.win_size, instances[38:,:], 0., 1.))
00224     preprocessed_dict = {'instances': instances,
00225                          'points2d': points2d,
00226                          'points3d': points3d,
00227                          'image': image_fname,
00228                          'labels': labels,
00229                          'sizes': feature_extractor.get_sizes()}
00230     if data_pkl.has_key('synthetic_locs3d'):
00231         preprocessed_dict['synthetic_locs3d'] = data_pkl['synthetic_locs3d']
00232 
00233     rospy.loginfo('saving results')
00234     ut.save_pickle(preprocessed_dict, feature_cache_fname)
00235     return feature_cache_fname
00236 
00237 def preprocess_data_in_dir(dirname, ext):
00238     print 'Preprocessing data in', dirname
00239     data_files = glob.glob(pt.join(dirname, '*dataset.pkl'))
00240     print 'Found %d scans' % len(data_files)
00241 
00242     for n in data_files:
00243         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
00244         print 'Loading', n
00245         cn = preprocess_scan_extract_features(n, ext)
00246         print 'Saved to', cn
00247         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
00248 
00249 def make_point_exclusion_test_set(training_dataset, all_data_dir, ext):
00250     #pdb.set_trace()
00251     scan_names = glob.glob(pt.join(all_data_dir, '*' + ext))
00252     dset = {'inputs': [], 'outputs': [], 'pt2d': [], 'pt3d': []}
00253     sizes = None
00254     i = 0
00255     for sn in scan_names:
00256         #load scan
00257         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
00258         print 'Loading scan', sn
00259         cn = ut.load_pickle(sn)
00260         if sizes == None:
00261             sizes = cn['sizes']
00262         selected_pts_in_train = np.where(training_dataset.scan_ids == sn)[1]
00263         print '  There are %d points in scan' % cn['instances'].shape[1]
00264 
00265         #if there are points in training set that are in this scan, unselect them
00266         if len(selected_pts_in_train) > 0:
00267             print '  There are %d of these points in the training set.' % len(selected_pts_in_train)
00268             scan_ind = training_dataset.idx_in_scan[0, selected_pts_in_train].A1
00269             select_ind = inverse_indices(scan_ind, cn['instances'].shape[1])
00270             assert((len(scan_ind) + len(select_ind)) == cn['instances'].shape[1])
00271         else:
00272             select_ind = np.array(range(cn['instances'].shape[1]))
00273         print '  Including %d points from this dataset' % len(select_ind)
00274         
00275         for datak, dsetk in [('instances', 'inputs'), ('labels', 'outputs'),\
00276                   ('points2d', 'pt2d'), ('points3d', 'pt3d')]:
00277             dset[dsetk].append(cn[datak][:, select_ind])
00278         i = i + 1
00279         if i > 2:
00280             break
00281 
00282     return InterestPointDataset(np.column_stack(dset['inputs']),\
00283                                 np.column_stack(dset['outputs']),\
00284                                 None, None, None, sizes = sizes)
00285 
00286 
00287 
00288 
00289 class SVM:
00290     ##
00291     # zero is on negative side of decision boundary
00292     # 0  /  1
00293     # -  /  +
00294     def __init__(self, dataset, params):
00295         samples = dataset.inputs.T.tolist()
00296         labels = dataset.outputs.T.A1.tolist()
00297         #pdb.set_trace()
00298         print 'SVM: training with params => ', params
00299         #pdb.set_trace()
00300         #dataset_to_libsvm(dataset, 'total_set_light_switch_libsvm.data')
00301         self.model = su.svm_train(labels, samples, params)
00302         self.nsamples = len(samples)
00303 
00304     def sv_indices(self):
00305         return np.where(self.model.get_support_vectors(self.nsamples))[0]
00306 
00307     def predict(self, instances):
00308         xi = instances.T.tolist()
00309         return su.svm_predict([0]*instances.shape[1], xi, self.model)[0]
00310 
00311     def distances(self, instances):
00312         xi = instances.T.tolist()
00313         dists = su.svm_predict([0]*instances.shape[1], xi, self.model)[2]
00314         return (np.matrix(dists)).T.A1.tolist()
00315 
00316 
00317 class DataScale:
00318 
00319     def __init__(self):
00320         self.maxes = None
00321         self.mins = None
00322         self.ranges = None
00323 
00324     def scale(self, data):
00325         if self.maxes == None:
00326             self.maxes = np.max(data,1)
00327             self.mins = np.min(data,1)
00328             self.ranges = self.maxes - self.mins
00329             self.ranges[np.where(self.ranges < .001)[0], :] = 1.
00330             #pdb.set_trace()
00331         #pdb.set_trace()
00332         #pdb.set_trace()
00333         scaled = (((data - self.mins) / self.ranges) * 2.) - 1
00334         return scaled
00335 
00336 
00337 class PCAIntensities:
00338 
00339     def __init__(self, intensities_index, reconstruction_std_lim, reconstruction_err_toler):
00340         self.intensities_mean     = None
00341         self.intensities_std      = None
00342         self.projection_basis     = None
00343         self.intensities_index    = intensities_index
00344         self.recon_err_raw        = None
00345         self.reconstruction_error = None
00346         self.pca_data             = None
00347         self.reconstruction_std_lim = reconstruction_std_lim
00348         self.reconstruction_err_toler = reconstruction_err_toler
00349 
00350     def calculate_pca_vectors(self, data, variance_keep):
00351         data_in = data[self.intensities_index:, :]
00352         #we already have pca vectors
00353         #pdb.set_trace()
00354         print 'PCAIntensities: data.shape', data.shape
00355         if self.intensities_mean != None:
00356             normed_data = (data_in - self.intensities_mean) / self.intensities_std
00357             #if not self.is_dataset_far_from_pca_subspace(self.projection_basis.T * normed_data, normed_data):
00358             if True:
00359                 print 'PCAIntensities: is_dataset_far_from_pca_subspace no, dataset is not far.'
00360                 return
00361             else:
00362                 print 'PCAIntensities: is_dataset_far_from_pca_subspace yes, dataset is far. recalculating pca.'
00363                 #pdb.set_trace()
00364                 nsamples = min(data_in.shape[1], 3000) #2000 is the max that we can handle
00365                 loaded_data = ut.load_pickle(self.pca_data)
00366                 data_in  = np.column_stack((data_in, loaded_data[self.intensities_index:, :]))
00367                 ntotal   = data_in.shape[1]
00368                 data_in  = data_in[:, np.random.permutation(np.array(range(ntotal)))[0:nsamples]]
00369 
00370         self.intensities_mean = np.mean(data_in, 1)
00371         self.intensities_std = np.std(data_in, 1)
00372         self.intensities_std[np.where(self.intensities_std == 0)[0].A1, :] = 1
00373 
00374         data_in_shifted = data_in - self.intensities_mean
00375         data_in_normed = data_in_shifted / self.intensities_std
00376         print 'PCAIntensities.calculate_pca_vectors: Constructing PCA basis'
00377         #self.projection_basis = dr.pca_vectors(data_in_normed, variance_keep)[:,:50]
00378         #pdb.set_trace()
00379         self.projection_basis = dr.pca_vectors(data_in_normed, variance_keep)[:,:50]
00380         #self.projection_basis = dr.pca_vectors(data_in_normed, variance_keep)
00381         print 'PCAIntensities.calculate_pca_vectors: PCA basis size -', self.projection_basis.shape
00382 
00383         projected = (self.projection_basis.T * data_in_normed)
00384         reconstruction = self.projection_basis * projected
00385         self.recon_err_raw = ut.norm(data_in_normed - reconstruction)
00386         self.recon_mean = np.mean(self.recon_err_raw)
00387         self.recon_std = np.std(self.recon_err_raw)
00388         self.reconstruction_error = self.calc_reconstruction_errors(projected, data_in_normed)
00389 
00390         pca_data_name = time.strftime('%A_%m_%d_%Y_%I:%M%p') + '_pca_data.pkl'
00391         #pdb.set_trace()
00392         ut.save_pickle(data, pca_data_name)
00393         self.pca_data = pca_data_name
00394 
00395     def calc_reconstruction_errors(self, projected_instances, original_instances):
00396         errors = ut.norm((self.projection_basis * projected_instances) - original_instances)
00397         mal_dist_errors = (errors - self.recon_mean) / (self.recon_std**2)
00398         nhigh_errors = np.sum(np.abs(mal_dist_errors).A1 > self.reconstruction_std_lim)
00399         npoints = original_instances.shape[1]
00400         percent_error = nhigh_errors / (float(npoints))
00401         rospy.loginfo('calc_reconstruction_errors: %.2f (%d / %d) with high reconstruction errors' \
00402                 % (percent_error, nhigh_errors, npoints))
00403         return percent_error
00404 
00405     def is_dataset_far_from_pca_subspace(self, projected_instances, original_instances):
00406         percent_error = self.calc_reconstruction_errors(projected_instances, original_instances)
00407         return percent_error > (self.reconstruction_error + self.reconstruction_err_toler)
00408 
00409     def partial_pca_project(self, instances):
00410         #pdb.set_trace()
00411         #self.intensities_mean = np.mean(data_in, 1)
00412         #instances1084G
00413         instance_mean = np.mean(instances[self.intensities_index:, :], 1) 
00414         #instances_in = (instances[self.intensities_index:, :] - self.intensities_mean) / self.intensities_std
00415         instances_in = (instances[self.intensities_index:, :] - instance_mean) / self.intensities_std
00416         reduced_intensities = self.projection_basis.T * instances_in
00417         return np.row_stack((instances[:self.intensities_index, :], reduced_intensities))
00418 
00419 class SVMPCA_ActiveLearner:
00420 
00421     ##
00422     # @param old_learner takes pca vectors calculated from old_learner if available
00423     # @param pca or take pca vectors from this param
00424     def __init__(self, use_pca, reconstruction_std_lim=None, 
00425                  reconstruction_err_toler=None, old_learner=None, pca=None):
00426         self.classifier = 'svm' #or 'knn'
00427         self.classifiers = {}
00428         self.n = 3.
00429 
00430         #self.intensities_mean = None
00431         #self.projection_basis = None
00432         self.reduced_dataset = None
00433         self.dataset = None
00434 
00435         self.use_pca = use_pca
00436         self.reconstruction_std_lim = reconstruction_std_lim
00437         self.reconstruction_err_toler = reconstruction_err_toler
00438         self.pca = None
00439 
00440         if old_learner != None:
00441             self.pca = old_learner.pca
00442 
00443         if pca != None:
00444             self.pca = pca
00445 
00446         #pdb.set_trace()
00447         #if old_learner != None:
00448         #    self.intensities_mean = old_learner.intensities_mean
00449         #    self.intensities_std = old_learner.intensities_std
00450         #    self.projection_basis = old_learner.projection_basis
00451         #    self.intensities_index = old_learner.intensities_index
00452         #    self.recon_err_raw = old_learner.recon_err_raw
00453         #    self.reconstruction_error = old_learner.reconstruction_error
00454         #    self.pca_data = old_learner.pca_data
00455 
00456     def partial_pca_project(self, instances):
00457         if self.use_pca:
00458             return self.pca.partial_pca_project(instances)
00459         else:
00460             return instances
00461 
00462     def get_closest_instances(self, instances, n=1):
00463         #pdb.set_trace()
00464         if self.use_pca:
00465             p_instances = np.matrix(self.partial_pca_project(instances))
00466         else:
00467             p_instances = instances
00468             #pdb.set_trace()
00469         s_instances = self.scale.scale(p_instances)
00470         distances = np.array(self.classifiers['svm'].distances(s_instances))
00471         selected_indices = np.argsort(np.abs(distances))[0:n]
00472         return selected_indices.tolist(), distances[selected_indices]
00473 
00474     def select_next_instances(self, instances, n=1):
00475         #pdb.set_trace()
00476         data_idx, data_dists = self.get_closest_instances(instances, n)
00477         data_dist = abs(data_dists[0])
00478         sv_dist   = abs(self.sv_dist[0])
00479 
00480         #we've converged if distance to datapoint closest to decision boundary
00481         #is no closer than distance to the support vectors. 
00482         #So we return nothing as a proposal.
00483         print 'SVMPCA_ActiveLearner: support vector dist %f data dist %f' % (sv_dist, data_dist)
00484         if sv_dist < data_dist:
00485             return None, None
00486         else:
00487             return data_idx, data_dists
00488 
00489     def select_next_instances_no_terminate(self, instances, n=1):
00490         data_idx, data_dists = self.get_closest_instances(instances, n)
00491         data_dist = abs(data_dists[0])
00492         sv_dist   = abs(self.sv_dist[0])
00493         return data_idx, data_dists, sv_dist < data_dist
00494 
00495     def train(self, dataset, inputs_for_scaling, svm_params, variance_keep=.95):
00496         #pdb.set_trace()
00497         #pdb.set_trace()
00498         #TODO: somehow generate labels for these datasets...
00499         self.dataset = dataset
00500         trainingset = dataset.inputs
00501         responses = dataset.outputs
00502 
00503         #Calculate PCA vectors (also try do detect if our PCA vectors need updating)
00504         if self.use_pca: #and self.projection_basis == None:
00505             #self.intensities_index = self.dataset.metadata[-1].extent[0]
00506             #rebalanced_set = self._balance_classes(trainingset, responses)
00507             #self._calculate_pca_vectors(rebalanced_set, variance_keep)
00508             #self._calculate_pca_vectors(inputs_for_scaling, variance_keep)
00509             if self.pca == None:
00510                 self.pca = PCAIntensities(self.dataset.metadata[-1].extent[0], self.reconstruction_std_lim, self.reconstruction_err_toler)
00511             self.pca.calculate_pca_vectors(inputs_for_scaling, variance_keep)
00512             #self.pca.calculate_pca_vectors(rebalanced_set, variance_keep, incremental=True)
00513 
00514         trainingset = self.partial_pca_project(trainingset)
00515         inputs_for_scaling = self.partial_pca_project(inputs_for_scaling)
00516     
00517         print 'SVMPCA_ActiveLearner.train: Training classifier.'
00518         #train => float32 mat, each row is an example
00519         #responses => float32 mat, each column is a corresponding response
00520         trainingset = np.matrix(trainingset, dtype='float32').copy()
00521         responses = np.matrix(responses, dtype='float32').copy()
00522 
00523         self.reduced_dataset = ds.Dataset(trainingset.copy(), responses.copy())
00524         self.scale = DataScale()
00525         if inputs_for_scaling == None:
00526             inputs_for_scaling = self.reduced_dataset.inputs
00527         else:
00528             print 'SVMPCA_ActiveLearner.train: using large input set for setting scaling parameters'
00529         self.scale.scale(inputs_for_scaling)
00530         rescaled_inputs = self.scale.scale(self.reduced_dataset.inputs)
00531         self.rescaled_dataset = ds.Dataset(rescaled_inputs, self.reduced_dataset.outputs)
00532 
00533         #dataset_to_libsvm(self.rescaled_dataset, 'interest_point_data.libsvm')
00534         self.classifiers['svm'] = SVM(self.rescaled_dataset, svm_params)
00535         #self.classifiers['knn'] = sp.KDTree(np.array(self.rescaled_dataset.inputs.T))
00536 
00537         self.sv_instances = self.dataset.inputs[:, self.classifiers['svm'].sv_indices()]
00538         self.sv_idx, self.sv_dist = self.get_closest_instances(self.sv_instances, 1)
00539 
00540     ##
00541     # @param instances column vectors of instances to predict
00542     def classify(self, instances):
00543         #pdb.set_trace()
00544 #        pdb.set_trace()
00545         projected_inst = np.matrix(self.partial_pca_project(instances), dtype='float32').copy()
00546         scaled_inst = self.scale.scale(projected_inst)
00547         if self.classifier == 'knn':
00548             labels = self.reduced_dataset.outputs[:, \
00549                     self.classifiers['knn'].query(scaled_inst, self.n)[1].tolist()[0]]
00550             if np.sum(labels) > (self.n/2.):
00551                 return POSITIVE
00552             else:
00553                 return NEGATIVE
00554 
00555         elif self.classifier == 'svm':
00556             #pdb.set_trace()
00557             r = self.classifiers['svm'].predict(scaled_inst)
00558             return r
00559 
00560     def _balance_classes(self, data, labels):
00561         posidx = np.where(labels == POSITIVE)[1].A1
00562         negidx = np.where(labels == NEGATIVE)[1].A1
00563         diff = abs(posidx.shape[0] - negidx.shape[0])
00564         if diff == 0:
00565             return data
00566 
00567         rospy.loginfo('SVMPCA_ActiveLearner: _balance_classes difference in class sizes is %d' % diff)
00568 
00569         posex = data[:, posidx]
00570         negex = data[:, negidx]
00571         if posidx.shape[0] < negidx.shape[0]:
00572             rospy.loginfo('SVMPCA_ActiveLearner. _balance_classes making data from POSITIVE instances')
00573             sset = posex
00574         else:
00575             rospy.loginfo('SVMPCA_ActiveLearner. _balance_classes making data from NEGATIVE instances')
00576             sset = negex
00577         
00578         rsubset = sset[:, np.random.randint(0, sset.shape[1], diff)]
00579         rospy.loginfo('SVMPCA_ActiveLearner: _balance_classes created %d instances to make up for it' % rsubset.shape[1])
00580 
00581         return np.column_stack((posex, negex, rsubset))
00582 
00583 class InterestPointDataset(ds.Dataset):
00584 
00585     def __init__(self, inputs, outputs, pt2d, pt3d, feature_extractor, scan_ids=None, idx_in_scan=None, sizes=None):
00586         ds.Dataset.__init__(self, inputs, outputs)
00587         self.pt2d = pt2d
00588         self.pt3d = pt3d
00589         self.scan_ids = scan_ids
00590         #if scan_ids != None:
00591         #    print 'scan id class', self.scan_ids.__class__
00592         self.idx_in_scan = idx_in_scan
00593         offset = 0
00594 
00595         #Intensity has to be the last feature
00596         if feature_extractor != None or sizes != None:
00597             if feature_extractor != None:
00598                 sizes = feature_extractor.get_sizes
00599             for k in ['expected_loc', 'distance', 'fpfh', 'intensity']:
00600                 if sizes.has_key(k):
00601                     start_idx = offset 
00602                     end_idx = offset + sizes[k]
00603                     self.add_attribute_descriptor(ds.AttributeDescriptor(k, (start_idx, end_idx)))
00604                     offset = end_idx
00605 
00606     def select_features(self, features):
00607         fset = set(features)
00608         selected_fea = []
00609         meta_data = []
00610         offset = 0
00611         for meta in self.metadata:
00612             m = copy.deepcopy(meta)
00613             if fset.issuperset([m.name]):
00614                 # TODO FIX THIS
00615                 #if m.name == 'distance':
00616                 #    m.extent = [0,4]
00617                 size_m = m.extent[1] - m.extent[0]
00618                 selected_fea.append(self.inputs[m.extent[0]:m.extent[1], :])
00619                 m.extent = [offset, offset+size_m]
00620                 meta_data.append(m)
00621                 offset = offset + size_m
00622         self.metadata = meta_data
00623         self.inputs = np.row_stack(selected_fea)
00624 
00625     def features_named(self, features):
00626         fset = set(features)
00627         selected_fea = []
00628         for meta in self.metadata:
00629             if fset.issuperset([meta.name]):
00630                 selected_fea.append(self.inputs[meta.extent[0]:meta.extent[1], :])
00631         return np.row_stack(selected_fea)
00632 
00633     def add(self, features, label, pt2d, pt3d, scan_id=None, idx_in_scan=None):
00634         print 'added point', pt2d[0,0], pt2d[1,0]
00635         if np.abs(pt2d[1,0]) > 10000:
00636             pdb.set_trace()
00637         if np.abs(pt2d[0,0]) > 10000:
00638             pdb.set_trace()
00639         self.inputs = np.column_stack((self.inputs, features))
00640         self.outputs = np.column_stack((self.outputs, label))
00641         self.pt2d = np.column_stack((self.pt2d, pt2d))
00642         self.pt3d = np.column_stack((self.pt3d, pt3d))
00643         if scan_id != None:
00644             self.scan_ids = np.column_stack((self.scan_ids, scan_id))
00645         if idx_in_scan != None:
00646             self.idx_in_scan = np.column_stack((self.idx_in_scan, idx_in_scan))
00647         
00648     def remove(self, instance_idx):
00649         self.inputs = np.column_stack((self.inputs[:,0:instance_idx], self.inputs[:,instance_idx+1:]))
00650         self.outputs = np.column_stack((self.outputs[:,0:instance_idx], self.outputs[:,instance_idx+1:]))
00651         self.pt2d = np.column_stack((self.pt2d[:,0:instance_idx], self.pt2d[:,instance_idx+1:]))
00652         self.pt3d = np.column_stack((self.pt3d[:,0:instance_idx], self.pt3d[:,instance_idx+1:]))
00653         if self.scan_ids != None:
00654             self.scan_ids = np.column_stack((self.scan_ids[:,0:instance_idx], self.scan_ids[:,instance_idx+1:]))
00655         if self.idx_in_scan != None:
00656             self.idx_in_scan = np.column_stack((self.idx_in_scan[:,0:instance_idx], self.idx_in_scan[:,instance_idx+1:]))
00657 
00658     def copy(self):
00659         ipd = InterestPointDataset(self.inputs.copy(), self.outputs.copy(), 
00660                 copy.copy(self.pt2d), copy.copy(self.pt3d), None)
00661         ipd.metadata = copy.deepcopy(self.metadata)
00662         return ipd
00663 
00664     def subset(self, indices):
00665         ipd = InterestPointDataset(self.inputs[:, indices].copy(), self.outputs[:, indices].copy(), 
00666                 copy.copy(self.pt2d[:, indices]), copy.copy(self.pt3d[:, indices]), None)
00667         ipd.metadata = copy.deepcopy(self.metadata)
00668         return ipd
00669 
00670     @classmethod
00671     def add_to_dataset(cls, dataset, features, label, pt2d, pt3d, scan_id, idx_in_scan, sizes):
00672         if dataset == None:
00673             dataset = InterestPointDataset(features, label, pt2d, pt3d, None, scan_id, idx_in_scan, sizes)
00674         else:
00675             dataset.add(features, label, pt2d, pt3d, scan_id=scan_id, idx_in_scan=idx_in_scan)
00676         return dataset
00677 
00678 
00679 class Recognize3DParam:
00680 
00681     def __init__(self):
00682         #Data extraction parameters
00683         self.grid_resolution = .01
00684         self.win_size = 15
00685         #self.win_multipliers = [1,2,4,8,16,32] for prosilica
00686         #self.win_multipliers = [1,2,4,8,16,32]
00687         self.win_multipliers = [2,4,8,16]
00688 
00689         self.win3d_size = .02
00690         self.voi_bl = [.5, .5, .5]
00691         self.radius = .5
00692         self.robot_reach_radius = 2.5
00693         #self.svm_params = '-s 0 -t 2 -g .0625 -c 4'
00694         #self.svm_params = '-s 0 -t 2 -g .0625 -c 4'
00695         #self.svm_params = '-s 0 -t 2 -g .4 -c 4'
00696         #self.svm_params = '-s 0 -t 2 -g 3.0 -c 4'
00697         #self.svm_params = '-s 0 -t 2 -g 5. -c 4'
00698         #self.svm_params = '-s 0 -t 2 -g .01 -c 4'
00699         #self.svm_params = '-s 0 -t 2 -g .2 -c 4'
00700         self.svm_params = '-s 0 -t 2 -g .5 -c .5'
00701         #self.svm_params = '-s 0 -t 2 -g 100 -c .5'
00702 
00703         #sampling parameters
00704         #self.n_samples = 5000
00705         #self.n_samples = 5000
00706         self.n_samples = 1500
00707         self.uni_mix = .3
00708         self.max_points_per_site = 5
00709 
00710         self.uncertainty_x = .1
00711         self.uncertainty_y = .1
00712         self.uncertainty_z = .1
00713         #print "Uncertainty is:", self.uncertainty
00714 
00715         #variance
00716         self.variance_keep = .99
00717         self.reconstruction_std_lim = 1.
00718         self.reconstruction_err_toler = .05
00719 
00720 
00721 class ImagePublisher:
00722 
00723     def __init__(self, channel, cal=None):
00724         from cv_bridge import CvBridge, CvBridgeError
00725         from sensor_msgs.msg import Image
00726 
00727         self.bridge = CvBridge()
00728         self.image_pub = rospy.Publisher(channel + '/image', Image)
00729         if cal != None:
00730             self.image_cal_pub = rospy.Publisher(channel + '/camera_info', sm.CameraInfo)
00731             self.cal = cal
00732         else:
00733             self.image_cal_pub = None
00734 
00735     def publish(self, cv_image): 
00736         self.image_pub.publish(self.bridge.cv_to_imgmsg(cv_image, "bgr8"))
00737         if self.image_cal_pub != None:
00738             self.image_cal_pub.publish(self.cal.msg)
00739 
00740 def find_max_in_density(locs2d):
00741     import scipy.stats as sct
00742     import scipy
00743     x = locs2d[0,:]
00744     y = locs2d[1,:]
00745 
00746     max_x = np.max(x)
00747     max_y = np.max(y)
00748     min_x = np.min(x)
00749     min_y = np.min(y)
00750 
00751     X, Y      = scipy.mgrid[min_x:max_x:500j, min_y:max_y:500j]
00752     positions = scipy.c_[X.ravel(), Y.ravel()]
00753     values    = scipy.c_[locs2d[0,:].A1, locs2d[1,:].A1]
00754     kernel    = sct.kde.gaussian_kde(values.T)
00755     Z         = np.reshape(kernel(positions.T).T, X.T.shape)
00756     loc_max   = np.argmax(Z)
00757     loc2d_max = np.matrix([X.flatten()[loc_max], Y.flatten()[loc_max]]).T
00758     
00759     #pylab.imshow(np.rot90(Z, 2), cmap=pylab.cm.gist_earth_r, extent=[0,img.cols, 0, img.rows])
00760     #pylab.imshow(img, cmap=pylab.cm.gist_earth_r, extent=[0,img.cols, 0, img.rows])
00761     #pylab.plot(locs2d[0,:].A1, locs2d[1,:].A1, 'k.', markersize=2)
00762     #pylab.plot([loc2d_max[0,0]], [loc2d_max[1,0]], 'gx')
00763     #cv.ShowImage("Positive Density", 255 * (np.rot90(Z)/np.max(Z)))
00764     #pdb.set_trace()
00765 
00766     return loc2d_max, Z
00767 
00768 class ScanLabeler:
00769 
00770     def __init__(self, dirname, ext, scan_to_train_on, seed_dset, features_to_use):
00771         self.scan_dir_name = dirname
00772         self.scan_names = glob.glob(pt.join(dirname, '*' + ext))
00773         self.scan_names.append(self.scan_names.pop(0))
00774         self.feature_file_ext = ext
00775         self.features_to_use = features_to_use
00776 
00777         self.current_scan_pred = None
00778         self.current_scan = None
00779         self.cdisp = None
00780 
00781         self.scan_idx = self.search_dataset_id(scan_to_train_on)
00782         if self.scan_idx == None:
00783             print 'ERROR: %s not found in dir %s' % (scan_to_train_on, dirname)
00784             self.scan_idx = 0
00785 
00786         self.scale = 1/3.
00787         #self.scale = 1.
00788         self.mode = 'GROUND_TRUTH'
00789         if seed_dset == None:
00790             self.training_sname = pt.splitext(self.scan_names[self.scan_idx])[0] + '_seed.pkl'
00791         else:
00792             self.training_sname = seed_dset
00793         print 'Using seed dataset name', self.training_sname
00794         self.frame_number = 0
00795 
00796         self.rec_params = Recognize3DParam()
00797         self.learner = None
00798         self.dataset = None #Training dataset
00799 
00800         cv.NamedWindow('Scan', cv.CV_WINDOW_AUTOSIZE)
00801         cv.NamedWindow('Positive Density', cv.CV_WINDOW_AUTOSIZE)
00802         self.load_scan(self.scan_names[self.scan_idx])
00803         cv.SetMouseCallback('Scan', self.mouse_cb, None)
00804 
00805 
00806     def search_dataset_id(self, scan_name):
00807         scan_idx = None
00808         for i, n in enumerate(self.scan_names):
00809             if n == scan_name:
00810                 scan_idx = i
00811         return scan_idx
00812 
00813 
00814     def classify_current_scan(self):
00815         if self.learner != None:
00816             sdset = self.select_features(self.current_scan['instances'], 
00817                     self.features_to_use, self.current_scan['sizes'])
00818             results = np.matrix(self.learner.classify(sdset))
00819             self.current_scan_pred = InterestPointDataset(sdset, results,
00820                                         self.current_scan['points2d'], self.current_scan['points3d'], None)
00821             if np.any(self.current_scan['labels'] == UNLABELED):
00822                 return
00823         
00824     def load_scan(self, fname):
00825         print 'Loading scan', fname
00826         self.cdisp = {}
00827         self.current_scan = ut.load_pickle(fname)
00828         #image_fname = pt.join(pt.split(fname)[0], self.current_scan['image'])
00829         img = cv.LoadImageM(self.current_scan['image'])
00830         self.cdisp['tree'] = sp.KDTree(np.array(self.current_scan['points2d'].T))
00831         self.cdisp['cv'] = cv.CreateMat(int(round(img.rows*self.scale)), 
00832                                         int(round(img.cols*self.scale)), cv.CV_8UC3)
00833         cv.Resize(img, self.cdisp['cv'])
00834         print 'loaded!'
00835         self.classify_current_scan()
00836         self.draw()
00837 
00838     def save_current(self):
00839         print 'saving current scan\'s data'
00840         fname = self.scan_names[self.scan_idx]
00841         print 'WARNING: THIS SHOULD NOT BE CALLED.'
00842         ut.save_pickle(self.current_scan, fname)
00843         print 'done saving!'
00844 
00845     def load_next(self):
00846         self.scan_idx = max(min(self.scan_idx+1, len(self.scan_names)-1), 0)
00847         self.load_scan(self.scan_names[self.scan_idx])
00848 
00849     def load_prev(self):
00850         self.scan_idx = min(max(self.scan_idx-1, 0), len(self.scan_names)-1)
00851         self.load_scan(self.scan_names[self.scan_idx])
00852 
00853     def draw(self, save_postf=""):
00854         img = cv.CloneMat(self.cdisp['cv'])
00855         #density_img = cv.fromarray(np.zeros((img.rows, img.cols)))
00856 
00857         #Draw ground truth labels
00858         #pdb.set_trace()
00859         pidx = np.where(self.current_scan['labels'] == POSITIVE)[1].A1.tolist()
00860         nidx = np.where(self.current_scan['labels'] == NEGATIVE)[1].A1.tolist()
00861         uidx = np.where(self.current_scan['labels'] == UNLABELED)[1].A1.tolist()
00862 
00863         if len(pidx) > 0:
00864             ppoints = self.current_scan['points2d'][:, pidx]
00865             draw_points(img, ppoints * self.scale, [0,255,0], 2, 1)
00866 
00867         if len(nidx) > 0:
00868             npoints = self.current_scan['points2d'][:, nidx]
00869             draw_points(img, npoints * self.scale, [0,0,255], 2, 1)
00870 
00871         if len(uidx) > 0:
00872             upoints = self.current_scan['points2d'][:, uidx]
00873             draw_points(img, upoints * self.scale, [255,255,255], 2, 1)
00874 
00875         #Draw training set
00876         if self.dataset != None:
00877             #pdb.set_trace()
00878             draw_dataset(self.dataset, img, 1./self.scale, 4, scan_id=self.scan_names[self.scan_idx])
00879 
00880         if self.current_scan_pred != None:
00881             draw_labeled_points(img, self.current_scan_pred, scale=1./self.scale)
00882             locs2d = self.current_scan_pred.pt2d[:, (np.where(POSITIVE == self.current_scan_pred.outputs)[1]).A1]
00883 
00884         #    loc_max, Z = find_max_in_density(locs2d)
00885         #    print 'Max location is', loc_max.T
00886         #    cv.ShowImage("Positive Density", 255 * (np.rot90(Z)/np.max(Z)))
00887 
00888             #X, Y = scipy.mgrid[0:img.cols:500j, 0:img.rows:500j]
00889             #positions = scipy.c_[X.ravel(), Y.ravel()]
00890             #values = scipy.c_[locs2d[0,:].A1, locs2d[1,:].A1]
00891             #kernel = sct.kde.gaussian_kde(values.T)
00892             #Z = np.reshape(kernel(positions.T).T, X.T.shape)
00893             #loc_max = np.argmax(Z)
00894             #loc2d_max = np.matrix([X.flatten()[loc_max], Y.flatten()[loc_max]]).T
00895             ##pdb.set_trace()
00896 
00897             #pylab.imshow(np.rot90(Z, 2), cmap=pylab.cm.gist_earth_r, extent=[0,img.cols, 0, img.rows])
00898             ##pylab.imshow(img, cmap=pylab.cm.gist_earth_r, extent=[0,img.cols, 0, img.rows])
00899             #pylab.plot(locs2d[0,:].A1, locs2d[1,:].A1, 'k.', markersize=2)
00900             #pylab.plot([loc2d_max[0,0]], [loc2d_max[1,0]], 'gx')
00901             #pdb.set_trace()
00902             #pylab.show()
00903             #draw_labeled_points(density_img, self.current_scan_pred, 
00904             #        scale=1./self.scale, pos_color=[255, 255, 255], neg_color=[0,0,0])
00905             #cv.Smooth(density_img, density_img, cv.CV_GAUSSIAN, 151, 151, 2)
00906 
00907         #Display
00908         #cv.ShowImage('Positive Density', density_img)
00909         cv.ShowImage('Scan', img)
00910         path = pt.splitext(insert_folder_name(self.scan_names[self.scan_idx], save_postf))[0]
00911         img_name = path + ('_active_learn%d.png' % (self.frame_number))
00912         cv.SaveImage(img_name, img)
00913         self.frame_number = self.frame_number + 1
00914         print '- refreshed display - %s' % img_name
00915 
00916     def step(self):
00917         k = cv.WaitKey(33)
00918         if k == ord('n'):
00919             print 'Loading next scan..'
00920             self.load_next()
00921 
00922         if k == ord('p'):
00923             print 'loading previous scan..'
00924             self.load_prev()
00925 
00926         if k == ord('0'):
00927             self.current_scan['labels'][0, :] = NEGATIVE
00928             self.draw()
00929             print 'Labeling everything as negative!'
00930 
00931         if k == ord('`'):
00932             if self.mode == 'TRAINING_SET':
00933                 self.mode = 'GROUND_TRUTH'
00934             else:
00935                 self.mode = 'TRAINING_SET'
00936             print 'ScanLabeler GUI mode changed to', self.mode
00937 
00938         if k == ord('c'):
00939             self.save_current()
00940             
00941         if k == ord('s'):
00942             if self.dataset != None:
00943                 #pdb.set_trace()
00944                 ut.save_pickle(self.dataset, self.training_sname)
00945                 print 'saved to', self.training_sname
00946 
00947         if k == ord('l'):
00948             if self.dataset == None and pt.isfile(self.training_sname):
00949                 print 'loading training set from disk'
00950                 self.dataset = ut.load_pickle(self.training_sname)
00951                 print 'loaded', self.training_sname
00952                 self.draw()
00953 
00954         if k == ord('t'):
00955             if self.dataset != None:
00956                 print 'Making test set.'
00957                 curr_test_set = make_point_exclusion_test_set(self.dataset, self.scan_dir_name)
00958                 print 'Test set has %d instances' % curr_test_set.inputs.shape[1]
00959                 fname = raw_input('Enter test set name to save to: ')
00960                 print 'Saving to', fname
00961                 ut.save_pickle(curr_test_set, fname)
00962                 print 'Saved!'
00963 
00964         if k == ord('r'):
00965             print "Training"
00966             #pdb.set_trace()
00967             self.train(self.select_features(self.current_scan['instances'], 
00968                 self.features_to_use, self.current_scan['sizes']))
00969             self.classify_current_scan()
00970             self.draw()
00971 
00972         if k == ord(' '):
00973             if self.learner != None:
00974                 print "selecting.."
00975                 #pdb.set_trace()
00976                 dset = self.select_features(self.current_scan['instances'], 
00977                         self.features_to_use, self.current_scan['sizes'])
00978                 #self.current_scan['instances']
00979                 selected_idx, selected_dist = self.learner.select_next_instances(dset)
00980                 if selected_idx != None:
00981                     self.add_to_training_set(selected_idx)
00982                     #self.train(self.train(self.current_scan['instances']))
00983                     self.train(self.select_features(self.current_scan['instances'], 
00984                         self.features_to_use, self.current_scan['sizes']))
00985                     self.classify_current_scan()
00986                     self.draw()
00987                 else:
00988                     print '======================='
00989                     print '>> LEARNER CONVERGED <<'
00990                     print '======================='
00991 
00992         if k == ord('z'):
00993             #d = self.dataset
00994             #d1 = InterestPointDataset(self.current_scan['instances'], self.current_scan['labels'],
00995             #        self.current_scan['points2d'], self.current_scan['points3d'], 
00996             #        None, sizes=self.current_scan['sizes'])
00997             # self.load_next()
00998             # d1.add(self.current_scan['instances'], self.current_scan['labels'],
00999             #         self.current_scan['points2d'], self.current_scan['points3d'])
01000 
01001             #self.dataset = d1
01002             #self.train()
01003             print 'generating libsvm dataset'
01004             dfname = raw_input('enter dataset filename: ')
01005             dataset_to_libsvm(self.learner.rescaled_dataset, dfname)
01006             #self.dataset = d
01007             print 'done'
01008 
01009     #def instances_to_image(self, instances, min_val, max_val):
01010     #    img_arrs = []
01011     #    for i in range(instances.shape[1]):
01012     #        img_arrs.append(self.instance_to_image(instances[:,i], min_val, max_val).copy())
01013     #    return cv.fromarray(np.concatenate(img_arrs, 0).copy())
01014 
01015     #def instance_to_image(self, instance, min_val, max_val):
01016     #    winside = self.rec_params.win_size * 2 + 1
01017     #    patch_size = winside*winside*3
01018     #    multipliers = [1,2,4,8,16,32]
01019     #    srange = max_val - min_val
01020 
01021     #    offset = 0
01022     #    patches = []
01023     #    for i in range(len(multipliers)):
01024     #        s = instance[offset:offset+patch_size, 0]
01025     #        s = np.array(np.abs(np.round(((s-min_val)/srange) * 255.)), 'uint8')
01026     #        patches.append(np.reshape(s, (winside, winside, 3)))
01027     #    return np.concatenate(patches, 1)
01028 
01029     def select_features(self, instances, features_to_use, sizes):
01030         offset = 0
01031         fset = set(features_to_use)
01032         selected_fea = []
01033         for k in ['expected_loc', 'distance', 'fpfh', 'intensity']:
01034             if not sizes.has_key(k):
01035                 continue
01036             start_idx = offset 
01037             end_idx = offset + sizes[k]
01038 
01039             if fset.issuperset([k]):
01040                 selected_fea.append(instances[start_idx:end_idx, :])
01041             offset = end_idx
01042 
01043         #pdb.set_trace()
01044         return np.row_stack(selected_fea)
01045 
01046     def automatic_label(self):
01047         self.dataset = ut.load_pickle(self.training_sname)
01048         fea = self.select_features(self.current_scan['instances'], ['distance'], self.current_scan['sizes'])
01049         #pdb.set_trace()
01050         self.train(fea)
01051         #for name in ['4_20_2011/down/Monday_04_18_2011_11_20PM_interest_point_dataset_features_df2_dict.pkl']:
01052         for idx, name in enumerate(self.scan_names):
01053             self.scan_idx = idx
01054             self.load_scan(name)
01055             self.classify_current_scan()
01056             self.draw()
01057             #pdb.set_trace()
01058             self.current_scan['labels'][0,:] = self.current_scan_pred.outputs[0,:]
01059             self.draw()
01060             self.save_current()
01061 
01062         #for k in ['expected_loc', 'distance', 'fpfh', 'intensity']:
01063 
01064 
01065     def test_feature_perf(self, scans_to_train_on, features_to_use, exp_name, use_pca=None):
01066         #Make folder for results
01067         BASE_FILE_NAME = pt.splitext(insert_folder_name(self.scan_names[self.scan_idx], exp_name))[0] #pt.splitext(self.scan_names[self.scan_idx])[0]
01068         try:
01069             os.mkdir(pt.split(BASE_FILE_NAME)[0])
01070         except OSError, e:
01071             if e.errno != 17:
01072                 pdb.set_trace()
01073                 raise e
01074 
01075         #Decide whether to use PCA
01076         if use_pca == None:
01077             if set(features_to_use).issuperset(['intensity']):
01078                 use_pca = True
01079             else:
01080                 use_pca = False
01081 
01082         if not pt.isfile(self.training_sname):
01083             print 'test_feature_perf: Training file', self.training_sname, 'not found! exiting.'
01084             return
01085 
01086         #Construct new dataset
01087         feature_sizes = self.current_scan['sizes']
01088         nsizes = {}
01089         for f in features_to_use:
01090             nsizes[f] = feature_sizes[f]
01091 
01092         dset_trained_on = []
01093         for sname in scans_to_train_on:
01094             scan_idx = self.search_dataset_id(sname)
01095             if scan_idx == None:
01096                 print 'ERROR: %s not found in dir given' % (sname)
01097             dset_trained_on.append(scan_idx)
01098             self.load_scan(self.scan_names[scan_idx])
01099             rcurrent_scan = self.select_features(self.current_scan['instances'], features_to_use, feature_sizes)
01100             scan_ids = np.matrix([sname]*rcurrent_scan.shape[1])
01101             idx_in_scan = np.matrix(range(rcurrent_scan.shape[1]))
01102             if self.dataset == None:
01103                 self.dataset = InterestPointDataset(rcurrent_scan, self.current_scan['labels'], 
01104                                     self.current_scan['points2d'], self.current_scan['points3d'], 
01105                                     None, scan_ids=scan_ids, idx_in_scan=idx_in_scan, sizes=nsizes)
01106             else:
01107                 self.dataset.add(rcurrent_scan, self.current_scan['labels'], self.current_scan['points2d'],
01108                                  self.current_scan['points3d'], scan_id=scan_ids, idx_in_scan=idx_in_scan)
01109 
01110         self.train(self.dataset.inputs, use_pca)
01111         #pdb.set_trace()
01112         for d in dset_trained_on:
01113             self.load_scan(self.scan_names[d])
01114             self.scan_idx = d
01115             self.classify_current_scan()
01116             self.draw(exp_name)
01117 
01118         k = cv.WaitKey(33)
01119 
01120         print '>>>> Training set peformance'
01121         _, train_conf = self.evaluate_learner(self.dataset.inputs, self.dataset.outputs)
01122         train_set_statistics = []
01123         train_set_statistics.append({'conf': train_conf, 
01124                                      'size': self.dataset.inputs.shape[1]})
01125 
01126         print '>>>> Performance on unseen scans'
01127         print 'Loading scans we\'ll be testing on'
01128         #all_scans_except_current = []
01129         indices_of_other_scans = inverse_indices(dset_trained_on, len(self.scan_names))
01130         print 'Trained on', dset_trained_on
01131         print 'Testing with', indices_of_other_scans
01132 
01133         self.dataset=None
01134         conf_unseen = []
01135         for i in indices_of_other_scans:
01136             self.load_scan(self.scan_names[i])
01137             self.scan_idx = i
01138             self.classify_current_scan()
01139             self.draw(exp_name)
01140             k = cv.WaitKey(33)
01141             sdset = self.select_features(self.current_scan['instances'], self.features_to_use, self.current_scan['sizes'])
01142             _, conf = self.evaluate_learner(sdset, self.current_scan['labels'])
01143             conf_unseen.append({'name': self.scan_names[i], 'conf': conf})
01144         perf_on_other_scans = []
01145         perf_on_other_scans.append(conf_unseen)
01146 
01147         #Save training results
01148         training_results_name = BASE_FILE_NAME + 'active_train_iter_results.pkl'
01149         ut.save_pickle({'train_set_statistics': train_set_statistics,
01150                         #'current_scan_statistics': current_scan_statistics,
01151                         'perf_on_other_scans': perf_on_other_scans}, training_results_name)
01152         print 'Saved training results to', training_results_name
01153 
01154 
01155     def generate_dataset_for_hyperparameter_grid_search(self, features_to_use):
01156         feature_sizes = self.current_scan['sizes']
01157 
01158         for sname in self.scan_names:
01159             print 'generate_dataset_for_hyperparameter_grid_search: loading %s' % sname
01160             self.load_scan(sname)
01161             rcurrent_scan = self.select_features(self.current_scan['instances'], features_to_use, feature_sizes)
01162             scan_ids = np.matrix([sname]*rcurrent_scan.shape[1])
01163             idx_in_scan = np.matrix(range(rcurrent_scan.shape[1]))
01164             if self.dataset == None:
01165                 self.dataset = InterestPointDataset(rcurrent_scan, self.current_scan['labels'], 
01166                                     self.current_scan['points2d'], self.current_scan['points3d'], 
01167                                     None, scan_ids=scan_ids, idx_in_scan=idx_in_scan, sizes=nsizes)
01168             else:
01169                 self.dataset.add(rcurrent_scan, self.current_scan['labels'], self.current_scan['points2d'],
01170                                  self.current_scan['points3d'], scan_id=scan_ids, idx_in_scan=idx_in_scan)
01171 
01172         self.train(self.dataset.inputs, True)
01173 
01174 
01175     def construct_learner(self, seed_set, prev_pca, g, c, ratio=None):
01176         features_used = ['intensity']
01177         learner = SVMPCA_ActiveLearner(use_pca=True, 
01178                         reconstruction_std_lim = self.rec_params.reconstruction_std_lim, 
01179                         reconstruction_err_toler = self.rec_params.reconstruction_err_toler,
01180                         old_learner=self.learner, pca=prev_pca)
01181         if ratio == None:
01182             nneg = np.sum(seed_set.outputs == NEGATIVE) #
01183             npos = np.sum(seed_set.outputs == POSITIVE)
01184             neg_to_pos_ratio = float(nneg)/float(npos)
01185         else:
01186             neg_to_pos_ratio = ratio
01187         weight_balance = ' -w0 1 -w1 %.2f' % neg_to_pos_ratio
01188         #pdb.set_trace()
01189         inputs_for_pca = self.select_features(self.current_scan['instances'], features_used, self.current_scan['sizes'])
01190         svm_params = '-s 0 -t 2 -g %.6f -c %.2f' % (g, c)
01191         learner.train(seed_set, 
01192                       #self.current_scan['instances'],
01193                       inputs_for_pca,
01194                       svm_params + weight_balance,
01195                       self.rec_params.variance_keep)
01196         return learner
01197 
01198     def evaluate_over_datasets(self, test_idx, learner, exp_name):
01199         for i in test_idx:
01200             self.learner = learner
01201             name = self.scan_names[i]
01202             self.load_scan(name)
01203             self.classify_current_scan()
01204             self.draw(exp_name)
01205 
01206     def active_learn_test3(self):
01207         #pdb.set_trace()
01208         #features_used = ['expected_loc', 'fpfh', 'intensity']
01209         features_used = ['intensity']
01210         exp_name = 'fixed_intensity_bug_filtered_pca50_window15'
01211         path = pt.split(insert_folder_name(self.scan_names[self.scan_idx], exp_name))[0]
01212         g = .5
01213         c = .5
01214         #pdb.set_trace()
01215         try:
01216             os.mkdir(path)
01217         except OSError, e:
01218             pass
01219 
01220         train_idx = range(16)
01221         test_idx  = range(20,24)
01222         #test_idx  = range(8,9)
01223 
01224         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
01225         print 'Training initial learning from seed dataset'
01226         #Load seed dataset from the first scan, train initial SVM
01227         print 'using', self.training_sname
01228         seed_set = ut.load_pickle(self.training_sname)
01229         metaintensity =  seed_set.metadata[1]
01230         sizes = {'intensity': metaintensity.extent[1] - metaintensity.extent[0]}
01231         seed_set.metadata = [metaintensity]
01232         metaintensity.extent = [0, sizes['intensity']]
01233 
01234         #self.load_scan(self.scan_names[0])
01235         #Train learner
01236         #pca_fname = 'pca_active_learn_test2.pkl'
01237         #if pt.isfile(pca_fname):
01238         #    prev_pca = ut.load_pickle(pca_fname)
01239         #else:
01240         #    prev_pca = None
01241 
01242         #learner = self.construct_learner(seed_set, prev_pca, g, c)
01243         #prev_pca = learner.pca
01244         #ut.save_pickle(prev_pca, pca_fname)
01245         test_inputs = []
01246         test_outputs = []
01247         print 'Loading test sets'
01248         for i in test_idx:
01249             name = self.scan_names[i]
01250             print 'loading', name
01251             eval_data_set = ut.load_pickle(name)
01252             test_inputs.append(self.select_features(eval_data_set['instances'], features_used, eval_data_set['sizes']))
01253             test_outputs.append(eval_data_set['labels'])
01254             #pdb.set_trace()
01255         test_inputs  = np.column_stack(test_inputs)
01256         test_outputs = np.column_stack(test_outputs)
01257 
01258         #Active learning train phase
01259         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
01260         print 'Learning phase'
01261         conf_mats = []
01262         #current_idx = 0
01263         #number_of_converged_scans = 0
01264         #iteration_number = 0
01265         for i in train_idx[0:5]:
01266             self.scan_idx = i
01267             self.load_scan(name)
01268             cur_instances = self.select_features(self.current_scan['instances'], 
01269                     features_used, self.current_scan['sizes'])
01270             seed_set = InterestPointDataset.add_to_dataset(seed_set, 
01271                             cur_instances[:, :],
01272                             self.current_scan['labels'][:, :],
01273                             self.current_scan['points2d'][:, :],
01274                             self.current_scan['points3d'][:, :],
01275                             i, None, #np.matrix(range(self.current_scan['instances'].shape[1])),
01276                             sizes=sizes)
01277             #learner = self.construct_learner(seed_set, prev_pca, g, c)
01278             #prev_pca = learner.pca
01279 
01280             #predictions = np.matrix(learner.classify(test_inputs))
01281             #conf_mat = confusion_matrix(test_outputs, predictions)
01282             #conf_mats.append(conf_mat)
01283             #pdb.set_trace()
01284             #ut.save_pickle(conf_mats, exp_name + '_confusion_mats.pkl')
01285             #ut.save_pickle(seed_set, exp_name + '_seed_set.pkl')
01286             #print '---------------------------------'
01287             ##print iteration_number
01288             #print 'scan idx', i
01289             #print 'results'
01290             #print conf_mat
01291             #print conf_mat[0,0] + conf_mat[1,1]
01292 
01293         #pdb.set_trace()
01294         learner = self.construct_learner(seed_set, None, g, c)
01295         #pdb.set_trace()
01296         cv.SaveImage('pca_filtered_%s.png' % exp_name,\
01297                      instances_to_image(\
01298                         self.rec_params.win_size,\
01299                         learner.pca.projection_basis,\
01300                             np.min(learner.pca.projection_basis),\
01301                             np.max(learner.pca.projection_basis)))
01302         prev_pca = learner.pca
01303         self.evaluate_over_datasets(test_idx, learner, exp_name)
01304 
01305         pdb.set_trace()
01306         print confusion_matrix(test_outputs, np.matrix(self.construct_learner(seed_set, prev_pca, g, c).classify(test_inputs)))
01307         # self.evaluate_learner(test_idx, self.construct_learner(seed_set, prev_pca, g, c), exp_name)
01308         #pdb.set_trace()
01309 
01310         #for gv in [.1,.5, 1,2,3,4,5,10,20,30,40,50,100,200]:
01311         #    learner = self.construct_learner(seed_set, prev_pca, gv, c)
01312         #    #learner.classify(test_set.inputs)
01313         #    #conf_mat = r3d.confusion_matrix(test_set.outputs, predictions)
01314         #    #evaluate performance
01315         #    predictions = np.matrix(learner.classify(test_inputs))
01316         #    conf_mat = confusion_matrix(test_outputs, predictions)
01317         #    conf_mats.append(conf_mat)
01318         #    print '---------------------------------'
01319         #    print 'results'
01320         #    print conf_mat
01321         #    print conf_mat[0,0] + conf_mat[1,1]
01322 
01323         ut.save_pickle(conf_mats, exp_name + '_confusion_mats.pkl')
01324 
01325 
01326 
01327     #This time we train the same way that the robot runs
01328     #train each scan until convergence
01329     #run until we have seen 4 scans that don't need training
01330     #evaluate using all unseen scans
01331     def active_learn_test2(self):
01332         #pdb.set_trace()
01333         #features_used = ['expected_loc', 'fpfh', 'intensity']
01334         features_used = ['intensity']
01335         exp_name = 'autolearn_g05_c05_max5_pca50_fast_feature_patch15_0'
01336         path = pt.split(insert_folder_name(self.scan_names[self.scan_idx], exp_name))[0]
01337         #pdb.set_trace()
01338         try:
01339             os.mkdir(path)
01340         except OSError, e:
01341             pass
01342 
01343         #train_idx = range(16)
01344         train_idx = np.random.permutation(range(16)).tolist()
01345         #test_idx  = range(16,17)
01346         test_idx  = range(18,24)
01347 
01348         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
01349         print 'Training initial learning from seed dataset'
01350         #Load seed dataset from the first scan, train initial SVM
01351         print 'using', self.training_sname
01352         seed_set = ut.load_pickle(self.training_sname)
01353         #pdb.set_trace()
01354         metaintensity =  seed_set.metadata[1]
01355         sizes = {'intensity': metaintensity.extent[1] - metaintensity.extent[0]}
01356         seed_set.metadata = [metaintensity]
01357         metaintensity.extent = [0, sizes['intensity']]
01358         #self.load_scan(self.scan_names[0])
01359 
01360         #Train learner
01361         pca_fname = 'pca_active_learn_test2.pkl'
01362         if pt.isfile(pca_fname):
01363             prev_pca = ut.load_pickle(pca_fname)
01364         else:
01365             prev_pca = None
01366         learner = SVMPCA_ActiveLearner(use_pca=True, 
01367                         reconstruction_std_lim = self.rec_params.reconstruction_std_lim, 
01368                         reconstruction_err_toler = self.rec_params.reconstruction_err_toler,
01369                         old_learner=self.learner, pca=prev_pca)
01370         nneg = np.sum(seed_set.outputs == NEGATIVE) #
01371         npos = np.sum(seed_set.outputs == POSITIVE)
01372         neg_to_pos_ratio = float(nneg)/float(npos)
01373         weight_balance = ' -w0 1 -w1 %.2f' % neg_to_pos_ratio
01374         inputs_for_pca = self.select_features(self.current_scan['instances'], 
01375                 features_used, self.current_scan['sizes'])
01376         learner.train(seed_set, 
01377                       inputs_for_pca,
01378                       self.rec_params.svm_params + weight_balance,
01379                       self.rec_params.variance_keep)
01380         prev_pca = learner.pca
01381         ut.save_pickle(prev_pca, pca_fname)
01382 
01383         test_inputs = []
01384         test_outputs = []
01385         print 'Loading test sets'
01386         for i in test_idx:
01387             name = self.scan_names[i]
01388             print 'loading', name
01389             eval_data_set = ut.load_pickle(name)
01390             test_inputs.append(self.select_features(eval_data_set['instances'], 
01391                 features_used, eval_data_set['sizes']))
01392             test_outputs.append(eval_data_set['labels'])
01393             #pdb.set_trace()
01394         test_inputs  = np.column_stack(test_inputs)
01395         test_outputs = np.column_stack(test_outputs)
01396 
01397         #Active learning train phase
01398         print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
01399         print 'Learning phase'
01400         conf_mats = []
01401         current_idx = 0
01402         number_of_converged_scans = 0
01403         iteration_number = 0
01404 
01405         for i in train_idx:
01406             #break
01407             name = self.scan_names[i]
01408             current_idx = i
01409 
01410             print '!!!!!!!!!!!!!!!!!!!!!!!!!!!'
01411             print 'loading scan %s' % name
01412             self.scan_idx = current_idx
01413             self.load_scan(name)
01414             self.draw(exp_name)
01415             cur_instances = self.select_features(self.current_scan['instances'], 
01416                     features_used, self.current_scan['sizes'])
01417             converged = False
01418 
01419             indices_added = []
01420             while True:
01421                 if len(indices_added) > 5:
01422                     #pdb.set_trace()
01423                     break
01424 
01425                 iteration_number += 1
01426                 remaining_pt_indices = inverse_indices(indices_added, cur_instances.shape[1])
01427                 remaining_instances = cur_instances[:, remaining_pt_indices]
01428                 ridx, selected_dist, converged = learner.select_next_instances_no_terminate(remaining_instances)
01429                 if converged:
01430                     print 'Converged on scan.'
01431                     break
01432 
01433                 #add to dataset 
01434                 selected_idx = remaining_pt_indices[ridx[0]]
01435                 indices_added.append(selected_idx)
01436                 seed_set = InterestPointDataset.add_to_dataset(seed_set, 
01437                         cur_instances[:, selected_idx],
01438                         self.current_scan['labels'][:, selected_idx],
01439                         self.current_scan['points2d'][:, selected_idx],
01440                         self.current_scan['points3d'][:, selected_idx],
01441                         current_idx, selected_idx,
01442                         sizes=sizes)
01443 
01444                 #retrain 
01445                 learner = SVMPCA_ActiveLearner(use_pca=True, 
01446                                 reconstruction_std_lim=self.rec_params.reconstruction_std_lim, 
01447                                 reconstruction_err_toler=self.rec_params.reconstruction_err_toler,
01448                                 old_learner=self.learner, pca=prev_pca)
01449                 nneg = np.sum(seed_set.outputs == NEGATIVE) #
01450                 npos = np.sum(seed_set.outputs == POSITIVE)
01451                 neg_to_pos_ratio = float(nneg)/float(npos)
01452                 weight_balance = ' -w0 1 -w1 %.2f' % neg_to_pos_ratio
01453                 inputs_for_pca = self.select_features(self.current_scan['instances'], features_used, self.current_scan['sizes'])
01454                 learner.train(seed_set, 
01455                               inputs_for_pca,
01456                               self.rec_params.svm_params + weight_balance,
01457                               self.rec_params.variance_keep)
01458                 prev_pca = learner.pca
01459                 ut.save_pickle(prev_pca, pca_fname)
01460 
01461                 #evaluate performance
01462                 predictions = np.matrix(learner.classify(test_inputs))
01463                 conf_mat = confusion_matrix(test_outputs, predictions)
01464                 conf_mats.append(conf_mat)
01465                 ut.save_pickle(conf_mats, exp_name + '_confusion_mats.pkl')
01466                 ut.save_pickle(seed_set, exp_name + '_seed_set.pkl')
01467                 print '---------------------------------'
01468                 print iteration_number
01469                 print 'scan idx', i
01470                 print 'results'
01471                 print conf_mat
01472                 print conf_mat[0,0] + conf_mat[1,1]
01473 
01474                 self.learner = learner
01475                 self.classify_current_scan()
01476                 self.draw(exp_name)
01477 
01478             if len(indices_added) == 0:
01479                 #pdb.set_trace()
01480                 print 'OUTER LOOP CONVERGED', number_of_converged_scans
01481                 number_of_converged_scans += 1
01482 
01483         for i in test_idx:
01484             self.learner = learner
01485             name = self.scan_names[i]
01486             self.load_scan(name)
01487             self.classify_current_scan()
01488             self.draw(exp_name)
01489 
01490         #evaluate performance
01491         predictions = np.matrix(learner.classify(test_inputs))
01492         conf_mat = confusion_matrix(test_outputs, predictions)
01493         conf_mats.append(conf_mat)
01494         ut.save_pickle(conf_mats, exp_name + '_confusion_mats.pkl')
01495         print '---------------------------------'
01496         print 'results'
01497         print conf_mat
01498         print conf_mat[0,0] + conf_mat[1,1]
01499 
01500         self.learner = learner
01501         self.dataset = seed_set
01502         print 'DO NOT SAVE'
01503         print 'DO NOT SAVE'
01504         print 'DO NOT SAVE'
01505         print 'DO NOT SAVE'
01506         print 'DO NOT SAVE'
01507         print 'DO NOT SAVE'
01508         print 'DO NOT SAVE'
01509         #self.current_scan['sizes'] = sizes
01510         self.run_gui()
01511         pdb.set_trace()
01512 
01513 
01514     def active_learn_test(self, features_to_use, exp_name, use_pca=None, run_till_end=False):
01515         BASE_FILE_NAME = pt.splitext(insert_folder_name(self.scan_names[self.scan_idx], exp_name))[0] #pt.splitext(self.scan_names[self.scan_idx])[0]
01516         try:
01517             os.mkdir(pt.split(BASE_FILE_NAME)[0])
01518         except OSError, e:
01519             if e.errno != 17:
01520                 pdb.set_trace()
01521                 raise e
01522 
01523         # Run learner until convergence on initial scan
01524         if use_pca == None:
01525             if set(features_to_use).issuperset(['intensity']):
01526                 use_pca = True
01527             else:
01528                 use_pca = False
01529 
01530         if not pt.isfile(self.training_sname):
01531             print 'active_learn_test: Training file', self.training_sname, 'not found! exiting.'
01532             return
01533 
01534         feature_sizes = self.current_scan['sizes']
01535         print 'active_learn_test: Using features', features_to_use
01536         print 'active_learn_test: feature sizes'
01537         for k in ['expected_loc', 'distance', 'fpfh', 'intensity']:
01538             if feature_sizes.has_key(k):
01539                 print k, feature_sizes[k]
01540 
01541         total_dim = 0
01542         for f in features_to_use:
01543             total_dim += feature_sizes[f]
01544 
01545         print 'active_learn_test: total feature size should be', total_dim
01546 
01547         #Select only the features we will use
01548         rcurrent_scan = self.select_features(self.current_scan['instances'], features_to_use, feature_sizes)
01549 
01550         #Load the seed dataset to initialize active learner with
01551         self.dataset = ut.load_pickle(self.training_sname)
01552         print 'active_learn_test: loaded seed training file', self.training_sname
01553         self.dataset.select_features(features_to_use)
01554 
01555         self.train(rcurrent_scan, use_pca)
01556         self.classify_current_scan()
01557         self.draw(exp_name)
01558         k = cv.WaitKey(33)
01559 
01560         #Load all the scans we'll be testing on
01561         print 'Loading scans we\'ll be testing on'
01562         print 'TRAINING ON SCAN NAMED', self.scan_names[self.scan_idx]
01563         all_scans_except_current = []
01564         indices_of_other_scans = inverse_indices(self.scan_idx, len(self.scan_names))
01565         for i in indices_of_other_scans:
01566             sn = self.scan_names[i]
01567             print '>>', sn
01568             scan_dict = ut.load_pickle(sn)
01569             reduced_sd = {}
01570             reduced_sd['instances'] = self.select_features(scan_dict['instances'], features_to_use, feature_sizes)
01571             reduced_sd['labels'] = scan_dict['labels']
01572             reduced_sd['name'] = sn
01573             all_scans_except_current.append(reduced_sd)
01574 
01575         i = 0
01576         converged = False
01577         train_set_statistics = []
01578         current_scan_statistics  = []
01579         perf_on_other_scans = []
01580         converged_at_iter = None
01581         should_run = True
01582 
01583         #Run active learner until convergence
01584         while should_run:
01585             if self.learner.pca.projection_basis != None:
01586                 cv.SaveImage(BASE_FILE_NAME + ('_iter_%d_basis.png' % i),\
01587                              instances_to_image(\
01588                                 self.rec_params.win_size,\
01589                                 self.learner.pca.projection_basis,\
01590                                 np.min(self.learner.pca.projection_basis),\
01591                                 np.max(self.learner.pca.projection_basis)))
01592                 cv.SaveImage(BASE_FILE_NAME + ('_intensity_set_%d.png' % i),\
01593                              instances_to_image(self.rec_params.win_size, self.dataset.features_named(['intensity']),\
01594                                                 0., 1.))
01595 
01596             self.classify_current_scan()
01597             self.draw(exp_name)
01598             k = cv.WaitKey(33)
01599 
01600             print '>>>> Train set peformance'
01601             _, train_conf = self.evaluate_learner(self.dataset.inputs, self.dataset.outputs)
01602             train_set_statistics.append({'conf': train_conf, 
01603                                          'size': self.dataset.inputs.shape[1]})
01604 
01605             print '>>>> Performance on current scan (correlated test set)'
01606             remaining_pt_indices = inverse_indices(self.dataset.idx_in_scan, rcurrent_scan.shape[1])
01607             remaining_instances = rcurrent_scan[:, remaining_pt_indices]
01608             remaining_outputs = self.current_scan['labels'][:, remaining_pt_indices]
01609             #remaining_outputs = rcurrent_scan[:, remaining_pt_indices]
01610             #pdb.set_trace()
01611             _, rem_conf  = self.evaluate_learner(remaining_instances, remaining_outputs)
01612             current_scan_statistics.append({'conf': rem_conf})
01613 
01614             print '>>>> Performance on unseen scans (test set)'
01615             conf_unseen = []
01616             for scan in all_scans_except_current:
01617                 _, conf = self.evaluate_learner(scan['instances'], scan['labels'], verbose=False)
01618                 conf_unseen.append({'name': scan['name'], 'conf': conf})
01619             perf_on_other_scans.append(conf_unseen)
01620 
01621             #Only select points that have *not* been added
01622             #if active_train:
01623             remaining_pt_indices = inverse_indices(self.dataset.idx_in_scan, rcurrent_scan.shape[1])
01624             if len(remaining_pt_indices) > 0:
01625                 ridx, selected_dist, converged = self.learner.select_next_instances_no_terminate(rcurrent_scan[:, remaining_pt_indices])
01626                 if not converged or run_till_end:
01627                     selected_idx = remaining_pt_indices[ridx]
01628                     self.add_to_training_set(selected_idx)
01629                     self.train(rcurrent_scan, use_pca)
01630                     i = i + 1
01631                 else:
01632                     should_run = False
01633 
01634                 if converged and converged_at_iter == None:
01635                     converged_at_iter = i
01636 
01637                 if i > 100 and converged:
01638                     should_run = False
01639 
01640             else:
01641                 should_run = False
01642 
01643         print '======================='
01644         print '>> LEARNER CONVERGED <<'
01645         print '======================='
01646         print 'saving dataset to', self.training_sname
01647         ut.save_pickle(self.dataset, BASE_FILE_NAME + '_converged_dset.pkl')
01648         print 'saved!'
01649 
01650         #Save training results
01651         training_results_name = BASE_FILE_NAME + 'active_train_iter_results.pkl'
01652         ut.save_pickle({'train_set_statistics': train_set_statistics,
01653                         'current_scan_statistics': current_scan_statistics,
01654                         'perf_on_other_scans': perf_on_other_scans,
01655                         'converged_at_iter': converged_at_iter}, training_results_name)
01656         print 'Saved training results to', training_results_name
01657 
01658     def run_gui(self):
01659         # Make a test set
01660         while not rospy.is_shutdown():
01661             self.step()
01662 
01663     def mouse_cb(self, event, x, y, flags, param):
01664         if not (event == cv.CV_EVENT_LBUTTONDOWN or \
01665                 event == cv.CV_EVENT_RBUTTONDOWN or \
01666                 event == cv.CV_EVENT_MBUTTONDOWN):
01667             return
01668         # Grab closest thing, change its label, and redraw
01669         ck = [self.cdisp['tree'].query(np.array([x,y]) / self.scale, k=1)[1]]
01670         cr = self.cdisp['tree'].query_ball_point(np.array([x,y]) / self.scale, 5.)
01671         
01672         print 'k nearest', len(ck), 'radius', len(cr)
01673 
01674         if len(ck) > len(cr):
01675             closest_idx = ck
01676         else:
01677             closest_idx = cr
01678 
01679         if self.mode == 'GROUND_TRUTH':
01680             if event == cv.CV_EVENT_LBUTTONDOWN:
01681                 label = POSITIVE
01682             elif event == cv.CV_EVENT_RBUTTONDOWN:
01683                 label = NEGATIVE
01684             elif event == cv.CV_EVENT_MBUTTONDOWN:
01685                 label = UNLABELED
01686             else:
01687                 return
01688 
01689             print 'Current mode is', self.mode
01690             #print 'old labels', self.current_scan['labels'][0, closest_idx]
01691             self.current_scan['labels'][0, closest_idx] = label
01692             #print 'new labels', self.current_scan['labels'][0, closest_idx]
01693 
01694         
01695         if self.mode == 'TRAINING_SET':
01696             # Try to add selected point
01697             if event == cv.CV_EVENT_LBUTTONDOWN:
01698                 self.add_to_training_set(closest_idx)
01699 
01700             # Try to remove the selected point
01701             elif event == cv.CV_EVENT_RBUTTONDOWN:
01702                 self.remove_from_training_set(closest_idx)
01703         self.draw()
01704 
01705     def add_to_training_set(self, indices):
01706         # Don't add examples that have not been labeled (remove examples with the label UNLABELED)
01707         labeled_idx = []
01708         for idx in indices:
01709             #print 'add_to_training_set:', self.current_scan['labels'][0, idx].__class__
01710             #if np.array([self.current_scan['labels'][0, idx]]).shape[0] > 1:
01711             #    pdb.set_trace()
01712             #if len(np.array([self.current_scan['labels'][0, idx]]).shape) > 1:
01713             #    pdb.set_trace()
01714 
01715             if self.current_scan['labels'][0, idx] != UNLABELED:
01716                 labeled_idx.append(idx)
01717         
01718         # Don't add examples that have been added (keep index of examples added from this scan).
01719         # Search the list of labeled examples.
01720         filtered_idx = []
01721         if self.dataset != None:
01722             for idx in labeled_idx:
01723                 #pdb.set_trace()
01724                 if self.dataset.idx_in_scan == None:
01725                     matched_idx = []
01726                 else:
01727                     matched_idx = np.where(self.dataset.idx_in_scan == idx)[1].A1
01728                 if len(matched_idx) > 0:
01729                     if np.any(self.scan_names[self.scan_idx] == self.dataset.scan_ids[:, matched_idx]):
01730                         continue
01731                 filtered_idx.append(idx)
01732         else:
01733             filtered_idx += labeled_idx
01734        
01735         if len(filtered_idx) < 1:
01736             print 'add_to_training_set: returned point #', labeled_idx, 'as it is already in the dataset'
01737             return
01738             #pdb.set_trace()
01739         filtered_idx = [filtered_idx[0]]
01740         pinfo = [self.current_scan[k][:, filtered_idx] for k in \
01741                         ['instances', 'labels', 'points2d', 'points3d']]
01742         pinfo.append(np.matrix([self.scan_names[self.scan_idx]] * len(filtered_idx)))
01743         pinfo.append(np.matrix(filtered_idx))
01744 
01745         if self.dataset == None:
01746             #pdb.set_trace()
01747             print 'WARNING: THIS BRANCH SHOULD BE REACHED DURING AUTONOMOUS RUN. add_to_training_set'
01748             #pdb.set_trace()
01749             self.dataset = InterestPointDataset(self.select_features(pinfo[0], self.features_to_use, self.current_scan['sizes']),
01750                                                 pinfo[1], pinfo[2], pinfo[3], None, pinfo[4], pinfo[5], 
01751                                                 sizes=self.current_scan['sizes'])
01752         else:
01753             self.dataset.add(self.select_features(pinfo[0], self.features_to_use, self.current_scan['sizes']), pinfo[1], \
01754                                                   pinfo[2], pinfo[3], pinfo[4], pinfo[5])
01755 
01756         print '>> Number of examples in dataset:', self.dataset.inputs.shape[1]
01757 
01758     def remove_from_training_set(self, indices):
01759         if self.dataset != None:
01760             for idx in indices:
01761                 matched_idx = np.where(self.dataset.idx_in_scan == idx)[1].A1
01762                 if len(matched_idx) > 0:
01763                     sm = np.where(self.scan_names[self.scan_idx] == self.dataset.scan_ids[:, matched_idx])[1]
01764                     if len(sm) > 0:
01765                         to_remove = matched_idx[sm]
01766                         print 'removing', len(sm), 'points'
01767                         for ridx in to_remove:
01768                             self.dataset.remove(ridx)
01769 
01770     def has_enough_data(self):
01771         pos_ex = np.sum(self.dataset.outputs)
01772         neg_ex = self.dataset.outputs.shape[1] - pos_ex
01773         if pos_ex > 0 and neg_ex > 0:
01774             return True
01775 
01776     def train(self, inputs_for_scaling):
01777         if self.dataset != None and self.has_enough_data():
01778             use_pca=False
01779             for f in self.features_to_use:
01780                 if f == 'intensity':
01781                     use_pca=True
01782             nneg = np.sum(self.dataset.outputs == NEGATIVE)
01783             npos = np.sum(self.dataset.outputs == POSITIVE)
01784             print '================= Training ================='
01785             print 'NEG examples', nneg
01786             print 'POS examples', npos
01787             print 'TOTAL', self.dataset.outputs.shape[1]
01788             neg_to_pos_ratio = float(nneg)/float(npos)
01789             #weight_balance = ' -w0 1 -w1 %.2f' % neg_to_pos_ratio
01790             #weight_balance = ' -w0 1 -w1 %.2f' % 2.
01791             #weight_balance = ""
01792             #weight_balance = ' -w0 1 -w1 5.0'
01793             weight_balance = ' -w0 1 -w1 %.2f' % (neg_to_pos_ratio)
01794             #weight_balance = ""
01795 
01796             self.learner = SVMPCA_ActiveLearner(use_pca, 
01797                     self.rec_params.reconstruction_std_lim, 
01798                     self.rec_params.reconstruction_err_toler,
01799                     old_learner=self.learner)
01800 
01801             self.learner.train(self.dataset, 
01802                                inputs_for_scaling,
01803                                self.rec_params.svm_params + weight_balance,
01804                                self.rec_params.variance_keep)
01805 
01806             #correct = np.sum(self.dataset.outputs == np.matrix(self.learner.classify(self.dataset.inputs)))
01807             #pdb.set_trace()
01808             #print 'Test set: %.2f' % (100.* (float(correct)/float(self.dataset.outputs.shape[1]))), '% correct'
01809             #self.evaluate_learner(self.dataset.inputs, self.dataset.outputs)
01810 
01811             if use_pca:
01812                 BASE_FILE_NAME = 'pca_fast'
01813                 i = 111
01814                 cv.SaveImage(BASE_FILE_NAME + ('_iter_%d_basis.png' % i),\
01815                              instances_to_image(\
01816                                 self.rec_params.win_size,\
01817                                 self.learner.pca.projection_basis,\
01818                                 np.min(self.learner.pca.projection_basis),\
01819                                 np.max(self.learner.pca.projection_basis)))
01820 
01821 
01822             print '=================  DONE  =================' 
01823 
01824     def evaluate_learner(self, instances, true_labels, verbose=True):
01825         predicted = np.matrix(self.learner.classify(instances))
01826 
01827         posidx = np.where(true_labels == POSITIVE)[1].A1
01828         negidx = np.where(true_labels == NEGATIVE)[1].A1
01829         m00 = m01 = m10 = m11 = 0
01830         nm00 = nm01 = nm10 = nm11 = 0
01831         if len(negidx) > 0:
01832             nm00 = float(np.sum(NEGATIVE == predicted[:, negidx]))
01833             nm01 = float(np.sum(POSITIVE == predicted[:, negidx]))
01834             m00 =  nm00 / len(negidx)
01835             m01 =  nm01 / len(negidx)
01836 
01837         if len(posidx) > 0:
01838             nm10 = float(np.sum(NEGATIVE == predicted[:, posidx]))
01839             nm11 = float(np.sum(POSITIVE == predicted[:, posidx]))
01840             m10 =  nm10 / len(posidx)
01841             m11 =  nm11 / len(posidx)
01842 
01843         conf_mat = np.matrix([[m00, m01], [m10, m11]], 'float')
01844         if verbose:
01845             print 'Confusion matrix:'
01846             print '-   %5.2f, %5.2f' % (100.* m00, 100.* m01)
01847             print '+  %5.2f, %5.2f' % (100.* m10, 100.* m11)
01848             print '   Total %5.2f' % (100.* (float(np.sum(true_labels == predicted)) / true_labels.shape[1]))
01849 
01850         return predicted, {'mat': np.matrix([[nm00, nm01], [nm10, nm11]], 'float'), 
01851                            'neg': len(negidx), 
01852                            'pos': len(posidx)}
01853         #print 'POS correct %.2f' % 100. * float(pcor) / len(posidx)
01854         #print 'NEG correct %.2f' % 100. * float(ncor) / len(negidx)
01855 
01856     def add_to_dataset(self, pinfo):
01857         if self.dataset == None:
01858             self.dataset = InterestPointDataset(pinfo[0], pinfo[1], pinfo[2], \
01859                     pinfo[3], None, pinfo[4], pinfo[5], sizes=self.current_scan['sizes'])
01860         else:
01861             self.dataset.add(pinfo[0], pinfo[1], \
01862                     pinfo[2], pinfo[3], pinfo[4], pinfo[5])
01863 
01864 class FiducialPicker:
01865 
01866     def __init__(self, fname):
01867         #load pickle and display image
01868         self.fname = fname
01869         self.data_pkl = ut.load_pickle(fname)
01870         image_fname = pt.join(pt.split(fname)[0], self.data_pkl['image'])
01871         self.img = cv.LoadImageM(image_fname)
01872         self.clicked_points = None
01873         self.clicked_points3d = None
01874 
01875         #make a map in image coordinates
01876         #bl_pc = ru.pointcloud_to_np(self.data_pkl['points3d'])
01877         bl_pc = self.data_pkl['points3d']
01878         self.image_T_laser = self.data_pkl['k_T_bl']
01879         self.image_arr = np.asarray(self.img)
01880         self.calibration_obj = self.data_pkl['cal']
01881         self.points_valid_image, self.colors_valid, self.points2d_valid = \
01882                 i3d.combine_scan_and_image_laser_frame(bl_pc, self.image_T_laser,\
01883                                             self.image_arr, self.calibration_obj)
01884 
01885         laser_T_image = np.linalg.inv(self.image_T_laser)
01886         self.points_valid_laser = tfu.transform_points(laser_T_image, self.points_valid_image[0:3,:])
01887         self.ptree = sp.KDTree(np.array(self.points2d_valid.T))
01888 
01889         cv.NamedWindow('image', cv.CV_WINDOW_AUTOSIZE)
01890         cv.ShowImage('image', self.img)
01891         cv.SetMouseCallback('image', self.mouse_cb, None)
01892         self.exit = False
01893         
01894 
01895     def mouse_cb(self, event, x, y, flags, param):
01896         if event != cv.CV_EVENT_LBUTTONDOWN:
01897             return
01898 
01899         pt = np.array([x,float(y)]).T
01900         idx = self.ptree.query(pt.T, k=1)[1]
01901         #pdb.set_trace()
01902         if self.clicked_points != None:
01903             self.clicked_points = np.column_stack((self.clicked_points, self.points2d_valid[:, idx]))
01904             self.clicked_points3d = np.column_stack((self.clicked_points3d, self.points_valid_laser[:,idx]))
01905         else:
01906             self.clicked_points = self.points2d_valid[:, idx]
01907             self.clicked_points3d = self.points_valid_laser[:,idx]
01908 
01909         #self.clicked_points
01910 
01911         #    label = POSITIVE
01912         #elif event == cv.CV_EVENT_RBUTTONDOWN:
01913         #    label = NEGATIVE
01914         #else:
01915         #    return
01916 
01917     def step(self):
01918         k = cv.WaitKey(33)
01919         if k == ord('s'):
01920             if self.clicked_points.shape[1] > 3:
01921                 fname = pt.splitext(self.fname)[0] + '_synthetic_locs3d.pkl'
01922                 print 'saving data to file:', fname
01923                 #self.data_pkl['synthetic_locs3d'] = self.clicked_points3d
01924                 #ut.save_pickle(self.data_pkl, self.fname)
01925                 ut.save_pickle(self.clicked_points3d, fname)
01926             else:
01927                 print 'ignored save command, need more points. only has', self.clicked_points3d.shape[1]
01928 
01929         if k == ord('x'):
01930             self.exit = True
01931 
01932         ibuffer = cv.CloneMat(self.img)
01933         draw_points(ibuffer, self.points2d_valid, [0,255,0], 1)
01934         #if self.clicked_points.shape[1] > 0:
01935         if self.clicked_points != None:
01936             draw_points(ibuffer, self.clicked_points, [0,0,255], 3)
01937         cv.ShowImage('image', ibuffer)
01938 
01939     def run(self):
01940         while not rospy.is_shutdown():
01941             self.step()
01942             if self.exit:
01943                 return
01944 
01945 class NarrowTextureFeatureExtractor:
01946     def __init__(self, prosilica, narrow_texture, prosilica_cal, projector, tf_listener, rec_params=None):
01947         self.cal = prosilica_cal
01948         self.prosilica = prosilica
01949         self.narrow_texture = narrow_texture
01950         self.tf_listener = tf_listener
01951         self.projector = projector
01952 
01953         if rec_params == None:
01954             rec_params = Recognize3DParam()
01955         self.rec_params = rec_params
01956 
01957     def read(self, expected_loc_bl, params=None):
01958         #self.laser_scan.scan(math.radians(180.), math.radians(-180.), 2.315)
01959         rospy.loginfo('grabbing point cloud')
01960         pointcloud_msg = self.narrow_texture.read()
01961         rospy.loginfo('grabbing prosilica frame')
01962         self.projector.set(False)
01963         for i in range(3):
01964             cvimage_mat = self.prosilica.get_frame()
01965         self.projector.set(True)
01966         rospy.loginfo('processing')
01967         pointcloud_ns = ru.pointcloud_to_np(pointcloud_msg)
01968         pointcloud_bl = tfu.transform_points(tfu.transform('base_link',\
01969                                                             'narrow_stereo_optical_frame', self.tf_listener),\
01970                                             pointcloud_ns)
01971 
01972         image_T_bl = tfu.transform('high_def_optical_frame', 'base_link', self.tf_listener)
01973 
01974         if params == None:
01975             params = self.rec_params
01976 
01977         #laser_T_bl = tfu.transform('/laser_tilt_link', '/base_link', self.tf_listener)
01978         #extractor = IntensityCloudData(pointcloud_bl, cvimage_mat, image_T_bl, self.cal, 
01979         #                     expected_loc_bl, expected_loc_bl, None, params)
01980         extractor = infea.IntensityCloudFeatureExtractor(pointcloud_bl, cvimage_mat, expected_loc_bl, 
01981                                                     None, image_T_bl, self.cal, params)
01982         xs, locs2d, locs3d = extractor.extract_features()
01983 
01984         rdict = {#'histogram': extractor.fpfh_hist,
01985                  #'hpoints3d': extractor.fpfh_points,
01986                  'points3d': pointcloud_bl,
01987                  'image': cvimage_mat}
01988 
01989         return {'instances': xs, 
01990                 'points2d': locs2d, 
01991                 'points3d': locs3d, 
01992                 'image': cvimage_mat, #rdict['image'], 
01993                 'rdict': rdict,
01994                 'sizes': extractor.sizes}
01995 
01996 
01997 if __name__ == '__main__':
01998     import sys
01999     import optparse
02000     p = optparse.OptionParser()
02001     p.add_option('-m', '--mode', action='store',
02002                 dest='mode', default='label', 
02003                 help='fiducialpicker, preprocess, or label')
02004     p.add_option("-f", "--feature", action="append", type="string")
02005     p.add_option("-t", "--test", action="store_true")
02006     p.add_option("-r", "--train", action="append", type="string")
02007     p.add_option("-n", "--expname", action="store", default="")
02008     p.add_option("-p", "--pca", action="store_true", default=None)
02009     p.add_option("-s", "--seed", action="store", default=None, help='not strictly neccessary if you use pickles ending with _seed.pkl')
02010     p.add_option("-e", "--end", action="store_true", default=False)
02011     p.add_option("-l", "--locations", action="store", default=None)
02012     p.add_option("-a", "--autolabel", action="store_true", default=None)
02013     #p.add_option("-k", "--kinect", action="store_true", default=True)
02014     opt, args = p.parse_args()
02015     mode = opt.mode
02016 
02017     print '======================================='
02018     print 'mode:', mode
02019     print '======================================='
02020     print args
02021 
02022     if mode == 'fiducialpicker':
02023         fp = FiducialPicker(args[0])
02024         fp.run()
02025 
02026     #if mode == 'standalone':
02027     #    object_name = args[0]
02028     #    raw_data_fname = args[1]
02029     #    if len(sys.argv) > 3:
02030     #        labeled_data_fname = args[2]
02031     #    else:
02032     #        labeled_data_fname = None
02033 
02034     #    cvgui = CVGUI4(raw_data_fname, object_name, labeled_data_fname)
02035     #    cvgui.run()
02036 
02037     if mode == 'preprocess':
02038         rospy.init_node('detect_fpfh', anonymous=True)
02039         preprocess_data_in_dir(args[0], ext='_features_df2_dict.pkl')
02040 
02041     if mode == 'locations':
02042         if opt.locations != None:
02043             locations = ut.load_pickle(opt.locations)
02044             keys = locations['data'].keys()
02045             for i, key in enumerate(keys):
02046                 print i, key
02047             picked_i = int(raw_input('pick a key to use'))
02048             seed_dset = keys[i]
02049             fname = raw_input('pick a file name')
02050             dset = locations['data'][seed_dset]['dataset']
02051             dset.idx_in_scan = np.matrix(dset.inputs.shape[1] * [0])
02052             dset.scan_ids = np.matrix(dset.inputs.shape[1] * [''])
02053             #dset.pt2d = None
02054             ut.save_pickle(dset, fname)
02055             pdb.set_trace()
02056             print 'saved %s' % fname
02057 
02058 
02059     if mode == 'hyper':
02060         s = ScanLabeler(args[0], ext='_features_df2_dict.pkl', scan_to_train_on=opt.train, 
02061                 seed_dset=opt.seed, features_to_use=opt.feature)
02062         s.generate_dataset_for_hyperparameter_grid_search(opt.feature)
02063 
02064 
02065     if mode == 'label':
02066         s = ScanLabeler(args[0], ext='_features_df2_dict.pkl', scan_to_train_on=opt.train, 
02067                 seed_dset=opt.seed, features_to_use=opt.feature)
02068         #s.automatic_label()
02069         #pdb.set_trace()
02070         if opt.autolabel:
02071             s.automatic_label()
02072         elif opt.test:
02073             print 'Running automated tests'
02074             print 'Using features', opt.feature
02075             s.active_learn_test2()
02076             #if len(opt.feature) == 1 and opt.feature[0] == 'distance':
02077             #    s.active_learn_test(['distance'], opt.expname, opt.pca, run_till_end=opt.end)
02078             #else:
02079             #    s.active_learn_test(opt.feature, opt.expname, opt.pca, run_till_end=opt.end)
02080         else:
02081             print 'launching gui.'
02082             s.run_gui()
02083 
02084     if mode == 'feature':
02085         s = ScanLabeler(args[0], ext='_features_df2_dict.pkl', scan_to_train_on=opt.train[0], 
02086                 seed_dset=opt.seed, features_to_use=opt.feature)
02087         if len(opt.feature) == 1 and opt.feature[0] == 'distance':
02088             s.test_feature_perf(opt.train, ['distance'], opt.expname, opt.pca)
02089         else:
02090             s.test_feature_perf(opt.train, opt.feature, opt.expname, opt.pca)
02091 
02092     if mode == 'call_fpfh':
02093         rospy.init_node('detect_fpfh', anonymous=True)
02094         fpfh = rospy.ServiceProxy('fpfh', fsrv.FPFHCalc)
02095 
02096         print 'loading'
02097         extractor, _ = load_data_from_file(args[0], Recognize3DParam())
02098         #data_pkl = ut.load_pickle(sys.argv[1])
02099         req = fsrv.FPFHCalcRequest()
02100         print 'npoints', extractor.points3d_valid_laser.shape[1]
02101         req.input = ru.np_to_pointcloud(extractor.points3d_valid_laser, 'base_link')
02102         #data_pkl['points_laser']
02103         print 'requesting'
02104         res = fpfh(req)
02105         print 'response received'
02106         #res.hist.histograms
02107         #res.hist.npoints
02108         #pdb.set_trace()
02109         histogram = np.matrix(res.hist.histograms).reshape((res.hist.npoints,33)).T
02110         points3d = np.matrix(res.hist.points3d).reshape((res.hist.npoints,3)).T
02111         print 'done'
02112         print 'done'
02113         print 'done'
02114         print 'done'
02115         print 'done'
02116 
02117     if mode == 'kinect':
02118         #import roslib; roslib.load_manifest('hai_sandbox')
02119         #import rospy
02120         #from sensor_msgs.msg import Image
02121         rospy.init_node('kinect_features')
02122         kfe = KinectFeatureExtractor()
02123         fname = opt.train[0]
02124 
02125         dataset = ut.load_pickle(fname)
02126         nneg = np.sum(dataset.outputs == NEGATIVE)
02127         npos = np.sum(dataset.outputs == POSITIVE)
02128         print '================= Training ================='
02129         print 'NEG examples', nneg
02130         print 'POS examples', npos
02131         print 'TOTAL', dataset.outputs.shape[1]
02132         neg_to_pos_ratio = float(nneg)/float(npos)
02133         weight_balance = ' -w0 1 -w1 %.2f' % neg_to_pos_ratio
02134         learner = SVMPCA_ActiveLearner(use_pca=True)
02135         trained = False
02136         ip = ImagePublisher('active_learn')
02137 
02138         while not rospy.is_shutdown():
02139             #calculate features
02140             xs, locs2d, locs3d, rdict['image'], rdict = kfe.read()
02141             if not trained:
02142                 learner.train(dataset, xs, kfe.rec_params.svm_params + weight_balance,
02143                               kfe.rec_params.variance_keep)
02144                 trained = True
02145             
02146             #predict
02147             results = np.matrix(learner.classify(sdset))
02148             current_scan_pred = InterestPointDataset(xs, results, locs2d, locs3d, None)
02149 
02150             #Draw
02151             img = cv.CloneMat(cdisp['cv'])
02152             draw_labeled_points(img, current_scan_pred, scale=1./self.scale)
02153             ip.publish(img)
02154 
02155         rospy.spin()
02156 


trf_learn
Author(s): Hai Nguyen (hai@gatech.edu) Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 11:47:18